本30路晶体管可编程模块的modbus上位机运行界面如图(附件中有vb.net源码下载)支持rs485与rs232通讯. 可做快递柜 电磁阀的控制
完整版modbus30路完善版本(看门狗)232+485单片机源程序如下:
- /******************************
- 程序功能: modbus RTU 模式设置读取十六个继电器状态,以及内部保持寄存器的设置读取
- 硬件测试环境:单片机stc89C52RC十六继电器485接口控制板
- 通信协议: 晶振:11.0592 波特率:9600 8位数据 1位停止位 偶校验 485通位接口P3.7控制方向端
- 控制板地址: 修改localAddr(变量)
- 线圈个数:16个 线圈地址范围:0x0000~0x000F
- 保持寄存器个数:16个(字节型) 寄存器地址:0x0000~0x000F
- \\******************************\\
- 功能码简介:
- 02:读取单个线圈状态
- 03:读取多个保持寄存器
- 05:设置单个线圈状态
- 06:设置单个寄存器值
- 0F:设置多个线圈
- 10:设置多个保持寄存器
- *******************************/
- #include "hader\\main.h"
- uint32 dwTickCount,dwIntTick; //时钟
- uint8 idata sendBuf[32],receBuf[16]; //发送接收缓冲区
- uint8 idata checkoutError; // ==2 偶校验错
- uint8 idata receTimeOut; //接收超时
- uint8 idata c10ms; //10ms 计时
- uint8 idata c200ms;
- bit b1ms,bt1ms,b10ms,bt10ms,b100ms,bt100ms; //定时标志位
- //定时处理
- void timeProc(void)
- {
- b1ms = 0;
- if(bt1ms) //如果1ms到
- {
- bt1ms = 0;
- b1ms = 1;
- if(receTimeOut>0) //如果接收超时值>0
- {
- receTimeOut--; //接收超时-1(1ms减1次)
- if(receTimeOut==0 && receCount>0) //判断通讯接收是否超时
- {
- // b485Send = 0; //将485置为接收状态
- receCount = 0; //将接收地址偏移寄存器清零
- checkoutError = 0;
- }
- }
- }
- } // void TimerProc(void)
- //初始化
- void initInt(void)
- {
- SCON = 0xd0;
- TMOD = 0x21;
- PCON = 0;
- TH0 = TIMER_HIGHT;
- TL0 = TIMER_LOW;
- TH1= 0xfd;
- TL1 = 0xfd; //波特率 9600
-
- TR0 = 1;
- TR1=1;
- ET0 = 1;
- ES = 1;
- EA = 1;
- //串口2设置
- S2CON = 0xd0; //方式1,9位数据,波特率不可变 S2TB8 偶校验位
- BRT=0XFD; //设置波特率9600
- AUXR=0x10; //启动串口1波特率发生器
- IP=0x00; //优先级默认 //开串口1中断
- IE2=0x01; //开串口2中断
- }
- //初始化
- void initProg(void)
- {
- P4SW|=0x20; //配置P4.5为IO口
- P4M0|=0x10; //配置P4.4为IO口
- P4M1|=0x10;
- P0=P1=P2=P3=0xff;
- P4|=0x30;
- initInt(); //初始化定时器
- // b485Send = 0;
- }
- //上电时读取上次线圈状态,并设置
- void forceMultipleCoils1()
- {
- uint8 tempAddr;
- uint8 i,k;
- uint8 Data;
- uint8 exit = 0;
- for(k=0;k<4;k++)
- {
- switch(k)
- {
- case 0:Data=coilreg1; break;
- case 1:Data=coilreg2; break;
- case 2:Data=coilreg3; break;
- case 3:Data=coilreg4; break;
- }
- for(i=0;i<8;i++)
- {
- if( Data &0x01==1)
- setCoilVal(tempAddr,0);
- else
- setCoilVal(tempAddr,1);
- Data=Data>>1;
- tempAddr++;
- if(tempAddr >=32)
- {
- exit = 1;
- break;
- }
- }
- if(exit==1)
- break;
- }
- }
- void main(void)
- {
-
- initProg();
- localAddr=EEPROMReadByte(0); //从EERPOM的相对0地址读取数据
- coilreg1=EEPROMReadByte(1);
- coilreg2=EEPROMReadByte(2);
- coilreg3=EEPROMReadByte(3);
- coilreg4=EEPROMReadByte(4);
- forceMultipleCoils1();
- if(localAddr>=10)
- {
- localAddr=1;
- EEPROMSectorErase(0); //从EEPROM的相对0地址扇区擦除
- EEPROMWriteByte(0,localAddr);
- EEPROMWriteByte(1,coilreg1);
- EEPROMWriteByte(2,coilreg2);
- EEPROMWriteByte(3,coilreg1);
- EEPROMWriteByte(4,coilreg2);
-
- }
- WDT_CONTR =0x32; //大概284.4ms
- while(1)
- {
- timeProc();
- checkComm0Modbus();
- }
- }
- //定时器0 1ms 中断
- void timer0IntProc() interrupt 1
- {
- TL0 = TIMER_LOW;
- TH0 = TIMER_HIGHT;
- dwIntTick++;
- bt1ms = 1;
- c10ms++;
- c200ms++;
- if(c10ms >= 10)
- {
- c10ms = 0; //20ms计时器清零
- bt10ms = 1;
- WDT_CONTR =0x32; //
- }
- } // void Timer0IntProc()
- // 串行中断1程序
- void commIntProc() interrupt 4
- {
- if(TI)
- {
- TI = 0;
- if(sendPosi < sendCount) //如果发送位置小于发送计数,那么继续发送
- {
- sendPosi++;
- ACC = sendBuf[sendPosi];
- TB8 = P; //加上校验位
- SBUF = sendBuf[sendPosi];
- }
- else //否则发送完毕,置接收状态
- {
- // b485Send = 0; //发送完后将485置于接收状态
- receCount = 0; //清接收地址偏移寄存器
- checkoutError = 0;
- }
- }
- else if(RI)
- {
- RI = 0;
- receTimeOut = 10; //通讯超时值
- receBuf[receCount] = SBUF;
- ACC = receBuf[receCount];
- if(P != RB8)
- checkoutError = 2; //偶校验出错
- receCount++; //接收地址偏移寄存器加1
- receCount &= 0x0f; //最多一次只能接收16个字节
- }
- } // void CommIntProc()
- //串口2中断
- void uart2_isr() interrupt 8
- {
-
- if( S2CON & 0x02 )
- {
- S2CON &= ~0x02;
- if(sendPosi<receCount) //如果发送位置小于发送计数,那么继续发送
- {
- sendPosi++;
- ACC = receBuf[sendPosi];
- if(P)
- S2CON|=0x08; // 7 6 5 4 3 2 1 0 Reset Value
- //sfr S2CON = 0x9A; //S2 Control S2SM0 S2SM1 S2SM2 S2REN S2TB8 S2RB8 S2TI S2RI 00000000B
- else
- S2CON&=0xf7;
- S2BUF =receBuf[sendPosi];
- }
- else //否则发送完毕,置接收状态
- {
- // b485Send = 0; //发送完后将485置于接收状态
- receCount = 0; //清接收地址偏移寄存器
- checkoutError = 0;
- }
- }
- else if( S2CON & 0x01)//接收
- {
- S2CON &= ~0x01;
- receTimeOut = 10; //通讯超时值
- receBuf[receCount] =S2BUF;
- ACC = receBuf[receCount];
- // if(P != RB8)
- // checkoutError = 2; //偶校验出错
- receCount++; //接收地址偏移寄存器加1
- receCount &= 0x0f; //最多一次只能接收16个字节
- }
- }
复制代码
简要说明: 一、 尺寸:长180mmX宽110mmX高22mm 二、 主要芯片:STC12C60S2支持双串口(支持51系列DIP40封装单片机) 三、 工作电压:直流6~24伏供电可控制负载6~24V 四、 串口1(COM1)下载程序,(RS485口使用单机机内部串口2均可与上位机通讯) 五、输入输出采用独立供电,也可以公用一个电源,独立供电可减少负载对单片机电路的影响 六、 特点: 1、具有电源指示。 2、三十路带光电隔离输出控制场效应管。
3、标准的11.0592M晶振。(便于设置串口波特率)
4、具有上电复位和手动复位。
5、支持51系列DIP40封装单片机。 5、输出三十路场效应管的供电采用独立供电 (可避免主控电路与被控电路干扰) 6、输出三十路具有LED指示。
7、三十路IRF1205场效应管。
8、可控制直流36V以内 50W负载设备。最大输出电流6A
9、具有RS232和RS485通信功能(可以同时和上位机通信)。 10、单片机无加密,可插拔更换,可随意更改程序。 使用说明: 【标注说明】
【接线图】
【应用举例接线图】
全部资料51hei下载地址(vb.net上位机与单片机下位机源程序与电路原理图等全套开发资料):
|