#stm32 MCU# #STM32F030# #代码#
【STM32F030开发】波特率自动识别
本文转自STMCU论坛,作者creep.
ST的很多ARM系列的串口都有个自动检测波特率的功能,比如这个STM32F030,还有前端时间论坛搞活动送的STM32L476。
使用自动识别波特率主要有2个方面的原因:
●:通信之前并不能确定波特率或者波特率可能不固定
●:系统的时钟准确性较差,计算出来的波特率可能不准确
自动识别的原理是MCU内部检测一个下降沿到上升沿的时间间隔进而算出来波特率,STM32030有2种模式:
STM32L476有4中模式:
这些模式的原理基本是上面说的那样测跳变沿的时间来计算波特率,下面我们使用模式0来测试。模式0的要求是发送的一个字节的第一个bit是1,比如
小写的a(0110 0001),MCU在接受到这个字节后会根据这个字节算出新波特率并更新相应的串口的波特率,下面的通信就使用这个波特率进行通信。
使用这个功能时要注意有的串口可能不带这功能,比如STM32030只有串口1带有自动识别功能,串口2并不到自动识别,有的单片机不同串口支持的模式也不太相同,下面是STM320X0系列的一些支持:
在初始化串口是默认设置波特率为为9600,然后用不同的波特率向MCU进行通信测试自动识别功能。NUCLEO测试时可以使用杜邦线将串口1的PA9/PA10连接到STLINK上面的TX/RX引脚,这样就可以借助STLINK的虚拟串口和串口1进行通信了,NUCLEO板子上默认STLINK虚拟串口是和串口2物理想连接的。STM030有标准库,所以我先使用标准库测试。
void USART_Config(void)
{
USART_InitTypeDefUSART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);
//U1_TX:PA9
//U1_RX:PA10
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType= GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_UP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
USART_InitStructure.USART_BaudRate= 9600;
USART_InitStructure.USART_WordLength= USART_WordLength_8b;
USART_InitStructure.USART_StopBits= USART_StopBits_1;
USART_InitStructure.USART_Parity= USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode= USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1,&USART_InitStructure);
USART_Cmd(USART1,ENABLE);
}
然后打开自动识别功能,等待接受字符进行识别,然后计算识别出来的波特率;
void AutoBauRate_StartBitMethod(void)
{
uint32_tbaudrateval = 0;
uint8_ttmp[25];
USART_AutoBaudRateConfig(USART1,USART_AutoBaudRate_StartBit);
USART_AutoBaudRateCmd(USART1,ENABLE);
while(USART_GetFlagStatus(USART1,USART_FLAG_REACK) == RESET)
{}
while(USART_GetFlagStatus(USART1,USART_FLAG_TEACK) == RESET)
{}
/*Loop until the end of Autobaudrate phase */
while(USART_GetFlagStatus(USART1,USART_FLAG_ABRF) == RESET)
{}
/*If AutoBaudBate error occurred */
if(USART_GetFlagStatus(USART1, USART_FLAG_ABRE) != RESET)
{
}
else
{
/*Wait until RXNE flag is set */
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == RESET)
{}
/*Wait until TXE flag is set */
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET)
{}
//将收到的数据发送到串口
USART_SendData(USART1,USART_ReceiveData(USART1));
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{}
//计算波特率
baudrateval= RCC_Clocks.SYSCLK_Frequency / USART1->BRR;
sprintf((char*)tmp,"rn检测到波特率为:%drn",baudrateval);
USART1_Send(tmp,25);
}
}
分别测试几种波特率向MCU发送数据a:可以看到识别计算出来的波特率和实际有差别,因为这个差别在串口波特率的接受范围内,所以并不影响实际的通信。
总体来说波特率自动识别还是很实用的,识别一次后就可以一直使用,如果有需要还可以继续识别。
测试代码:
链接:https://pan.baidu.com/s/1EJRNbMhQX-vfwv-rVnrIqw
提取码:3xed
查看评论 回复
游客 | 2019-09-26 22:20:39 |
不错,挺详细的 |