Freemodbus中波特率的配置-具体到STM32

这里再称赞一下Freemodbus的作者,这哥们儿确实是一个编程高手。

Freemodbus需要配合一个定时器使用,这是因为它是通过定时器超时来判断Modbus传输过程结束的,在Modbus协议中,以RTU模式为例,报文帧由时长至少为3.5个字符的空闲间隔区分,这个区间被称为t3.5,注意,这里是“至少”不是至多,也就是通信之间也不希望对方发的过快,所以在Freemodbus中对定时器就采用了类似于四舍五入的办法,比3.5个字符略微多一点的溢出时间。

一般的串口通信中,发送一个字符需要:1位起始位+8位数据位+1位校验位(可选)+1位停止位,总共11位,所以3.5个字符时间就是 3.5*11 = 38.5位

假设波特率是9600,波特率的单位是bps,也就是1秒传送的位数(千万别以为是字节数。。。)

那么传输1位的时间大约就是 1000/9600 = 0.10416667(ms)

这样,3.5个字符的时间就是 38.5位,也就是大约 4.01ms,这也就是定时器需要中断的时间,可以比这个时间略大一点点,所以Freemodus的作者做了一个 特别巧妙的公式变量:

usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate )

这里,usTimerT35_50us表示 3.5个字符,对应 50us的倍数,以波特率9600计算,刚刚理论计算为4ms左右,4000us/50us = 80

那么这个公式的计算结果是:usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate ) = 7*220000/(2*9600) = 80.2,这个值是无符号整型,所以就是80,看到这里就好奇,这个作者是怎么想到这么个通用公式的。

那么算出 80 以后怎么用呢,80代表的是80个 50us,这是作者为了移植方便,所以都用 50us作为基准,在具体使用的时候,刚说到要比t3.5稍微大点,大太多,反应慢,容易出错,作者给了一种方法:

usTimeoutMS = ( usTim1Timerout50us + 10 ) / 20;

其中 usTimeoutMS 就是要延时的ms数,还是以9600为例,那么定时器溢出时间为  (80+10)/20 = 4ms,然后移植者再根据自己的处理器,设置4ms的定时器溢出即可。

你可能感兴趣的:(嵌入式)