|
本帖最后由 fangyan123 于 2021-11-30 17:03 编辑
在这里Modbus主要指Modbus-RTU协议,下面的说明均以Modbus-RTU协议进行说明。如果对Modbus协议不了解,建议先下载最下方的“Modbus协议.pdf”文档熟悉该协议。
1-协议简介
Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。
2-硬件连接
Modbus协议实际应用一般基于RS485物理层,下图为RS485模块接线图:
27
在测试协议时,可以通过串口与电脑上位机软件通信进行测试,下面的测试程序都是直接通过电脑上位机进行测试。
3-图形块说明 在这里会挑一些重要或者特殊的进行说明。 1.读线圈
24
输入参数:1.超时时间:主机发送数据后,堵塞等待从机响应的最长时间。
2.buf:读回来的线圈值,为无符号8位整数的数组。
返回参数:从机响应超时返回0,不正确类型返回-1,成功返回1。
2.读输入寄存器
23
输入参数:1.buf:读回来的输入寄存器值,为无符号8位整数类型的数组,也就是会将输入寄存器的16位数据拆分 为2个8位的数据,高位在前低位在后。
3.写多个保持寄存器
22
输入参数:1.buf:读回来的输入寄存器值,为无符号8位整数类型的数组,也就是会将输入寄存器的16位数据拆分 为2个8位的数据,高位在前低位在后。
4.读保持寄存器
21
输入参数:1.buf:读回来的输入寄存器值,为无符号8位整数类型的数组,也就是会将输入寄存器的16位数据拆分 为2个8位的数据,高位在前低位在后。
5.读写多个保持寄存器
20
输入参数:1.buf:该语句会将buf中的数据写入从机,并将从机读取回来的数据又写回buf中,为无符号8位整数类 型的数组,也就是会将输入寄存器的16位数据拆分为2个8位的数据,高位在前低位在后。
6.定时回调函数
19
需要使用定时器每隔100us调用一次。
4-范例代码
1.读取线圈
图形块以及字符代码
18
- #define MBMASTER_USART1 1
- #include <CH32V103.h>
- #include "myLib/CH32V_ST7735S.h"
- #include "mylib/MB_Master.h"
- #include "CH32V_TIM.h"
- uint8_t buf[5];
- SPITFT spi_tft(128,128,PC5,PA2,PA4);
- MBMaster mbMaster(USART1,9600,USART_Parity_No);
- void TIM_attachInterrupt_2() {
- mbMaster.TimerCallback();
- }
- int main(void)
- {
- CH32_Init();
- spi_tft.init();
- spi_tft.set_direction(2);
- spi_tft.clear((0x67FF));
- mbMaster.Init();
- TIM_attachInterrupt(TIM2, 100, TIM_attachInterrupt_2);
- while(1){
- if(mbMaster.ReqReadCoils(1,1,9,buf,500)){
- spi_tft.clear((0x67FF));
- spi_tft.set_cursor(34,0);
- spi_tft.draw_hanzi_12("读线圈测试");
- spi_tft.set_cursor(0,15);
- spi_tft.println((String("buf[0]:") + String(buf[(int)(0)])));
- spi_tft.println((String("buf[1]:") + String(buf[(int)(1)])));
- delay(1000);
- }
- }
- return 1;
- }
复制代码 效果展示:
17
2.读离散量输入
图形块以及字符代码
16
- #define MBMASTER_USART1 1
- #include <CH32V103.h>
- #include "myLib/CH32V_ST7735S.h"
- #include "mylib/MB_Master.h"
- #include "CH32V_TIM.h"
- uint8_t buf[5];
- SPITFT spi_tft(128,128,PC5,PA2,PA4);
- MBMaster mbMaster(USART1,9600,USART_Parity_No);
- void TIM_attachInterrupt_2() {
- mbMaster.TimerCallback();
- }
- int main(void)
- {
- CH32_Init();
- spi_tft.init();
- spi_tft.set_direction(2);
- spi_tft.clear((0x67FF));
- mbMaster.Init();
- TIM_attachInterrupt(TIM2, 100, TIM_attachInterrupt_2);
- while(1){
- if(mbMaster.ReqReadDiscreteInputs(1,1,9,buf,500)){
- spi_tft.clear((0x67FF));
- spi_tft.set_cursor(34,0);
- spi_tft.draw_hanzi_12("读线圈测试");
- spi_tft.set_cursor(0,15);
- spi_tft.println((String("buf[0]:") + String(buf[(int)(0)])));
- spi_tft.println((String("buf[1]:") + String(buf[(int)(1)])));
- delay(1000);
- }
- }
- return 1;
- }
复制代码 效果展示:
15
3.读输入寄存器
图形块及字符代码
14
- #define MBMASTER_USART1 1
- #include <CH32V103.h>
- #include "myLib/CH32V_ST7735S.h"
- #include "mylib/MB_Master.h"
- #include "CH32V_TIM.h"
- uint8_t buf[5];
- SPITFT spi_tft(128,128,PC5,PA2,PA4);
- MBMaster mbMaster(USART1,9600,USART_Parity_No);
- void TIM_attachInterrupt_2() {
- mbMaster.TimerCallback();
- }
- int main(void)
- {
- CH32_Init();
- spi_tft.init();
- spi_tft.set_direction(2);
- spi_tft.clear((0x67FF));
- mbMaster.Init();
- TIM_attachInterrupt(TIM2, 100, TIM_attachInterrupt_2);
- while(1){
- if(mbMaster.ReqReadInputRegister(1,1,1,buf,500)){
- spi_tft.clear((0x67FF));
- spi_tft.set_cursor(34,0);
- spi_tft.draw_hanzi_12("读输入测试");
- spi_tft.set_cursor(0,15);
- spi_tft.println((String("buf[0]:") + String(buf[(int)(0)])));
- spi_tft.println((String("buf[1]:") + String(buf[(int)(1)])));
- delay(1000);
- }
- }
- return 1;
- }
复制代码 效果展示:
13
4.读保持寄存器
图形块及字符代码
12
- #define MBMASTER_USART1 1
- #include <CH32V103.h>
- #include "myLib/CH32V_ST7735S.h"
- #include "mylib/MB_Master.h"
- #include "CH32V_TIM.h"
- uint8_t buf[5];
- SPITFT spi_tft(128,128,PC5,PA2,PA4);
- MBMaster mbMaster(USART1,9600,USART_Parity_No);
- void TIM_attachInterrupt_2() {
- mbMaster.TimerCallback();
- }
- int main(void)
- {
- CH32_Init();
- spi_tft.init();
- spi_tft.set_direction(2);
- spi_tft.clear((0x67FF));
- mbMaster.Init();
- TIM_attachInterrupt(TIM2, 100, TIM_attachInterrupt_2);
- while(1){
- if(mbMaster.ReqReadHoldingRegister(1,1,1,buf,500)){
- spi_tft.clear((0x67FF));
- spi_tft.set_cursor(16,0);
- spi_tft.draw_hanzi_12("读保持寄存器测试");
- spi_tft.set_cursor(0,15);
- spi_tft.println((String("buf[0]:") + String(buf[(int)(0)])));
- spi_tft.println((String("buf[1]:") + String(buf[(int)(1)])));
- delay(1000);
- }
- }
- return 1;
- }
复制代码 效果展示:
11
5.写单个线圈
图形块及字符代码
10
- #define MBMASTER_USART1 1
- #include <CH32V103.h>
- #include "myLib/CH32V_ST7735S.h"
- #include "mylib/MB_Master.h"
- #include "CH32V_TIM.h"
- uint8_t buf[5];
- SPITFT spi_tft(128,128,PC5,PA2,PA4);
- MBMaster mbMaster(USART1,9600,USART_Parity_No);
- void TIM_attachInterrupt_2() {
- mbMaster.TimerCallback();
- }
- int main(void)
- {
- CH32_Init();
- spi_tft.init();
- spi_tft.set_direction(2);
- spi_tft.clear((0x67FF));
- mbMaster.Init();
- TIM_attachInterrupt(TIM2, 100, TIM_attachInterrupt_2);
- while(1){
- spi_tft.clear((0x67FF));
- spi_tft.set_cursor(0,10);
- if(mbMaster.ReqWriteCoil(1,1,0,500)){
- spi_tft.draw_hanzi_12("写线圈成功");
- }
- else{
- spi_tft.draw_hanzi_12("写线圈失败");
- }
- delay(1000);
- spi_tft.clear((0x67FF));
- spi_tft.set_cursor(0,22);
- if(mbMaster.ReqWriteCoil(1,1,1,500)){
- spi_tft.draw_hanzi_12("写线圈成功");
- }
- else{
- spi_tft.draw_hanzi_12("写线圈失败");
- }
- delay(1000);
- }
- return 1;
- }
复制代码 效果展示:
无
6.写多个线圈
图形块及字符代码
9
- #define MBMASTER_USART1 1
- #include <CH32V103.h>
- #include "myLib/CH32V_ST7735S.h"
- #include "mylib/MB_Master.h"
- #include "CH32V_TIM.h"
- uint8_t buf[5];
- SPITFT spi_tft(128,128,PC5,PA2,PA4);
- MBMaster mbMaster(USART1,9600,USART_Parity_No);
- void TIM_attachInterrupt_2() {
- mbMaster.TimerCallback();
- }
- int main(void)
- {
- CH32_Init();
- spi_tft.init();
- spi_tft.set_direction(2);
- spi_tft.clear((0x67FF));
- mbMaster.Init();
- TIM_attachInterrupt(TIM2, 100, TIM_attachInterrupt_2);
- while(1){
- spi_tft.clear((0x67FF));
- spi_tft.set_cursor(0,10);
- buf[(int)(0)] = 0xff;
- if(mbMaster.ReqWriteCoil_S(1,1,6,buf,500)){
- spi_tft.draw_hanzi_12("写线圈成功");
- }
- else{
- spi_tft.draw_hanzi_12("写线圈失败");
- }
- delay(1000);
- spi_tft.clear((0x67FF));
- spi_tft.set_cursor(0,22);
- buf[(int)(0)] = 0;
- if(mbMaster.ReqWriteCoil_S(1,1,6,buf,500)){
- spi_tft.draw_hanzi_12("写线圈成功");
- }
- else{
- spi_tft.draw_hanzi_12("写线圈失败");
- }
- delay(1000);
- }
- return 1;
- }
复制代码 效果展示:
8
7.写单个保持寄存器
图形块及字符代码
3
- #define MBMASTER_USART1 1
- #include <CH32V103.h>
- #include "myLib/CH32V_ST7735S.h"
- #include "mylib/MB_Master.h"
- #include "CH32V_TIM.h"
- uint8_t buf[5];
- SPITFT spi_tft(128,128,PC5,PA2,PA4);
- MBMaster mbMaster(USART1,9600,USART_Parity_No);
- void TIM_attachInterrupt_2() {
- mbMaster.TimerCallback();
- }
- int main(void)
- {
- CH32_Init();
- spi_tft.init();
- spi_tft.set_direction(2);
- spi_tft.clear((0x67FF));
- mbMaster.Init();
- TIM_attachInterrupt(TIM2, 100, TIM_attachInterrupt_2);
- while(1){
- spi_tft.clear((0x67FF));
- spi_tft.set_cursor(0,10);
- if(mbMaster.ReqWriteHoldingRegister(1,1,0x1234,500)){
- spi_tft.draw_hanzi_12("写寄存器成功");
- }
- else{
- spi_tft.draw_hanzi_12("写寄存器失败");
- }
- delay(1000);
- }
- return 1;
- }
复制代码 效果展示:
6
8.写多个保持寄存器
图形块及字符代码
4
- #define MBMASTER_USART1 1
- #include <CH32V103.h>
- #include "myLib/CH32V_ST7735S.h"
- #include "mylib/MB_Master.h"
- #include "CH32V_TIM.h"
- uint8_t buf[5];
- SPITFT spi_tft(128,128,PC5,PA2,PA4);
- MBMaster mbMaster(USART1,9600,USART_Parity_No);
- void TIM_attachInterrupt_2() {
- mbMaster.TimerCallback();
- }
- int main(void)
- {
- CH32_Init();
- spi_tft.init();
- spi_tft.set_direction(2);
- spi_tft.clear((0x67FF));
- mbMaster.Init();
- TIM_attachInterrupt(TIM2, 100, TIM_attachInterrupt_2);
- while(1){
- buf[(int)(0)] = 0x12;
- buf[(int)(1)] = 0x34;
- buf[(int)(2)] = 0x56;
- buf[(int)(3)] = 0x78;
- spi_tft.clear((0x67FF));
- spi_tft.set_cursor(0,10);
- if(mbMaster.ReqWriteHoldingRegister_S(1,1,2,buf,500)){
- spi_tft.draw_hanzi_12("写寄存器成功");
- }
- else{
- spi_tft.draw_hanzi_12("写寄存器失败");
- }
- delay(1000);
- }
- return 1;
- }
复制代码 效果展示:
5
7.读写多个保持寄存器
图形块及字符代码
2
- #define MBMASTER_USART1 1
- #include <CH32V103.h>
- #include "myLib/CH32V_ST7735S.h"
- #include "mylib/MB_Master.h"
- #include "CH32V_TIM.h"
- uint8_t buf[5];
- SPITFT spi_tft(128,128,PC5,PA2,PA4);
- MBMaster mbMaster(USART1,9600,USART_Parity_No);
- void TIM_attachInterrupt_2() {
- mbMaster.TimerCallback();
- }
- int main(void)
- {
- CH32_Init();
- spi_tft.init();
- spi_tft.set_direction(2);
- spi_tft.clear((0x67FF));
- mbMaster.Init();
- TIM_attachInterrupt(TIM2, 100, TIM_attachInterrupt_2);
- while(1){
- buf[(int)(0)] = 0x12;
- buf[(int)(1)] = 0x34;
- buf[(int)(2)] = 0x56;
- buf[(int)(3)] = 0x78;
- spi_tft.clear((0x67FF));
- spi_tft.set_cursor(0,10);
- if(mbMaster.ReqReadWriteHoldingRegister_S(1,3,2,1,2,buf,500)){
- spi_tft.draw_hanzi_12("写寄存器成功");
- spi_tft.set_cursor(0,27);
- spi_tft.println((String("buf[0]:") + String(buf[(int)(0)])));
- spi_tft.println((String("buf[1]:") + String(buf[(int)(1)])));
- }
- else{
- spi_tft.draw_hanzi_12("写寄存器失败");
- }
- delay(1000);
- }
- return 1;
- }
复制代码 效果展示:
1
附件:
Modbus协议.pdf
(1.04 MB, 下载次数: 76)
|
|