如何把Modbus的通信参数存在单片机的flash中--FreeModbus从站设计(11)
FreeModbus从站设计(11)-把Modbus的通信参数存在单片机的flash中
关键词:FreeModbus CubeMX HAL库 flash 通信参数
作为从站,Modbus-RTU通信的参数主要包括从站地址和串口参数,串口参数又包括波特率、校验位、停止位等,把这些参数存储在单片机的flash里,孔丙火(微信公众号:孔丙火)认为,可以简化电路设计,应用更加灵活。通用串口参数中数据位,在Modbus-RTU通信中是不需要设置的,因为Modbus协议规范规定,Modbus-RTU的数据位必须为8位。
1.通信参数在flash中的存储位置
STM32F103C8T6的flash存储区是没有区分程序区和用户数据区的,将通信参数存在flash中,最大的一个原则是不能影响程序代码存储区,否则会有意想不到的后果。具体存在flash中的哪个位置,要根据实际情况来,一般来说,程序代码都不会把flash占满,一般存在最后一页。以此系列文章的示例程序为例,通过keil的编译信息,可以看到程序占用的flash空间只有十几kB,如图1所示,而STM32F103C8T6的flash空间是64kB,共64页,因此擦除、写数据到最后一页不会影响程序代码。
图1
STM32F103C8T6属于中等容量的STM32F103,其flash组织结构如图2所示。中等容量的STM32F103有64kB和128kB两种,STM32F103C8T6是64kB的,因此,只有64页。Flash的操作必须要先擦除,再写入,并且是按页擦除的。最后一页的地址为:0x0800FC00。
图2
2.基于HAL库写flash的方法
图3
如图3所示,孔丙火(微信公众号:孔丙火)在modbus_app.c文件中写了一个写flash的函数。总体流程就是先擦除再写入,直接调用HAL库函数就可以了。
3.通信参数修改的基本流程
基本流程:从站收到修改通信参数的命令→将参数存储到中间数组→写flash→重新初始化串口和协议栈参数。
这里的示例程序,采用写多个保持寄存器(16功能码)传输修改通信参数命令,设定为:从地址15(协议地址格式)开始,写5个寄存器,首个寄存器写入的输入必须为0xFFAA,后面四个寄存器分别表示:从站地址、波特率、校验位、停止位,程序代码如图4所示。
图4
这段代码写在eMBRegHoldingCB()函数中,这个函数在之前的章节有阐述。收到的通信参数存储在了usUsrComFlashData[]中,这是一个全局变量。并且将ucUsrComconfig置1,用于在函数外部写flash的标识。
图5
如图5所示,调用vUsrWriteFlash()函数写flash,此段代码写在主循环while(1)中。
重新初始化串口和协议栈参数,有两种方法,一种是在修改通信参数后,让用户重启,程序在main()函数的初始化阶段完成串口和协议栈参数的初始化,还有一种是在收到修改通信参数的命令后,在线重新初始化串口和协议栈。孔丙火(微信公众号:孔丙火)认为,在工业控制领域,前一种方法更好,因为工控领域最重要的是安全,如果从站正在接收控制命令,这时对串口和协议栈重新初始化,是有危险的,而且修改通信参数的事件,并非高频率。
总结:介绍了STM32F103C8T6的flash的组织结构,进一步分析了通信参数在flash中的存储位置,阐述了基于HAL库写flash的方法和通信参数修改的基本流程。代码经过实践,可以实现将通信参数存在flash中,并可以通过Modbus命令修改通信参数。
文章在公众号(孔丙火)同步推出,欢迎查看更多系列文章。
单片机、ARM、现场总线、PLC、嵌入式软硬件的设计经验分享,秉承“点点滴滴皆智慧”的理念,以实际项目为单元阐述知识点,一起分享,共同交流。