本帖最后由 陈陈陈 于 2016-8-11 11:09 编辑
arduino 使用modbus做工控
@迷你强
强总之前写过一个modbus slave的帖子,这是我这个帖子的灵感来源
使用的单片机为ATMEGA8 用isp 烧入了optiboot的bootloader之后用于工控场合
关键的芯片图纸如下
如何给ATMEGA8烧入bootloader参见帖子:http://www.geek-workshop.com/thread-25004-1-1.html
如何使用arduino 当成isp 参见帖子:http://www.arduino.cn/thread-1245-1-1.html
Max13487的选用可以让单片机无需调高或者调低485发送使能线,即可直接往485总线发送和接受数据,自动转换的,很高级的。推荐!
MAX706芯片是用来给单片机做复位用的,单片机一旦跑飞,就处于发呆的状态,不会再发出任何信号,这个机制的好处就是单片机发呆超过1.6秒(换句话说呢就是delay也要少用),MAX706就直接强制让单片机重启!很好用的,推荐!
好了前提条件就说完了,我们开始使用这个系统吧。
需要用到的库为: #include <SimpleModbusSlave.h> #include <MsTimer2.h> 代码如下 - #include<SimpleModbusSlave.h>
- #include <MsTimer2.h>
- enum
- {
- //这里不好理解的话,你就把modbus的寄存器地址当成是一堆连续的地址,这里就是从零开始的地址位置
- //The first register starts at address 0
- IN0,
- IN1,
- IN2,
- IN3,
- OUT0,
- OUT1,
- OUT2,
- OUT3,
- LED_STATE,
- ADDRESS,
- TOTAL_ERRORS,
- //leave this one
- TOTAL_REGS_SIZE
- //total number of registers for function 3 and 16 share the same register array
- };
-
- unsigned int holdingRegs[TOTAL_REGS_SIZE];// function 3 and 16 register array
- ////////////////////////////////////////////////////////////
-
- void setup()
- {
- /*parameters(long baudrate,
- unsigned char ID,
- unsigned char transmit enablepin,
- unsigned int holding registerssize)
-
- The transmit enable pin is used in half duplex communication to activatea MAX485 or similar
- to deactivate this mode use any value < 2 because 0 & 1 is reservedfor Rx & Tx
- */
-
- modbus_configure(9600,1,2,TOTAL_REGS_SIZE,0);
- pinMode(A0, OUTPUT);
- pinMode(A1, OUTPUT);
- pinMode(A2, OUTPUT);
- pinMode(A3, OUTPUT);
- pinMode(8, INPUT);
- pinMode(9, INPUT);
- pinMode(10, INPUT);
- pinMode(2, INPUT);
- holdingRegs[OUT0]=1;
- holdingRegs[OUT1]=1;
- holdingRegs[OUT2]=1;
- holdingRegs[OUT3]=1;
- pinMode(7, OUTPUT);//看门狗引脚,定时清除用
- MsTimer2::set(1000, flash); // 500ms period
- MsTimer2::start();
- }
-
- void loop()
- {
- holdingRegs[TOTAL_ERRORS] = modbus_update(holdingRegs);//报错收集
- holdingRegs[IN0] = digitalRead(8);
- holdingRegs[IN1] = digitalRead(9);
- holdingRegs[IN2] = digitalRead(10);
- holdingRegs[IN3] = digitalRead(2);// 数据写入holding寄存器
- digitalWrite(A0, holdingRegs[OUT0]);
- digitalWrite(A1, holdingRegs[OUT1]);
- digitalWrite(A2, holdingRegs[OUT2]);
- digitalWrite(A3, holdingRegs[OUT3]); //读到的数据往继电器输出
- }
- void flash()//清除看门狗功能
- {
- static boolean output = HIGH;
- digitalWrite(7, output);
- output = !output;
- }
复制代码 |