STM32L476+STM32cubeMx+Freemodbus移植成功记录
modbus通信需要一个串口和定时器,在STM32L476上串口使用USART3,定时器使用TIM4,同时由于使用了485通信,需要一个GPIO引脚PB1控制485芯片的数据收发,移植Freemodbus过程记录如下:
一、CubeMX的配置
基于STM32L476RCTx的Modbus移植(新建工程,选择对应的芯片型号),使用Serial wire(ST_Link)串行调试方式,选用时钟为HSE外接石英晶振。
配置时钟树,外部晶振为8MHz,时钟频率最高只能到80MHz,这里设置为64MHz。
串口配置
串口采用异步通信的方式(Asynchronous异步通信),这里随便配置即可,因为modbus移植过程中还会对串口重新进行初始化。
STM32L476有485硬件流控制功能,查阅资料说如果使用硬件流控来控制485芯片的DE引脚,可以省去手动操作RS485收发器的使能引脚步骤,但是在实际使用中发现串口不能正常收发数据,所以还是通过IO口来控制485芯片。
GPIO设置为推挽输出模式,作为RS485的发送接收控制端,输出速度选择High。
串口3的配置如下:
STM32L476与STM32F103系列相比多了一些advanced Features,STM32串口默认是打开Overrun、DMA on Rx Error,如果使能后出现错误会关闭串口接收,调用错误回调函数,这里直接关闭使能,不影响正常通信。
定时器配置
Modbus协议的RTU模式规定报文帧的时长至少为3.5个字符的空闲间隔区分,如果在指定的时间内没有接收到新的字符数据,则认为收到了新的帧。
在freemodbus中默认定义:当波特率大于19200时,判断一帧数据超时时间固定为1750us,当波特率小于19200时,超时时间为3.5个字符时间。Freemodbus协议中使用了一个公式来实现不同波特率下超时时间的设置
usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate )
为了后续项目移植方便,需要用定时器产生50us的基准。
STM32L476中采用TIM4,TIM4挂载在APB1上,pclk1为64MHz,预分频系数3199,计数周期为49,对应时间为50us,随便配置就行,因为在modbus移植过程中还会对定时器初始化。
自动重载ENABLE,设置定时器触发方式为Update Event
定时器的溢出时间的计算公式为:
Tout = ((arr+1)*(psc+1))/Tclk 这里arr=49,psc=3199,Tclk=64MHz,
于是Tout = (3200*(arr+1))/64us = (arr+1)*50us,后面可以通过改变arr的值改变定时时间。
NVIC
使能定时器4和串口3的中断,还需要配置中断优先级,定时器的中断优先级低于串口中断即可。(优先级数字越小,优先级越高)
取消自动生成中断服务程序,在移植过程中要自己编写串口和定时器服务程序。
Code Generator
只拷贝相关文件库到工程下 每个外设生成独立的”.c/h”文件,Project Manager 项目生成工程路径中最好不要用中文,不然STM32CubeMX会在生成项目时报错,IDE选择MDK-ARM