完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
一、概要
使用UART串口时往往比较喜欢配置波特率为标准的9600、115200等,而实际应用中需要更高的波特率。如果在配置UART波特率时任意输入一个很高的波特率,如200000,那么很有可能因为单片机的波特率寄存器配置方法,导致实际的波特率与200000相差很大,往往当误差大于2%时就不能稳定通讯了。因此,在获得尽量高的波特率的同时,还要保证尽量小的波特率误差,最粗暴的方式就是把目标波特率范围内的所有波特率都算一遍,然后取波特率高且误差小的。 二、STM32F4波特率的计算方法 以stm32f4系列为例,其波特率的计算方法如下,公式1: 1.fCK为UART外设的运行频率,stm32f4中为主频的一半; 2.OVER8是8倍过采样、16倍过采样的选择寄存位,当其设置为0时,表示使用16倍过采样,当其设置为1时,表示使用8倍过采样; 3.USARTDIV 是一个存放在 USART_BRR 寄存器中的无符号定点数,当 OVER8=0 时,小数部分编码为 4 位并通过 USART_BRR 寄存器中的 DIV_fraction[3:0] 位编程,当 OVER8=1 时,小数部分编码为 3 位并通过 USART_BRR 寄存器中的 DIV_fraction[2:0] 位编程,此时 DIV_fraction[3] 位必须保持清零状态。 USART_BRR寄存器的内容如下所示 由USART_BRR计算USARTDIV的步骤在参考手册里已经做了如下示例说明 三、高波特率、低误差的计算方法 有了以上的理论基础,那么就可以在matlab中进行编程了。具体思路为:由初始初始波特率到截至期望波特率,按100进行步进增加;每次的波特率计算出USARTDIV后,按照STM32写USART_BRR的方式写到DIV_Mantissa与DIV_Fraction中;然后按照USART_BRR中的DIV_Mantissa与DIV_Fraction的值对实际波特率按公式1进行计算;最后得出期望波特率与实际波特率的误差,只存储误差小于2%的记录。这样一来,我们就可以获得高波特率,且低误差的波特率了,按照此波特率进行设置没有问题。 具体程序如下,备注已经写的非常清楚了,可以拿来就用。如果你的使用情景和我不同,那么只可能改以下三个地方: 1.uart_fclk的设置,具体按你的主频来,主频除以2就是uart_fclk; 2.uart_overSample的设置,一般默认是按16倍过采样,如果你用了8倍,改成8即可; 3.for baud=9600: 100:5000000,初始期望波特率与截至期望波特率。 %存放波特率和误差的数组,第一列存期望波特率,第二列存实际波特率,第三列存误差 resArr = 1; %resArr数组的写指针 pWresArr = 1; %usart外设的频率,挂载在APB1总线上,主频168M时usart外设频率为84MHz,可根据实际情况调整 uart_fclk = 84000000; %默认的16倍过采样,OVER8=1时为8 uart_overSample = 16; %USARTDIV的值 uart_div = 0; %USARTDIV在USART_BRR寄存器中的整数部分 DIV_Mantissa = 0; %USARTDIV的小数部分 DIV_Fraction = 0; %实际波特率 true_baudrate = 0; %从波特率9600开始算,直到5M,步进值100 for baud=9600:100:5000000 %第一步,计算当前波特率算出的USARTDIV,并按16倍过采样保存到小数点后四位 uart_div = uart_fclk / (baud * uart_overSample); uart_div = roundn(uart_div,-4); %第二步,获得USARTDIV的小数部分,乘以16后四舍五入到整数 DIV_Fraction = uart_div - floor(uart_div); DIV_Fraction = round(DIV_Fraction * uart_overSample); %第三步,计算真实的波特率 %此时USART_BRR寄存器中存储了USARTDIV的整数部分DIV_Mantissa和其小数部分DIV_Fraction DIV_Mantissa = floor(uart_div); true_baudrate = uart_fclk / (uart_overSample * (DIV_Mantissa + roundn(DIV_Fraction/16,-4))); %第四步,计算实际波特率和期望波特率的百分比误差,通常小于2%可认为可以比较稳定的通讯 diff = (true_baudrate - baud) / baud *100; if(diff 《= 2 && diff 》= -2) %存期望波特率到resArr resArr(pWresArr,1) = baud; %存实际波特率到resArr resArr(pWresArr,2) = true_baudrate; %存百分比误差到resArr resArr(pWresArr,3) = diff; %resArr写指针加1 pWresArr = pWresArr + 1; end end 四、实验验证 1.与参考手册中的典型波特率误差进行比对 运行matlab程序后,在resArr里便输出了结果,在STM32F4参考手册中给出了许多典型波特率以及其误差,如下所示,由于程序里设置的频率为84MHz,故只关心红框部分即可。 在我们的resArr中分别找到这几个典型波特率,发现与官方表格结果完全一致。 2.实际验证 在resArr中选一个较大的波特率,因为resArr之中只保存了误差小于2%的结果,所以,放心大胆的选把。这里随便选一个,1.9M,相当快的波特率了。 在单片机中设置波特率,并打印一句“AD7606 Reset”,如下所示 在串口助手中设置波特率为1908900,可以正常通讯,如下所示。 最后,由于使用的ttl转USB模块用的是CH340芯片,其最大波特率为2M,所以更高波特率的就暂时没法测了。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 06:04 , Processed in 0.663119 second(s), Total 47, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号