stm32串口實驗:stm32通過usart1進行串口收發,PA9(TX)和PA10(RX)


這是stm32開發中比較簡單的實驗,原理是通過串口助手發送信息,stm32接收到信息以后在串口助手中打印相同的內容。

這里直接分享keil5工程代碼,是在工程模板的基礎上移植和修改了正點原子的串口代碼

百度網盤鏈接:https://pan.baidu.com/s/1aptEjcYPuQlDD_ayZaNoJw
提取碼:8hr9

(如果失效的話可以在下方評論留下郵箱,我看到會給你發一份)

順便把usart.c和usart.h還有mian.c中的代碼復制到下面,小伙伴可以直接移植到自己的工程中

實現的效果也在下面放上串口助手中顯示的圖片

usart.c

  1 #include "sys.h"
  2 #include "usart.h"
  3 
  4 
  5 //STM32F103核心板例程
  6 //庫函數版本例程
  7 /********** mcudev.taobao.com 出品  ********/
  8 
  9 
 10 //////////////////////////////////////////////////////////////////////////////////      
 11 //如果使用ucos,則包括下面的頭文件即可.
 12 #if SYSTEM_SUPPORT_UCOS
 13 #include "includes.h"                    //ucos 使用      
 14 #endif
 15 //////////////////////////////////////////////////////////////////////////////////     
 16 //STM32開發板
 17 //串口1初始化           
 18 
 19 //////////////////////////////////////////////////////////////////////////////////       
 20  
 21 
 22 //////////////////////////////////////////////////////////////////
 23 //加入以下代碼,支持printf函數,而不需要選擇use MicroLIB      
 24 #if 1
 25 #pragma import(__use_no_semihosting)             
 26 //標准庫需要的支持函數                 
 27 struct __FILE 
 28 { 
 29     int handle; 
 30 
 31 }; 
 32 
 33 FILE __stdout;       
 34 //定義_sys_exit()以避免使用半主機模式    
 35 void _sys_exit(int x) 
 36 { 
 37     x = x; 
 38 } 
 39 //重定義fputc函數 
 40 int fputc(int ch, FILE *f)
 41 {      
 42     while((USART1->SR&0X40)==0);//循環發送,直到發送完畢   
 43     USART1->DR = (u8) ch;      
 44     return ch;
 45 }
 46 #endif 
 47 
 48 /*使用microLib的方法*/
 49  /* 
 50 int fputc(int ch, FILE *f)
 51 {
 52     USART_SendData(USART1, (uint8_t) ch);
 53 
 54     while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}    
 55    
 56     return ch;
 57 }
 58 int GetKey (void)  { 
 59 
 60     while (!(USART1->SR & USART_FLAG_RXNE));
 61 
 62     return ((int)(USART1->DR & 0x1FF));
 63 }
 64 */
 65  
 66 #if EN_USART1_RX   //如果使能了接收
 67 //串口1中斷服務程序
 68 //注意,讀取USARTx->SR能避免莫名其妙的錯誤       
 69 u8 USART_RX_BUF[USART_REC_LEN];     //接收緩沖,最大USART_REC_LEN個字節.
 70 //接收狀態
 71 //bit15,    接收完成標志
 72 //bit14,    接收到0x0d
 73 //bit13~0,    接收到的有效字節數目
 74 u16 USART_RX_STA=0;       //接收狀態標記      
 75   
 76 void uart_init(u32 bound){
 77     //GPIO端口設置
 78   GPIO_InitTypeDef GPIO_InitStructure;
 79     USART_InitTypeDef USART_InitStructure;
 80     NVIC_InitTypeDef NVIC_InitStructure;
 81      
 82     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);    //使能USART1,GPIOA時鍾
 83      //USART1_TX   PA.9
 84     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
 85     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 86     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //復用推挽輸出
 87     GPIO_Init(GPIOA, &GPIO_InitStructure);
 88    
 89     //USART1_RX      PA.10
 90     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
 91     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
 92     GPIO_Init(GPIOA, &GPIO_InitStructure);  
 93 
 94    //Usart1 NVIC 配置
 95 
 96     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
 97     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優先級3
 98     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子優先級3
 99     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
100     NVIC_Init(&NVIC_InitStructure);    //根據指定的參數初始化VIC寄存器
101   
102    //USART 初始化設置
103 
104     USART_InitStructure.USART_BaudRate = bound;//一般設置為9600;
105     USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數據格式
106     USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
107     USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
108     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制
109     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //收發模式
110 
111     USART_Init(USART1, &USART_InitStructure); //初始化串口
112     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟中斷
113     USART_Cmd(USART1, ENABLE);                    //使能串口 
114 
115 }
116 
117 
118 
119 void USART1_IRQHandler(void)                    //串口1中斷服務程序
120     {
121     u8 Res;
122 #ifdef OS_TICKS_PER_SEC         //如果時鍾節拍數定義了,說明要使用ucosII了.
123     OSIntEnter();    
124 #endif
125     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中斷(接收到的數據必須是0x0d 0x0a結尾)
126         {
127         Res =USART_ReceiveData(USART1);//(USART1->DR);    //讀取接收到的數據
128         
129         if((USART_RX_STA&0x8000)==0)//接收未完成
130             {
131             if(USART_RX_STA&0x4000)//接收到了0x0d
132                 {
133                 if(Res!=0x0a)USART_RX_STA=0;//接收錯誤,重新開始
134                 else USART_RX_STA|=0x8000;    //接收完成了 
135                 }
136             else //還沒收到0X0D
137                 {    
138                 if(Res==0x0d)USART_RX_STA|=0x4000;
139                 else
140                     {
141                     USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
142                     USART_RX_STA++;
143                     if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收數據錯誤,重新開始接收      
144                     }         
145                 }
146             }            
147      } 
148 #ifdef OS_TICKS_PER_SEC         //如果時鍾節拍數定義了,說明要使用ucosII了.
149     OSIntExit();                                               
150 #endif
151 } 
152 #endif    

 

usart.h

 1 #ifndef __USART_H
 2 #define __USART_H
 3 #include "stdio.h"    
 4 #include "sys.h" 
 5 
 6 //STM32F103核心板例程
 7 //庫函數版本例程
 8 /********** mcudev.taobao.com 出品  ********/
 9 
10 //////////////////////////////////////////////////////////////////////////////////     
11 //STM32開發板
12 //串口1初始化           
13 
14 #define USART_REC_LEN              200      //定義最大接收字節數 200
15 #define EN_USART1_RX             1            //使能(1)/禁止(0)串口1接收
16           
17 extern u8  USART_RX_BUF[USART_REC_LEN]; //接收緩沖,最大USART_REC_LEN個字節.末字節為換行符 
18 extern u16 USART_RX_STA;                 //接收狀態標記    
19 //如果想串口中斷接收,請不要注釋以下宏定義
20 void uart_init(u32 bound);
21 #endif

 

main.c

 1 #include "sys.h"
 2 #include "delay.h"
 3 #include "usart.h"
 4 
 5 uint8_t t;
 6 uint8_t len;
 7 uint16_t times=0;
 8     
 9 int main(void)
10 {    
11     delay_init();     //延時函數初始化      
12     uart_init(115200);     //串口初始化為115200
13     
14     while(1)
15     {
16         if(USART_RX_STA&0x8000)  //USART_RX_STA第十六位為1則括號內為1,表示接收完數據
17         {                       
18             len=USART_RX_STA&0x3fff;//得到此次接收到的數據長度
19             printf("\r\n您發送的消息為:\r\n\r\n");
20             for(t=0;t<len;t++)
21             {
22                 USART_SendData(USART1, USART_RX_BUF[t]);//向串口1發送數據
23                 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待發送結束
24             }
25             printf("\r\n\r\n");//插入換行
26             USART_RX_STA=0;
27         }else
28         {
29             times++;
30             if(times%500==0)printf("請輸入數據,以回車鍵結束\n");  
31             delay_ms(10);   
32         }
33     }     
34 }

 

串口實驗效果圖:

未發送時

 

 發送數據時:

 祝小伙伴們2020加油!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM