你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32串口多机通信

[复制链接]
STMCU小助手 发布时间:2022-1-23 15:26
最近在做多节点无线通信,用到STM32 USART多机串行通信。
记录下多机串行通信配置要点。
下面是我封装的会用到的函数:
  1. // .h
  2. #ifndef _MULTIUSART_H
  3. #define _MULTIUSART_H
  4. #include "sys.h"
  5. #include "stm32f10x_usart.h"

  6. /*
  7.     USART_SR状态寄存器
  8.     USART_DR数据寄存器
  9.     USART_BRR波特率寄存器
  10.    
  11.     TXD-PA9
  12.     RXD-PA10
  13. */

  14. #define USART_REC_LEN              60      
  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. extern void USART_InitEx(u32 bound);
  20. extern void USART_SendDataEx(USART_TypeDef* USARTx, uint16_t Data);
  21. extern void USART_SendAddr(USART_TypeDef* USARTx, uint16_t Addr);


  22. #endif
复制代码
  1. // .c
  2. #include "MultiUSART.h"



  3. //串口1中断服务程序
  4. //注意,读取USARTx->SR能避免莫名其妙的错误      
  5. u8 USART_RX_BUF[USART_REC_LEN] = "";     //接收缓冲,最大USART_REC_LEN个字节.
  6. //接收状态
  7. //bit15,    接收完成标志
  8. //bit14,    接收到0x0d
  9. //bit13~0,    接收到的有效字节数目
  10. u16 USART_RX_STA=0;       //接收状态标记      



  11. void USART_InitEx(u32 bound)
  12. {
  13.     GPIO_InitTypeDef GPIO_InitStructure;
  14.     USART_InitTypeDef USART_InitStructure;
  15.     NVIC_InitTypeDef NVIC_InitStructure;
  16.      
  17.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);    //使能USART1,GPIOA时钟
  18.      USART_DeInit(USART1);                                      //复位串口1
  19.    
  20.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;         
  21.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  22.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;            //复用推挽输出
  23.     GPIO_Init(GPIOA, &GPIO_InitStructure);            
  24.    
  25.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  26.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //浮空输入
  27.     GPIO_Init(GPIOA, &GPIO_InitStructure);         

  28.    //Usart1 NVIC 配置
  29.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  30.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
  31.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子优先级3
  32.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
  33.     NVIC_Init(&NVIC_InitStructure);   
  34.   
  35.    //USART 初始化设置
  36.     USART_InitStructure.USART_BaudRate = bound;
  37.     USART_InitStructure.USART_WordLength = USART_WordLength_9b;
  38.     USART_InitStructure.USART_StopBits = USART_StopBits_1;
  39.     USART_InitStructure.USART_Parity = USART_Parity_No;        
  40.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  41.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;   

  42.     USART_Init(USART1, &USART_InitStructure);         //初始化串口
  43.     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);    //开启中断   接收中断
  44.     USART_Cmd(USART1, ENABLE);                        //使能串口
  45.    
  46.    
  47.     USART_SetAddress(USART1, 0x01);                    //设置USART1节点地址
  48.     //USART_WakeUpConfig(USART1, USART_WakeUp_AddressMark);//地址标记唤醒
  49.    
  50.     //USART_ReceiverWakeUpCmd(USART1,ENABLE);
  51. }


  52. void USART_SendDataEx(USART_TypeDef* USARTx, uint16_t Data)
  53. {
  54.     /* Check the parameters */
  55.     assert_param(IS_USART_ALL_PERIPH(USARTx));
  56.     assert_param(IS_USART_DATA(Data));
  57.    
  58.     /* Transmit Data */
  59.     USARTx->DR = (Data & (uint16_t)0x01FF);
  60.    
  61.     //等待发送缓冲区空
  62.     //或   等待发送结束
  63.     //while((USART1->SR&0X40)==0);
  64.     while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET){};
  65. }

  66. void USART_SendAddr(USART_TypeDef* USARTx, uint16_t Addr)
  67. {
  68.     /* Check the parameters */
  69.     assert_param(IS_USART_ALL_PERIPH(USARTx));
  70.    
  71.     // 9位字长, 最高位为1,低四位为地址
  72.     //USARTx->DR = (1<<8) | Addr;
  73.     Addr |= (uint16_t)0x0100;
  74.     USARTx->DR = (Addr & (uint16_t)0x010F);
  75. }

  76. #if EN_USART1_RX
  77. void USART1_IRQHandler(void)                                //串口1中断服务程序
  78. {
  79.     u8 Res;
  80.     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)      //接收中断(接收到的数据必须是0x0d 0x0a结尾)
  81.     {
  82.         Res =USART_ReceiveData(USART1);//(USART1->DR);        //读取接收到的数据
  83.         
  84.         if((USART_RX_STA&0x8000)==0)                        //接收未完成
  85.         {
  86.             if(USART_RX_STA&0x4000)                            //接收到了0x0d
  87.             {
  88.                 if(Res!=0x0a)
  89.                     USART_RX_STA=0;                            //接收错误,重新开始
  90.                 else
  91.                     USART_RX_STA|=0x8000;                    //接收完成了
  92.             }
  93.             else                                             //还没收到0X0D
  94.             {   
  95.                 if(Res==0x0d)
  96.                     USART_RX_STA|=0x4000;
  97.                 else
  98.                 {
  99.                     USART_RX_BUF[USART_RX_STA&0X3FFF]=Res;
  100.                     USART_RX_STA++;
  101.                     if(USART_RX_STA>(USART_REC_LEN-1))
  102.                         USART_RX_STA=0;                        //接收数据错误,重新开始接收      
  103.                 }         
  104.             }
  105.         }            
  106.      }
  107. }
  108. #endif
复制代码
在主机端,可以写个键盘控制发送地址,类似:
switch(KeyValue)
        {
            case 1: USART_SendAddr(USART1, 0x01); break;  //从机1
            case 2: USART_SendAddr(USART1, 0x02); break;  //从机2
.............
然后即可自己设定通信协议分别处理从机发过来的数据了。

在从机端,由于要设为静默模式:
USART_SetAddress(USART1, 0x01);    //设置USART1节点地址 如从机1设为0x01
USART_WakeUpConfig(USART1, USART_WakeUp_AddressMark);  //地址标记唤醒
USART_ReceiverWakeUpCmd(USART1,ENABLE);  //使处于静默模式
这几句在串口初始化时要开启。

当主机发出正确地址给从机时,下面if 语句便成立可执行。
//从机被唤醒, 接收中断恢复正常   
if((USART1->CR1 &((uint16_t)0x0002)) == 0)
{........}
从而可在其中添加从机要给主机发送数据的程序。

收藏 评论0 发布时间:2022-1-23 15:26

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版