一、STM32cubemx 对stm32F405RCT6的串口最大速率测试
前面的stm32cubemx初始化部分,参考这一篇博文。
STM32串口 14MBit/s波特率测试_stm32 vcp 波特率-CSDN博客
这里我把串口UART的TX和RX通过短接,自环的方式
分别把串口的波特率设置为(bps)
19200、115200、230400、460800、1000000、2000000
每次发送60s的数据,计算出每秒的数据量
串口助手用的是正点原子公司,例如波特率 1000 000bps,数据位8位,停止位1位。
60s一共发送5996388个数据包。计算出1s发送99.9K个数据包,速率为99.9K/s。
设置不同的波特率:19200、115200、230400、460800、1000000、2000000
每次发送60s的数据,计算出每秒的数据包
波特率 | 每秒的数据包 |
19200 | 1.9K |
115200 | 11K |
230400 | 23K |
460800 | 46K |
1000 000 | 99K |
2000 000 | 151K |
从上表看出,从19200到1000000,数据量和波特率基本都是按照比例来的。
到了2000 000波特率,就出现发送数据量不成比例,可能是和单片机串口速率、线缆,上位机等限制有关系。
但是19200波特率 算下来每秒的数据量应该为19.2K,但实际测试得到的是1.9K个数据包。
我们分析下原因。
二、串口报文组成
串口的报文数据由:
起始位(1bit)+ 数据位(5~8bit)+ 奇偶校验位(1bit)+ 停止位(1~1.5bit)
1、起始位
在发送有效数据前,无需配置,会自动产生1bit 逻辑“0”的低电平的起始位,表示串口数据传输开始,之后开始发送有效数据。
2、数据位
数据位通常是5~8位,我们设置是8位。
串口助手设置也是8位数据位。
3、停止位
停止位,停止位是一帧数据结束的标志,可以是1bit、1.5bit或者2bit逻辑“1” 高电平,
这里选择设置1位停止位。
4、校验位
奇偶校验位,因为在通信过程中易受到外部干扰而导致数据出现偏差,所以在有效数据之后增加了校验位来解决这个问题,校验方式需要配置,校验方式有奇校验、偶校验、0校验和1校验:
奇校验要求有效数据和校验位中“1”的个数为奇数;
偶校验则要求有效数据和校验位中“1”的个数为偶数;
0校验位则是校验位始终为0,在收到报文后,检测校验位是否为0;
1校验则是校验位始终为1,在收到报文后,检测校验位是否为1;
这里选择无校验位。
综上累加,得到每个数据帧/包的长度=
起始位(1bit)+ 数据位(5~8bit)+ 奇偶校验位(1bit)+ 停止位(1~1.5bit)
=1 + 8 + 0 + 1=10位。
那么就除了波特率2000 000bps,其他的都对应上了。
我们再来验证下,数据位长度发生变化,对数据的收发有无影响。
5、验证一
在stm32cubemx的设置界面中,把数据位还是8位。
校验位改成奇数校验。能看到数据长度是包含校验位的。
生成初始化代码:
huart1.Instance = USART1;
huart1.Init.BaudRate =115200;//波特率
huart1.Init.WordLength = UART_WORDLENGTH_8B; //数据位9位,包含校验位
huart1.Init.StopBits = UART_STOPBITS_1;//1位停止位
huart1.Init.Parity = UART_PARITY_ODD;//奇校验
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_8;
if (HAL_UART_Init(&huart1) != HAL_OK)
这时候的串口助手数据位要改成7位(应该是不包含校验位)。校验位改成ODD。
发送一分钟的数据量
算出来一秒钟有11.33K个数据包,每个数据包的长度
=起始位(1bit)+ 数据位(5~8bit)+ 奇偶校验位(1bit)+ 停止位(1~1.5bit)
=1 + 7 + 1 + 1=10位。
11.33K *10 =113.3 与115.2Kbps。基本吻合。
因为我是手动一分钟计时,存在一定的误差。
6、验证二
在stm32cubemx的设置界面中,把数据位改成9位。能看到数据长度是包含校验位的。
生成初始化代码
huart1.Instance = USART1;
huart1.Init.BaudRate =115200;//波特率
huart1.Init.WordLength = UART_WORDLENGTH_9B; //数据位9位,包含校验位
huart1.Init.StopBits = UART_STOPBITS_1;//1位停止位
huart1.Init.Parity = UART_PARITY_ODD;//奇校验
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_8;
if (HAL_UART_Init(&huart1) != HAL_OK)
这时候串口助手,数据位改成8位,校验位为odd,
.发送一分钟数据,
算出来一秒钟有10.39K个数据包,每个数据包的长度
=起始位(1bit)+ 数据位(5~8bit)+ 奇偶校验位(1bit)+ 停止位(1~1.5bit)
=1 + 8 + 1 + 1=11位。
10.39K *11 =114.29与115.2Kbps基本吻合。
综上测试1,2.数据位长度发生变化,对数据的收发无影响。
7、验证三,波特率设置为1000 000bps
在stm32cubemx的设置界面中,把数据位改成9位。能看到数据长度是包含校验位的。
生成初始化代码
huart1.Instance = USART1;
huart1.Init.BaudRate =1000000;//波特率
huart1.Init.WordLength = UART_WORDLENGTH_9B; //数据位9位,包含校验位
huart1.Init.StopBits = UART_STOPBITS_1;//1位停止位
huart1.Init.Parity = UART_PARITY_ODD;//奇校验
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_8;
if (HAL_UART_Init(&huart1) != HAL_OK)
这时候串口助手,数据位改成8位,校验位为odd,
.发送一分钟数据,
算出来一秒钟有8.34K个数据包,每个数据包的长度
=起始位(1bit)+ 数据位(5~8bit)+ 奇偶校验位(1bit)+ 停止位(1~1.5bit)
=1 + 8 + 1 + 1=11位。
8.34K *11 =916.85K与1000Kbps差的较多。
综上测试3.串口增加校验位,在波特率1000000bps时候,会出现数据收发速度达不到要求的情况。
所以,若存在校验位,就要考虑降低串口的波特率设定。