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

【STM32F030开发】波特率自动识别 精华  

[复制链接]
creep 发布时间:2015-12-1 22:57
前几天参加论坛活动人品小爆发抽中了一个NUCLEO-STM32F030和一个移动电源,感谢与非网,ST,沐紫和苏柚,特别要感谢苏柚的不辞辛劳。
QQ图片20151126215320.jpg QQ图片20151126215856.jpg QQ图片20151126215330.jpg NUCLOE-STM32F030:
为了避免板子一到手就沦落到吃灰的命运,趁着新鲜感和热乎劲先写个测试程序,也是为继续给自己攒人品。
ST的很多ARM系列的串口都有个自动检测波特率的功能,比如这个STM32F030,还有前端时间论坛搞活动送的STM32L476。
使用自动识别波特率主要有2个方面的原因:  
       ●:通信之前并不能确定波特率或者波特率可能不固定
       ●:系统的时钟准确性较差,计算出来的波特率可能不准确
自动识别的原理是MCU内部检测一个下降沿到上升沿的时间间隔进而算出来波特率,STM32030有2种模式: 1.png
STM32L476有4中模式:
2.png
3.png
这些模式的原理基本是上面说的那样测跳变沿的时间来计算波特率,下面我们使用模式0来测试。模式0的要求是发送的一个字节的第一个bit是1,比如
小写的a(0110 0001),MCU在接受到这个字节后会根据这个字节算出新波特率并更新相应的串口的波特率,下面的通信就使用这个波特率进行通信。
使用这个功能时要注意有的串口可能不带这功能,比如STM32030只有串口1带有自动识别功能,串口2并不到自动识别,有的单片机不同串口支持的模式也不太相同,下面是STM320X0系列的一些支持:
4.png
在初始化串口是默认设置波特率为为9600,然后用不同的波特率向MCU进行通信测试自动识别功能。NUCLEO测试时可以使用杜邦线将串口1的PA9/PA10连接到STLINK上面的TX/RX引脚,这样就可以借助STLINK的虚拟串口和串口1进行通信了,NUCLEO板子上默认STLINK虚拟串口是和串口2物理想连接的。STM030有标准库,所以我先使用标准库测试。
串口的初始化和平常一样:
  1. void USART_Config(void)
  2. {        
  3.   USART_InitTypeDef USART_InitStructure;
  4.   GPIO_InitTypeDef GPIO_InitStructure;
  5.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
  7.        
  8.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
  9.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);
  10.         //U1_TX :PA9
  11.         //U1_RX :PA10
  12.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
  13.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  14.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  15.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  16.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  17.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  18.        
  19.   USART_InitStructure.USART_BaudRate = 9600;
  20.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  21.   USART_InitStructure.USART_StopBits = USART_StopBits_1;
  22.   USART_InitStructure.USART_Parity = USART_Parity_No;
  23.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  24.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  25.   USART_Init(USART1, &USART_InitStructure);
  26.   USART_Cmd(USART1, ENABLE);
  27.        
  28. }
复制代码
然后打开自动识别功能,等待接受字符进行识别,然后计算识别出来的波特率;
  1. void AutoBauRate_StartBitMethod(void)
  2. {   
  3.         uint32_t baudrateval = 0;
  4.         uint8_t  tmp[25];
  5.        
  6.   USART_AutoBaudRateConfig(USART1, USART_AutoBaudRate_StartBit);  

  7.   USART_AutoBaudRateCmd(USART1, ENABLE);  

  8.   while(USART_GetFlagStatus(USART1, USART_FLAG_REACK) == RESET)
  9.   {}   

  10.   while(USART_GetFlagStatus(USART1, USART_FLAG_TEACK) == RESET)
  11.   {}  
  12.   
  13.   /* Loop until the end of Autobaudrate phase */
  14.   while(USART_GetFlagStatus(USART1, USART_FLAG_ABRF) == RESET)
  15.   {}  
  16.   
  17.   /* If AutoBaudBate error occurred */
  18.   if (USART_GetFlagStatus(USART1, USART_FLAG_ABRE) != RESET)
  19.   {
  20.   }
  21.   else
  22.   {
  23.    
  24.     /* Wait until RXNE flag is set */
  25.     while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
  26.     {}
  27.    
  28.     /* Wait until TXE flag is set */   
  29.     while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
  30.     {}
  31.    
  32.                 //将收到的数据发送到串口
  33.     USART_SendData(USART1, USART_ReceiveData(USART1));
  34.     while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  35.     {}

  36.                 //计算波特率
  37.     baudrateval = RCC_Clocks.SYSCLK_Frequency / USART1->BRR;
  38.                 sprintf((char*)tmp,"\r\n检测到波特率为:%d\r\n",baudrateval);
  39.                 USART1_Send(tmp,25);   
  40.   }  
  41. }
复制代码
分别测试几种波特率向MCU发送数据a:可以看到识别计算出来的波特率和实际有差别,因为这个差别在串口波特率的接受范围内,所以并不影响实际的通信。

9600.png 15200.png 19200.png

460800.png 921600.png

NUCLEO-STM32L476:
上面使用的STM32F030可能很多小伙伴没有这个板子,下面用NUCLEO-STML476测试下,相应的使用的HAL库。使用HAL设置比较简单,在初始化串口时顺便打开自动识别高级功能即可。
  1. void USART1_Init(void)
  2. {
  3.   UartHandle.Instance        = USART1;
  4.   UartHandle.Init.BaudRate   = 9600;
  5.   UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
  6.   UartHandle.Init.StopBits   = UART_STOPBITS_1;
  7.   UartHandle.Init.Parity     = UART_PARITY_NONE;
  8.   UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
  9.   UartHandle.Init.Mode       = UART_MODE_TX_RX;
  10.   UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT;
  11.         UartHandle.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE;
  12.         UartHandle.AdvancedInit.AutoBaudRateMode = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT;
  13.         USART1_MspInit();
  14.   if(HAL_UART_Init(&UartHandle) != HAL_OK)
  15.   {
  16.     while(1);
  17.   }               
  18. }
复制代码
波特率初始化为9600后BRR的值为0X208D(8333),此时的波特率为80000000/8333 = 9600.此时MCU主频为80MHZ
5.png
使用460800的波特率和MCU通信后BRR的值为:0xAE(174) ,此时的波特率为 80000000/174 = 459770.误差率为0.22%
6.png
总体来说波特率自动识别还是很实用的,识别一次后就可以一直使用,如果有需要还可以继续识别。
测试代码:
USART_AutoBaudRate_STM32F030标准库模式.rar (232.69 KB, 下载次数: 427)

评分

参与人数 1 ST金币 +30 收起 理由
沐紫 + 30

查看全部评分

收藏 26 评论64 发布时间:2015-12-1 22:57

举报

64个回答
kingsings 回答时间:2015-12-1 23:26:19
ST的芯片还有这功能,学习了
风子 回答时间:2015-12-2 00:30:16
学习了,大神出手就是不一样
Paderboy 回答时间:2015-12-2 08:05:46
大神出手就是不一样,学习啊。。。
STMCU-Logo.png
foxglove 回答时间:2015-12-2 08:07:03
波特率自动识别
slotg 回答时间:2015-12-2 08:29:08
很不错,感谢分享。
liuyu-419812 回答时间:2015-12-2 08:44:11
挺好的,学习了
disheng4688 回答时间:2015-12-2 08:44:13
学习                  
zhangdaijin 回答时间:2015-12-2 08:47:50
alvin_ 回答时间:2015-12-2 08:52:38
一次中两个奖!这真是人品爆发了!

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

官网相关资源

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