找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3133|回复: 0
打印 上一主题 下一主题
收起左侧

STM32f407串口轮询和中断 源程序详细注释

[复制链接]
跳转到指定楼层
楼主
ID:772513 发表于 2021-2-5 09:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是刚接触串口一些心得体会:轮询方式将接收函数放在while循环中,每次循环cpu主动询问并判断是否有数据接收,接收占用CPU资源较多,所以一般使用串口中断方式接收数据,串口接收到数据后触发中断,cpu被打断,中断当前任务去处理接收的数据。个人理解轮询和中断最大区别就是cpu主动和被动请求,如果大家还有其他理解,欢迎提出

单片机源程序如下:
  1. #include "led.h"
  2. #include "key.h"
  3. #include "usart.h"
  4. #include "systick.h"
  5. #include "beep.h"

  6. int main(void)
  7. {
  8.         u8 buf[50];
  9.         LED_Init();       //LED初始化
  10.         KEY_Init();       //按键初始化
  11.         BEEP_Init();      //蜂鸣器初始化
  12.         USART1_Init(9600);//串口1初始化
  13.         while(1)
  14.         {  
  15.                 USART1_ReceString(buf);
  16.                 printf("%s\r\n",buf);
  17.                 if(strcmp((char*)buf,"开灯")==0)
  18.                 {               
  19.                         LED1_ON;
  20.                         LED2_ON;
  21.                         LED3_ON;
  22.                         LED4_ON;
  23.                         printf("主人,已为您开灯\r\n");                        
  24.                 }
  25.                 else if (strcmp((char*)buf,"关灯")==0)
  26.                 {
  27.                         LED1_OFF;
  28.                         LED2_OFF;
  29.                         LED3_OFF;
  30.                         LED4_OFF;
  31.                         printf("主人,已为您灯关\r\n");
  32.                 }
  33.                 else if (strcmp((char*)buf,"启动蜂鸣器")==0)
  34.                 {
  35.                         BEEP_ON;
  36.                         printf("回禀大人,蜂鸣器已响\r\n");
  37.                 }
  38.                 else if (strcmp((char*)buf,"关闭蜂鸣器")==0)
  39.                 {
  40.                         BEEP_OFF;
  41.                         printf("回禀大人,蜂鸣器已关\r\n");
  42.                 }
  43.         }
  44. }

复制代码
  1. #include "usart.h"


  2. //输出重定向 (重新定义输出方向)
  3. int fputc(int ch,FILE *f)
  4. {
  5.         while(!(USART1->SR&(1<<6)));//等待传送已完成
  6.         USART1->DR = ch;
  7.         return ch;
  8. }


  9. /**********************************************************************
  10. *函数名:u1_printf
  11. *功  能:自定义的打印函数
  12. *参  数:格式参数
  13. *返  回:无
  14. *备  注:等效于库 函数printf
  15. **********************************************************************/
  16. void u1_printf(char* fmt,...)
  17. {  
  18.         unsigned int i,length;
  19.         char TxBuff[100];  
  20.         va_list ap;
  21.         va_start(ap,fmt);
  22.         vsprintf(TxBuff,fmt,ap);
  23.         va_end(ap);        
  24.         length=strlen((const char*)TxBuff);               
  25.         for(i = 0;i < length;i ++)
  26.         {        
  27.                 while(!(USART1->SR&(1<<6)));               
  28.                 USART1->DR = TxBuff[i];        
  29.         }        
  30. }

  31. /**********************************************************************
  32. *函数名:USART1_Init
  33. *功  能:串口1初始化
  34. *参  数:波特率
  35. *返  回:无
  36. *备  注:
  37. 1.时钟使能 GPIOA 和串口1
  38. 2.串口1引脚 TXD(PA9)   RXD(PA10)配置为复用模式
  39. **********************************************************************/
  40. void USART1_Init(u32 bound)
  41. {
  42.         float usartdiv;
  43.         u16 DIV_Mantissa;//整数部分
  44.         u16 DIV_Fraction;//小数部分
  45.         RCC->APB2ENR  |= 1<<4;//串口1时钟使能
  46.         RCC->AHB1ENR  |= 1<<0;//PA端口使能
  47.         
  48.         //PA9配置复用模式,且映射到USART1
  49.         GPIOA->MODER  &=~(3<<9*2);  //清零
  50.         GPIOA->MODER  |=2<<9*2;     //复用模式
  51.         
  52.         GPIOA->OTYPER &=~(1<<9);    //推挽
  53.         
  54.         GPIOA->OSPEEDR &=~(3<<2*9); //清零
  55.         GPIOA->OSPEEDR &=1<<2*9;    //速度25MHZ
  56.         
  57.         GPIOA->AFR[1]  &=~(0xf<<4);//4~7位清理        
  58.         GPIOA->AFR[1]  |=7<<4;                //映射(选择)
  59.                
  60.         //PA10配置复用,且映射到到USART1
  61.         GPIOA->MODER   |=2<<10*2;   //复用功能
  62.         GPIOA->AFR[1]  &=~(0xf<<8);        //位清理        
  63.         GPIOA->AFR[1]  |=7<<8;            //PA10映射到USART1
  64.         
  65.         //CPU帮我们算波特率
  66.         usartdiv=84*1000000/16.0/bound;
  67.         DIV_Mantissa=usartdiv;
  68.         DIV_Fraction=(usartdiv-DIV_Mantissa)*16;
  69.         USART1->BRR=DIV_Mantissa<<4|DIV_Fraction;
  70.         
  71.         USART1->CR1 |=1<<13|1<<3|1<<2;//串口使能,发送使能,接收使能
  72.         printf("串口1初始化\r\n");
  73. }



  74. /**********************************************************************
  75. *函数名:USART1_ReceByte
  76. *功  能:串口1接收单个字节
  77. *参  数:无
  78. *返  回:字节数据
  79. *备  注:
  80. **********************************************************************/
  81. u8 USART1_ReceByte(void)
  82. {
  83.         while(!(USART1->SR&(1<<5)));//等待接收完成
  84.         return USART1->DR;//读取数据
  85. }

  86. /**********************************************************************
  87. *函数名:USART1_ReceByte
  88. *功  能:串口1接收单个字节
  89. *参  数:无
  90. *返  回:字节数据
  91. *备  注:
  92. **********************************************************************/
  93. void USART1_ReceString(u8 *buf)
  94. {
  95.         u8 ch;
  96.         while(1)
  97.         {
  98.                 ch=USART1_ReceByte();
  99.                 if(ch=='\r'||ch=='\n')
  100.                 {
  101.                         break;//接收
  102.                 }
  103.                 *buf++=ch;
  104.         }
  105.         *buf=0;//构成字符串
  106. }



复制代码


全部程序51hei下载地址:
USART串口中断.7z (292.74 KB, 下载次数: 20)
USART(轮询法接收数据).7z (299.78 KB, 下载次数: 13)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表