串口的波特率与过采样的关系_串口过采样,2024年最新2024年Golang大厂面试分享

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注go)
img

正文

单片机串口在异步通信的时候通常采用过采样的方式来发送和接收串行数据,如下面数据手册中的说明:

反复看了多遍,大概意思是说减小过采样的倍数可以产生更精确的波特率,但是减小过采样倍数后,由于采样次数的减少在输入数据发生抖动的时候会导致误码率的增加,对于这段话的具体理解过程如下:

串口的设备时钟U_PCLK用于产生串口波特率时钟,比如设备时钟为12M,波特率为115200,则波特率时钟周期为12M/115200,用这个值来设置BRG寄存器;但是由于使用了过采样来实现串行数据的收发,因此需要使用到过采样寄存器(OSR),OSR寄存器中的值表示每个数据比特位的收发使用到的设备时钟数,比如OSR的值为0xF,表示每个数据比特位的收发需要使用到16个设备时钟周期,也就是说采样频率是波特率的16倍,最小可以到5倍,这个时候BRG寄存器的数值就应该设置为12M/115200/(OSR值+1),比如:    LPC_USART0->OSR = 0x07;
LPC_SYSCON->UARTCLKDIV     = 1;          /* UART时钟分频值为 1 */
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 14);  /* 初始化UART AHB时钟  */
LPC_USART0->BRG = SystemCoreClock * LPC_SYSCON->SYSAHBCLKDIV /
(LPC_SYSCON->UARTCLKDIV * (LPC_USART0->OSR+1) * UART_BPS) - 1; /* 串口通信波特率 */

这样通过BRG寄存器和OSR寄存器的设置就能进行正常的串口通信了,由于BRG寄存器为整数寄存器,在波特率比较高或者设置时钟频率低的时候误差比较大;比如OSR为16倍采样率的时候,经过上面式子计算出的BRG=6,用下面的算式计算出的波特率为:

uiRealbaud = (uint32_t)(SystemCoreClock * LPC_SYSCON->SYSAHBCLKDIV / 
((LPC_USART0->OSR+1) * uiClkDiv * uiUartBRG * (1 + (double)uiFDRMul / uiFDRDiv)))。12M/(16*1*7)=107,142.85,误差为:(115200-107143)/115200=7%,所以减小采样频率可以提高波特率精度。采样数据的减少,可能导致数据比特的错误,可以如下图来说明:

上图采样脉冲为3个,当使用5倍波特率进行采样的时候,这时采样设备时钟数为5个,第一个为开始采样时间,中间3个为连续的数据比特采样时钟,最后一个为结束采样时钟。如果数据比特的斜率有抖动,如下图,数据采样时钟可能采样到不对的电平信号,导致比特错误。

过采样能增强抗干扰的原理分析,以16倍频为例:标准UART的RXD前端有一个"1到0跳变检测器",当其连续接受到8个RXD上的地电平时,该检测器就认为RXD线出现了起始位,进入接受数据状态.在接受状态,接受控制器对数据位7,8,9三个脉冲采样,并遵从三中取二的原则确定最终值.采用这一方法的根本目的还是为了增强抗干扰,提高数据传送的可靠性,采样信号总是在每个接受位的中间位置,可以避开数据位两端的边沿失真,也可以防止接受时钟频率和发送时钟频率不完全同步引起的误差.异步串口通信的数据格式:

由于在空闲状态时,传送线为逻辑“1”状态,而数据的传送总是以一个起始位“0”开始,所以当接收器检测到一个从“1”向“0”的跳变时,便视为可能的起始位(要排除干扰引起的跳变);起始位被确认后,就知道发送器已开始发送,接收器就可以按这个数据通信格式接收后续的数据了;当检测到停止位“1”后就表明一帧字符数据已发送完毕。关于接收器的设计最主要的一点是如何提高采样的准确率,最好是保证采样点处于被采样数据的时间中间点。所以,在接收采样时要用比数据波特率高n倍(n≥1)速率的时钟对数据进行采样。在本程序中用16倍波特率时钟进行采样。结合图示,我们讲解一下如何让采样时刻处于被采样数据的时间中间点:

  1. 在t1时刻若检测到低电平,就开始对这个低电平进行连续的检测
  2. 当检测了8个时钟周期后,到达t2,此刻,若前面的8个周期都是低电平,则认为检测到了起始脉冲。否则就认为是干扰,重新检测。
  3. 在检测到起始位后,再计数16个采样时钟周期就到达了第一个数据位的时间中间点t3,在此刻采样数据并进行保存。
  4. 然后再经过16个周期,就是第二个数据位的时间中间点,在此时刻进行采样;然后,再经过16个周期,就是第三个数据位的时间中间点, 在此时刻进行采样……一直这样采样,直到把所有的数据位采样完毕。

分数波特率发生器:上面程序中计算波特率的方法是整数的方法,在设备时钟频率低或者波特率比较高的时候误差比较大,这个时候可以使用分数波特率发生器。比如,115200波特率,BRG寄存器的值=12M/(16*115200)=6.5104166666666666666666666666667=6(取整),然后mcu产生的实际波特率,用上面提到的计算公式为12M/(16*1*7)=107,142.85,误差为:(115200-107143)/115200=7%;2400波特率的时候,BRG寄存器的值=12M/(16*2400)=312.5=312(取整),然后mcu产生的实际波特率,用上面提到的计算公式为12M/(16*1*313)=2,396.166134185,误差为:(2400-2396)/2400=0.1667%。分数波特率发生器采用多位小数的分数逼近法,该算法的数学原理是:任何一个多位小数,无论是无理数还是有理数,均可以用一个分数来近似它,并可以用一定的程序使其误差越来越小,直至达到所需的精确度。比如,115200波特率采用分数波特率发生器的时候通过计算如下:

用分数发生器,则BRG=5,分子部分为58,分母部分为192+1=193,用前面的公式进行计算,实际波特率=12M/(16*1*5*(1+58/193))=115,338.6454,误差为:(115200-15,338)/115200=0.119%,计算出来的波特率精度高。

void FDRCalculate( uint32_t  uiMainClk,                                 /* 主时钟                       */

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!*

  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值