使用的库主要有两个
Modbus Arduino
链接: https://caiyun.139.com/m/i?135Ce0r2XISCO 提取码:Gm7U
Modbus Serial
链接: https://caiyun.139.com/m/i?135CmOG7oNCL9 提取码:iAHE
硬件
arduino mega 2560,TTL转485,485转usb
上位机
arduino IDE
MThings:485测试工具
实例
主站发送数据到指定寄存器,让13脚的LED亮灭。
#include <ModbusSerial.h>
const int LedPin = 13;
const int TxenPin = -1; // -1 表示不需要DE/RE使能引脚
const byte SlaveId = 1;//设置从站号
/*
这个库没找到批量设置寄存器的函数,所以定义一个数据,在setup()for循环一次
*/
int modbus_hreg[5] = {0};// Modbus Registers Offsets (0-9999)
#define MySerial Serial1 // define serial port used, Serial most of the time, or Serial1, Serial2 ... if available
const unsigned long Baudrate = 115200; //波特率,看它的函数里面,好像不能低于19200
// ModbusSerial object
ModbusSerial mb (MySerial, SlaveId, TxenPin);//同时配置了端口和从站号
/*
这个是延时用的,不用delay
https://docs.arduino.cc/built-in-examples/digital/BlinkWithoutDelay
因为后面要用到串口中断,而串口中断是等loop循环执行完成以后,才执行
*/
unsigned long PreviousMillis = 0;
void setup() {
int i;
Serial.begin(9600);
MySerial.begin (Baudrate,MB_PARITY_NONE); // 波特率115200、8N1
// prefer the line below instead if possible
// MySerial.begin (Baudrate, MB_PARITY_EVEN);
while (! MySerial)
;
mb.config (Baudrate);
// Set LedPin mode
pinMode (LedPin, OUTPUT);
//addHreg表示配置可读可写寄存器(地址,默认值)
for(i=0;i<5;i++){
modbus_hreg[i]=i;
mb.addHreg(modbus_hreg[i],0);
}
}
void loop() {
unsigned long CurrentMillis = millis();
//这个用法可以不用像delay()那样会在loop()里停下来
if(CurrentMillis-PreviousMillis >= 1000){
PreviousMillis = CurrentMillis;
//Hreg(地址),取出指定地址的值
Serial.println(mb.Hreg(modbus_hreg[0]));
}
}
//串口中断函数
void serialEvent1() {
// 执行数据处理
mb.task();
//本地对寄存器赋值,mb.Hreg(modbus地址,变量);
digitalWrite (LedPin, bool(mb.Hreg(modbus_hreg[0])));
}
学习过程中,参考了这几篇文档,在此感谢各位大佬。
Arduino基础篇(五)-- 如何快速上手串口通信(Serial)_arduino serial_长路漫漫2021的博客-CSDN博客
Blink Without Delay | Arduino Documentation | Arduino Documentation