[其他] STM32F103RCT6 两个串口通讯程序

[复制链接]
 楼主| 有何不可0365 发表于 2022-7-30 22:59 | 显示全部楼层 |阅读模式
STM32F103RCT6 两个串口通讯程序 此程序为STM32F103RCT6单片机UART1 与UART3两个个串口通讯实验,UART1与UART3互相收发信息。两个串口需要同时与电脑相连接。串口1利用STM32自身串口,串口3通过CH340模块与电脑USB通讯。

 楼主| 有何不可0365 发表于 2022-7-30 23:00 | 显示全部楼层
串口1给串口3发送数据,串口3接收后打印“串口1给串口3发送数据” 串口3给串口1发送数据,串口1接收后打印“串口1给串口3发送数据”
 楼主| 有何不可0365 发表于 2022-7-30 23:01 | 显示全部楼层
硬件连接图
517762e547a73bbb7.png
 楼主| 有何不可0365 发表于 2022-7-30 23:02 | 显示全部楼层
实验结果图
9561662e547c8c52df.png
 楼主| 有何不可0365 发表于 2022-7-30 23:02 | 显示全部楼层
程序代码链接: //download.csdn.net/download/qq_42258981/12255597.


 楼主| 有何不可0365 发表于 2022-7-30 23:03 | 显示全部楼层
  1. #include "sys.h"
  2. #include "usart.h"       

  3. #if SYSTEM_SUPPORT_OS
  4. #include "includes.h"//ucos 使用          
  5. #endif

  6. //加入以下代码,支持printf函数,而不需要选择use MicroLIB          
  7. #if 1
  8. #pragma import(__use_no_semihosting)            
  9. //标准库需要的支持函数                 
  10. struct __FILE
  11. {
  12.         int handle;

  13. };

  14. FILE __stdout;      
  15. //定义_sys_exit()以避免使用半主机模式   
  16. void _sys_exit(int x)
  17. {
  18.         x = x;
  19. }
  20. //重定义fputc函数
  21. int fputc(int ch, FILE *f)
  22. {      
  23.         while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
  24.     USART1->DR = (u8) ch;   
  25. while((USART3->SR&0X40)==0);//循环发送,直到发送完毕   
  26.     USART3->DR = (u8) ch;     
  27.         return ch;
  28. }
  29. #endif

  30. /********************  USART1   *******************/

  31. #if EN_USART1_RX   //如果使能了接收
  32. //串口1中断服务程序
  33. //注意,读取USARTx->SR能避免莫名其妙的错误          
  34. u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
  35. //接收状态
  36. //bit15,        接收完成标志
  37. //bit14,        接收到0x0d
  38. //bit13~0,        接收到的有效字节数目
  39. u16 USART_RX_STA=0;       //接收状态标记          

  40. u8 aRxBuffer[RXBUFFERSIZE];//HAL库使用的串口接收缓冲
  41. UART_HandleTypeDef UART1_Handler; //UART句柄
  42.   
  43. //初始化IO 串口1
  44. //bound:波特率
  45. void uart_init(u32 bound)
  46. {       
  47.         //UART 初始化设置
  48.         UART1_Handler.Instance=USART1;                                            //USART1
  49.         UART1_Handler.Init.BaudRate=bound;                                    //波特率
  50.         UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式
  51.         UART1_Handler.Init.StopBits=UART_STOPBITS_1;            //一个停止位
  52.         UART1_Handler.Init.Parity=UART_PARITY_NONE;                    //无奇偶校验位
  53.         UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控
  54.         UART1_Handler.Init.Mode=UART_MODE_TX_RX;                    //收发模式
  55.         HAL_UART_Init(&UART1_Handler);                                            //HAL_UART_Init()会使能UART1
  56.        
  57.         HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
  58.   
  59. }

  60. //UART底层初始化,时钟使能,引脚配置,中断配置
  61. //此函数会被HAL_UART_Init()调用
  62. //huart:串口句柄

  63. void HAL_UART_MspInit(UART_HandleTypeDef *huart)
  64. {
  65.     //GPIO端口设置
  66.         GPIO_InitTypeDef GPIO_Initure;
  67.        
  68.         if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
  69.         {
  70.                 __HAL_RCC_GPIOA_CLK_ENABLE();                        //使能GPIOA时钟
  71.                 __HAL_RCC_USART1_CLK_ENABLE();                        //使能USART1时钟
  72.                 __HAL_RCC_AFIO_CLK_ENABLE();
  73.        
  74.                 GPIO_Initure.Pin=GPIO_PIN_9;                        //PA9
  75.                 GPIO_Initure.Mode=GPIO_MODE_AF_PP;                //复用推挽输出
  76.                 GPIO_Initure.Pull=GPIO_PULLUP;                        //上拉
  77.                 GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
  78.                 HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //初始化PA9

  79.                 GPIO_Initure.Pin=GPIO_PIN_10;                        //PA10
  80.                 GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;        //模式要设置为复用输入模式!       
  81.                 HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //初始化PA10
  82.                
  83. #if EN_USART1_RX
  84.                 HAL_NVIC_EnableIRQ(USART1_IRQn);                                //使能USART1中断通道
  85.                 HAL_NVIC_SetPriority(USART1_IRQn,3,3);                        //抢占优先级3,子优先级3
  86. #endif       
  87.         }
  88.        
  89.         if(huart->Instance==USART3)//如果是串口3,进行串口1 MSP初始化
  90.         {
  91.                 __HAL_RCC_GPIOB_CLK_ENABLE();                        //使能GPIOB时钟
  92.                 __HAL_RCC_USART3_CLK_ENABLE();                        //使能USART3时钟
  93.                 __HAL_RCC_AFIO_CLK_ENABLE();
  94.        
  95.                 GPIO_Initure.Pin=GPIO_PIN_10;                        //PB10
  96.                 GPIO_Initure.Mode=GPIO_MODE_AF_PP;                //复用推挽输出
  97.                 GPIO_Initure.Pull=GPIO_PULLUP;                        //上拉
  98.                 GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
  99.                 HAL_GPIO_Init(GPIOB,&GPIO_Initure);                   //初始化PA9

  100.                 GPIO_Initure.Pin=GPIO_PIN_11;                        //PB11
  101.                 GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;        //模式要设置为复用输入模式!       
  102.                 HAL_GPIO_Init(GPIOB,&GPIO_Initure);                   //初始化PB11
  103.                
  104. #if EN_USART3_RX
  105.                 HAL_NVIC_EnableIRQ(USART3_IRQn);                                //使能USART3中断通道
  106.                 HAL_NVIC_SetPriority(USART3_IRQn,3,2);                        //抢占优先级3,子优先级2
  107. #endif       
  108.         }
  109. }

  110. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  111. {
  112.         if(huart->Instance==USART1)//如果是串口1
  113.         {
  114.                 if((USART_RX_STA&0x8000)==0)//接收未完成
  115.                 {
  116.                         if(USART_RX_STA&0x4000)//接收到了0x0d
  117.                         {
  118.                                 if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;//接收错误,重新开始
  119.                                 else USART_RX_STA|=0x8000;        //接收完成了
  120.                         }
  121.                         else //还没收到0X0D
  122.                         {       
  123.                                 if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000;
  124.                                 else
  125.                                 {
  126.                                         USART3_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ;
  127.                                         USART_RX_STA++;
  128.                                         if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收          
  129.                                 }                 
  130.                         }
  131.                 }

  132.         }
  133. }

  134. //串口1中断服务程序
  135. void USART1_IRQHandler(void)                       
  136. {
  137.         u32 timeout=0;
  138. #if SYSTEM_SUPPORT_OS                 //使用OS
  139.         OSIntEnter();   
  140. #endif
  141.        
  142.         HAL_UART_IRQHandler(&UART1_Handler);        //调用HAL库中断处理公用函数
  143.        
  144.         timeout=0;
  145.     while (HAL_UART_GetState(&UART1_Handler) != HAL_UART_STATE_READY)//等待就绪
  146.         {
  147.          timeout++;超时处理
  148.      if(timeout>HAL_MAX_DELAY) break;               
  149.        
  150.         }
  151.      
  152.         timeout=0;
  153.         while(HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1
  154.         {
  155.          timeout++; //超时处理
  156.          if(timeout>HAL_MAX_DELAY) break;       
  157.         }
  158. #if SYSTEM_SUPPORT_OS                 //使用OS
  159.         OSIntExit();                                                                                           
  160. #endif
  161. }
  162. #endif       

  163. /********************  USART3   *******************/

  164. #if EN_USART3_RX   //如果使能了接收
  165. //串口1中断服务程序
  166. //注意,读取USARTx->SR能避免莫名其妙的错误          
  167. u8 USART3_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
  168. u16 USART3_RX_STA=0;       //接收状态标记          

  169. //u8 aRxBuffer[RXBUFFERSIZE];//HAL库使用的串口接收缓冲
  170. UART_HandleTypeDef UART3_Handler; //UART句柄
  171.   
  172. //初始化IO 串口1
  173. //bound:波特率
  174. void uart3_init(u32 bound)
  175. {       
  176.         //UART 初始化设置
  177.         UART3_Handler.Instance=USART3;                                            //USART3
  178.         UART3_Handler.Init.BaudRate=bound;                                    //波特率
  179.         UART3_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式
  180.         UART3_Handler.Init.StopBits=UART_STOPBITS_1;            //一个停止位
  181.         UART3_Handler.Init.Parity=UART_PARITY_NONE;                    //无奇偶校验位
  182.         UART3_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控
  183.         UART3_Handler.Init.Mode=UART_MODE_TX_RX;                    //收发模式
  184.         HAL_UART_Init(&UART3_Handler);                                            //HAL_UART_Init()会使能UART3
  185.        
  186.         HAL_UART_Receive_IT(&UART3_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
  187.   
  188. }

  189. //UART底层初始化,时钟使能,引脚配置,中断配置
  190. //此函数会被HAL_UART_Init()调用
  191. //huart:串口句柄



  192. //串口3中断服务程序
  193. void USART3_IRQHandler(void)                       
  194. {
  195.         u8 Res;
  196.         HAL_StatusTypeDef err;
  197. #if SYSTEM_SUPPORT_OS                 //使用OS
  198.         OSIntEnter();   
  199. #endif
  200.         if((__HAL_UART_GET_FLAG(&UART3_Handler,UART_FLAG_RXNE)!=RESET))  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
  201.         {
  202.                 Res=USART3->DR;
  203.                 if((USART3_RX_STA&0x8000)==0)//接收未完成
  204.                 {
  205.                         if(USART3_RX_STA&0x4000)//接收到了0x0d
  206.                         {
  207.                                 if(Res!=0x0a)USART3_RX_STA=0;//接收错误,重新开始
  208.                                 else USART3_RX_STA|=0x8000;        //接收完成了
  209.                         }
  210.                         else //还没收到0X0D
  211.                         {       
  212.                                 if(Res==0x0d)USART3_RX_STA|=0x4000;
  213.                                 else
  214.                                 {
  215.                                         USART_RX_BUF[USART3_RX_STA&0X3FFF]=Res ;
  216.                                         USART3_RX_STA++;
  217.                                         if(USART3_RX_STA>(USART_REC_LEN3-1))USART3_RX_STA=0;//接收数据错误,重新开始接收          
  218.                                 }                 
  219.                         }
  220.                 }                    
  221.         }
  222.         HAL_UART_IRQHandler(&UART3_Handler);       
  223. #if SYSTEM_SUPPORT_OS                 //使用OS
  224.         OSIntExit();                                                                                           
  225. #endif
  226. }
  227. #endif       
 楼主| 有何不可0365 发表于 2022-7-30 23:04 | 显示全部楼层
主函数
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "key.h"

  6. int main(void)
  7. {
  8.         u8 len;       
  9.         u16 times=0;
  10.        
  11.     HAL_Init();                                     //初始化HAL库   
  12.     Stm32_Clock_Init(RCC_PLL_MUL9);           //设置时钟,72M
  13.         delay_init(72);                               //初始化延时函数
  14.         uart_init(115200);                                        //初始化串口
  15.         uart3_init(115200);                                        //初始化串口
  16.         LED_Init();                                                        //初始化LED       
  17.         KEY_Init();                                                        //初始化按键
  18.        
  19.     while(1)
  20.     {       
  21.        if(USART3_RX_STA&0x8000)
  22.                 {                                          
  23.                         len=USART3_RX_STA&0x3fff;//得到此次接收到的数据长度
  24.                         HAL_UART_Transmit(&UART1_Handler,(uint8_t*)USART_RX_BUF,len,1000);        //发送接收到的数据
  25.                         while(__HAL_UART_GET_FLAG(&UART3_Handler,UART_FLAG_TC)!=SET);                //等待发送结束
  26.                         printf("\r\n\r\n");//插入换行
  27.                         USART3_RX_STA=0;
  28.                 }
  29.                  if(USART_RX_STA&0x8000)
  30.                 {                                          
  31.                         len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
  32.                         HAL_UART_Transmit(&UART3_Handler,(uint8_t*)USART3_RX_BUF,len,1000);        //发送接收到的数据
  33.                         while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET);                //等待发送结束
  34.                         printf("\r\n\r\n");//插入换行
  35.                         USART_RX_STA=0;
  36.                 }
  37.     }
  38. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

781

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

45

主题

781

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部