本帖最后由 lihuasoft 于 2019-11-2 00:54 编辑
继续为建设杰发MCU的生态,增砖添瓦。这次奉献本人移植到AC7811的全套FreeModbus源码,以及一个Modbus通信测试教程。
此贴是本人AC7811试用报告的第二部分(6-8)。第一部分(1-5),请点链接:https://bbs.21ic.com/icview-2873036-1-1.html
这第二部分,包括3块内容(ADC测试、移植MODBUS从机、MODBUS通信测试教程)。
虽然分3块,但其实代码整合在一起了。下面分述:
6、AC7811的ADC测试(多路规则通道)
ADC的测试代码,全部在main.c里面,主要就是ADC_init和ADC_DMA_init这两个函数,参照了官方工程师提供的代码。
启用了9个ADC通道,其中通道1-8对应PA8-PA15,通道17对应内部温度传感器。
软件触发这9个通道的AD值采样转换后,由DMA搬运存放在MODBUS的“输入寄存器”区。
具体请看工程代码。
7、移植FreeModbus从机
移植的这个FreeMODBUS从机,最初是本人前几年移植到一个STM32项目里。现在修改移植到AC7811。
主要有以下亮点:
1) 修复了freemodbus原代码中的几处BUG
2)在支持01、02、03、04、05、06、0F、10这8个常用功能码的基础上(网上代码几乎都是仅仅支持这8个而已),增加了对07、08、11、16、17等功能码的支持
3)支持MODBUS-RTU和MODBUS-ASCII两种模式
移植主要用到了TIMER1和UART2,需要修改的文件在freemodbus_port文件夹下。
具体请下载附件里的全套代码阅读。
8、MODBUS主从通信教程
考虑到可能有的朋友不太熟悉MODBUS,下面以图文形式介绍MODBUS主从通信测试:
1)下载附件,把里面的AC781x_FreeModbus文件夹下的工程编译下载到mini板。
工程使用了以下资源:
TIMER1、UART2:用于FreeModbus
PA0-PA7:GPIO,初始化为推挽输出
PA8-PA15:ADC引脚
PB0-PB15:GPIO,初始化为输入模式
2)在Windows系统安装附件里提供的Modbus Poll工具(附送注册表修改工具)。准备一个USB转串口,连接到UART2。
3)mini板上电后,绿色LED亮(对应PA0)
4)运行Modbus Poll软件。在通信测试中,这个软件的角色是主机,而mini板是从机(设备一般都是从机)。下面凡提到“从机”,就是指mini板上运行的freeModbus。
5)点击Modbus Poll菜单项Connection-->Connect,打开连接窗口。
选择正确的串口,设置波特率等通信参数如图(波特率可修改,需与从机一致)。
Mode选择RTU。点击Advanced按钮,把里面包括流控设置在内的所有已选项去掉。
点击图中的OK按钮,建立连接。
6)连接成功后,默认将显示如图表格。这10行,是从机的10个“保持寄存器”。
其中第0个保持寄存器,默认值为0,它的低8位对应mini板的PA0-PA7。
7)选中表格中全部10行(ctrl+A),右击,在右键菜单里选择Format-->HEX,改为十六进制显示数值,如图:
8)双击表中的保持寄存器0,即上图箭头所指的蓝色格,将弹出窗口,用于修改寄存器值。如图。其中,SlaveID是从机ID(我们的从机ID默认为1,具体请看main.c),Address即寄存器地址。我们在Value格里,输入5555。这是一个十六进制值,点击Send发送给从机,同时注意观察mini板的LED
9)修改成功,保持寄存器0的值已经是0x5555,这时,会看到mini板的绿色LED熄灭了。
这是因为,0号保持寄存器的低8位对应PA0-PA7,修改的结果使PA0为高电平,于是LED就熄灭了。
10)点击主菜单Setup-->Read/Write Defin项,在弹出的窗口中,
会看到默认Function项是“03 Read Holding Reg”(即读保持寄存器,正如前面几步操作,都是针对保持寄存器)。
把Function项改为“01”,默认的数量10改为16(即读出从Address0起的16个Coils),点击OK。
Coils是线圈的意思,一个Coil其实就是一个二进制位、开关量。
11)点击OK后,表格变成了下面的样子,每个地址对应的值非0即1。
注意,图中的F=01,就是前面所说的Function设置为01,指向Coils区(这些是MODBUS术语,看不懂的话,请参阅有关资料)
12)双击第0个Coil所在的格子(蓝色格),弹出的修改窗口中,Value改为Off,点击Send把修改提交到从机。
会发现:LED又亮了。(LED亮灭的逻辑,请参看PCB原理图)
13)再次点击主菜单Setup-->Read/Write Defin项,在弹出的窗口中,修改Function为“02”。
点击OK后,将读出Discrete区(离散输入区)的16个值。
14)下图就是从机上的16个离散量,它非1即0,来自PB0-PB15(这16个IO被初始化为输入模式)。
图中对应PB7的那个离散量值为0,是因为我在测试时,把PB7用导线接到了地。
15)再次点击主菜单Setup-->Read/Write Defin项,在弹出的窗口中,修改Function为“04”。数量改为10。
点击OK后,将Poll出“输入寄存器”区的10个“输入寄存器”的值。
16)因为我们的从机只设置了10个输入寄存器(取决于你的定义,可以更多的),数量如果超过10,ModbusPoll软件就会报错。图中,第0个输入寄存器,保存的是从机的ID;第1-8个输入寄存器,提供的是当前的ADC通道1-8(即PA8-PA15)的AD值;而第9个输入寄存器,提供的是内部温度传感器的AD值。
17)用杜邦线把PA8和PA9分别接到VDD和VSS,从机的ADC会采样转换新的AD值,并由DMA搬运放入输入寄存器。
会发现输入寄存器1和2的值变成了4095和0。
18)下面直接测试MODBUS指令码。点击modbus poll软件工具栏上的TC按钮,打开Test Center窗口。
输入“01 07”(中间有一个半角空格隔开),勾选Add check,CRC,然后点击Send发送到从机。
01是从机的ID,07是功能码。这句指令的意思是:向01从机索要异常状态信息。从机返回的信息中,包含8个异常二进位(图中的FF)。因为我们的从机并没有现实功能,就把这8个二进位,映射到了PB0-PB7。
用导线把mini板的PB7引脚接到GND,再发送01 07,从机返回的码就变成了BF,如图。
19)再测11功能码。发送01 11后,从机将返回一大串信息,
如图,后面的一串ASCII码其实是“AC781x-Modbus,......”,这串字符在程序中有定义。
20)测试03功能码。在“01 03 00 00 00 01”这串指令中,从左至右含义分别是:
01:从机ID
03:功能码
00 00:从第0000个寄存器开始读
00 01:共读出1个
合起来,意思就是:要求1号从机返回从第0个保持寄存器起,共1个寄存器的值。
提交后,结果如图。
21)下面再测试MODBUS-ASCII模式。
其实你可以不用重复烧写,而是改为用上电时某个IO的状态来决定FreeModbus从机初始化为RTU模式或ASCII模式。
但我为了分开,就用一个宏来区分,每次需要重新编译。
你可以把工程切换一下,如图:
22)重新编译,烧写到mini板。上电后,运行modbus-poll软件,Connect从机时注意选择ASCII模式:
23)来到Test Center,输入功能码指令测试。注意ASCII码模式变样了,用冒号先导,11码的指令是:
3A 30 31 31 31
把CRC换为LRC,点击Send提交,如图:
24)ASCII模式下测试03码:
25)如有看不懂的地方,请网络搜索MODBUS指令码资料,了解一下就懂了!(附件里提供了几个pdf文档)
如有通信失败,请检查:串口物理连接、从机ID是否正确、波特率等。可适当降低波特率(主机从机必须一致)。
本人虽偶尔来看贴,但不能及时一一回贴,请见谅!
打这么多字,实在是太累了。。。杰发官方的朋友,能不能给一套电机开发板玩玩呀。。。。。。
|