找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3577|回復(fù): 0
收起左側(cè)

STM32f407串口輪詢和中斷 源程序詳細(xì)注釋

[復(fù)制鏈接]
ID:772513 發(fā)表于 2021-2-5 09:58 | 顯示全部樓層 |閱讀模式
這是剛接觸串口一些心得體會:輪詢方式將接收函數(shù)放在while循環(huán)中,每次循環(huán)cpu主動詢問并判斷是否有數(shù)據(jù)接收,接收占用CPU資源較多,所以一般使用串口中斷方式接收數(shù)據(jù),串口接收到數(shù)據(jù)后觸發(fā)中斷,cpu被打斷,中斷當(dāng)前任務(wù)去處理接收的數(shù)據(jù)。個人理解輪詢和中斷最大區(qū)別就是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,"關(guān)燈")==0)
  26.                 {
  27.                         LED1_OFF;
  28.                         LED2_OFF;
  29.                         LED3_OFF;
  30.                         LED4_OFF;
  31.                         printf("主人,已為您燈關(guān)\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,"關(guān)閉蜂鳴器")==0)
  39.                 {
  40.                         BEEP_OFF;
  41.                         printf("回稟大人,蜂鳴器已關(guān)\r\n");
  42.                 }
  43.         }
  44. }

復(fù)制代碼
  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. *函數(shù)名:u1_printf
  11. *功  能:自定義的打印函數(shù)
  12. *參  數(shù):格式參數(shù)
  13. *返  回:無
  14. *備  注:等效于庫 函數(shù)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. *函數(shù)名:USART1_Init
  33. *功  能:串口1初始化
  34. *參  數(shù):波特率
  35. *返  回:無
  36. *備  注:
  37. 1.時鐘使能 GPIOA 和串口1
  38. 2.串口1引腳 TXD(PA9)   RXD(PA10)配置為復(fù)用模式
  39. **********************************************************************/
  40. void USART1_Init(u32 bound)
  41. {
  42.         float usartdiv;
  43.         u16 DIV_Mantissa;//整數(shù)部分
  44.         u16 DIV_Fraction;//小數(shù)部分
  45.         RCC->APB2ENR  |= 1<<4;//串口1時鐘使能
  46.         RCC->AHB1ENR  |= 1<<0;//PA端口使能
  47.         
  48.         //PA9配置復(fù)用模式,且映射到USART1
  49.         GPIOA->MODER  &=~(3<<9*2);  //清零
  50.         GPIOA->MODER  |=2<<9*2;     //復(fù)用模式
  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配置復(fù)用,且映射到到USART1
  61.         GPIOA->MODER   |=2<<10*2;   //復(fù)用功能
  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;//串口使能,發(fā)送使能,接收使能
  72.         printf("串口1初始化\r\n");
  73. }



  74. /**********************************************************************
  75. *函數(shù)名:USART1_ReceByte
  76. *功  能:串口1接收單個字節(jié)
  77. *參  數(shù):無
  78. *返  回:字節(jié)數(shù)據(jù)
  79. *備  注:
  80. **********************************************************************/
  81. u8 USART1_ReceByte(void)
  82. {
  83.         while(!(USART1->SR&(1<<5)));//等待接收完成
  84.         return USART1->DR;//讀取數(shù)據(jù)
  85. }

  86. /**********************************************************************
  87. *函數(shù)名:USART1_ReceByte
  88. *功  能:串口1接收單個字節(jié)
  89. *參  數(shù):無
  90. *返  回:字節(jié)數(shù)據(jù)
  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;//構(gòu)成字符串
  106. }



復(fù)制代碼


全部程序51hei下載地址:
USART串口中斷.7z (292.74 KB, 下載次數(shù): 20)
USART(輪詢法接收數(shù)據(jù)).7z (299.78 KB, 下載次數(shù): 13)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表