STM32F103、FreeModbus从站设计(7)-如何让RTU的定时器正常工作起来
关键词:Modbus FreeModbus STM32F103C8T6 CubeMX 移植
1.基本原理
在CubeMX工程配置中,已经将定时器2(TIM2)的时钟周期(可以理解为心跳一下)设为50us,Counter Period(产生中断)暂时设为了35,也就是说50us×35=1750us产生一次中断,这个时间就是判断RTU中帧间隔的标准。但在Freemodbus协议栈(遵循Modbus国标)中,这个时间不是固定的,在波特率小于19200bps时,需要具体计算这个时间,当波特率大于或等于19200bps时,这个时间固定为1750us,如图1所示。因此,孔丙火(微信公众号:孔丙火)认为,把它设为固定值是不方便的,当波特率修改的时候,还要单独修改此参数,可以用一个变量来设置此参数,变量的值随波特率而改变,这也有利于后期通信参数修改的程序。
图1
2.代码修改
在mbrtu.c中,有一个eMBRTUInit()函数,在协议栈初始化的时候被调用,在图2中可以看出,t3.5的计算方法。计算完了以后,调用xMBPortTimersInit()这个函数,这个函数在porttimer.c中,如果参数是写死的,CubeMX本身已经生成了定时器的初始化函数,这个函数是不用写的,直接返回True就行了。孔丙火(微信公众号:孔丙火)这里需要根据这个计算结果修改通信参数,因此要用一下这个函数。
图2
在modbus_app.c中定义一个全局变量uint16_t usUsrTimeOutCount;//modbus定时器计数周期(50us的个数),在xMBPortTimersInit()中,将usTimerT35_50us的值赋给usUsrTimeOutCount,然后在函数MX_TIM2_Init()中用这个值对TIM2进行初始化。xMBPortTimersInit()的代码如图3所示。MX_TIM2_Init()修改后的代码如图4所示。孔丙火(微信公众号:孔丙火)提醒,这样修改之后,在main.c中MX_TIM2_Init()这个函数的调用必须在eMBInit( MB_RTU, ucUsrSlaveAddress, 1, ulUsrBaudRate, eUsrParity );之后。在main.c中的初始化阶段的调用关系如图5所示。
图3
图4
图5
文章在公众号(孔丙火)同步推出,欢迎查看更多系列文章。
单片机、ARM、现场总线、PLC、嵌入式软硬件的设计经验分享,秉承“点点滴滴皆智慧”的理念,以实际项目为单元阐述知识点,一起分享,共同交流。
文章评论(0条评论)
登录后参与讨论