单片机与昆仑通态通讯
基于Modbus的飞思卡尔单片机与MCGS触摸屏通信的实现

基于Modbus的飞思卡尔单片机与MCGS触摸屏通信的实现刘先越; 朱娜; 郭隆军【期刊名称】《《机电设备》》【年(卷),期】2019(036)004【总页数】7页(P28-34)【关键词】船舶电力系统; ModbusRTU; 飞思卡尔单片机; MCGS触摸屏【作者】刘先越; 朱娜; 郭隆军【作者单位】中国人民武装警察部队海警学院浙江宁波 315801; 中国舰船设计研究中心湖北武汉 430064; 中国船舶重工集团第七一一研究所上海 201108【正文语种】中文【中图分类】TN910 引言传统的PLC与触摸屏进行通信实现人机交互的方式虽然有着功能可靠、触点多等优点,但随着船舶电力系统集成度变高,PLC的数据处理和管理能力已无法满足现代船舶要求。
因此,随着单片机嵌入式系统在船舶领域应用越来越广泛,在Modbus协议下的单片机与触摸屏人机交互控制方式得以实现。
根据船舶环境恶劣、工况复杂等特点,本文采用成本低、可靠性高、抗干扰性强的飞思卡尔单片机与昆仑通态 MCGS进行通信试验,详细阐述了 MCGS触摸屏所支持的ModbusRTU协议指令系统的组成及其应答格式,软件设计和试验测试。
1 Modbus RTU协议1.1 Modbus RTU报文格式Modbus通信协议是工业中最开放、通用的协议之一,该协议采用主从应答通信,详细规定了主从应答通信行为,定义了设备能够识别和使用的报文结构。
Modbus 报文帧分为ASCII帧和RTU帧,两种帧格式只在起始位、结束符和校验码上有所区别,其中,RTU帧被MCGS中的“莫迪康Modbus RTU”设备驱动所支持。
这里只介绍RTU帧,ASCII帧可以参考该介绍。
RTU报文帧格式见表1。
使用RTU帧的报文发送需延时≥3.5个字符;设备地址及功能码为1字节;数据区由n个字节组成,每个字节8位;校验区为16位,分两个字节承载低八位和高八位。
表1 RTU报文帧格式帧格式所占字符数起始位≥3.5字符设备地址 8位功能代码8位数据 n个8位CRC校验 16位结束符≥3.5字符网络设备不断侦测网络总线,包括停顿间隔;每个设备都进行解码,以判断数据是否是发给自己的;在最后一个字符结束之后,当接收数据延时≥3.5个字符后,一个新的报文可在此之后开始[1]。
EC20系列PLC与昆仑通态通讯手册

EC20系列PLC与昆仑通态通讯手册感谢您购买艾默生网络能源有限公司的可编程控制器(PLC),在使用我公司EC20系列PLC产品之前,请仔细阅读EC20的相关资料。
本手册主要介绍EC20系列PLC与昆仑通态人机界面(HMI)的通讯设置以及如何通过昆仑通态人机界面访问PLC内部软元件资源(X、Y、M、SM、S、T、C、D、SD、Z)。
昆仑通态人机界面通过EC20PLC协议可与我公司EC20系列PLC进行通讯,硬件通讯接口为RS232或RS485。
下面介绍昆仑通态人机界面与PLC的通讯设置和软元件访问。
目录一、EC20系列PLC通讯设置(ControlStar) (1)二、昆仑通态—MCGS5.5(05.0000) (3)1、通讯设置 (3)2、软元件访问 (6)3、硬件接线 (13)附件 (15)一、EC20系列PLC通讯设置(ControlStar)双击ControlStar中“工程管理器”的“系统块”,弹出系统块。
选择“通讯口”选项卡,将通讯口(0)或(1)(和硬件通讯接口一致)参数设置中选MODBUS协议。
通讯口(1)既可RS232通讯又可RS485通讯,但只能选择其中一种通讯方式。
点击“Modbus设置”按钮,将弹出“Modbus协议参数”对话框;设置PLC的通讯串口,包括波特率、奇偶校验、数据位、停止位和站号,确认是否与人机界面软件的设置一致。
注:PLC设置为“从站”,“传送模式”设置为“RTU模式”,并保证站号的唯一性,无重复站号。
二、昆仑通态—MCGS5.5(05.0000)1、通讯设置点击“工作台”的“设备窗口”选项卡,若列表框中无“设备窗口”,请先点击“新建窗口”按钮新建“设备窗口”。
双击列表中的“设备窗口”或选中“设备窗口”后点击“设备组态”按钮,将弹出“设备组态:设备窗口”和“设备工具箱”对话框;若未出现“设备工具箱”对话框,请点击菜单“查看”的“设备工具箱”子选项。
点击“设备管理”按钮,将弹出“设备管理”对话框;分别将“可选设备”列表中的“EC20PLC(也可能在“用户定制设备”中)”和“通用串口父设备”增加到“选定设备”列表框中,点击“确定”后,在“设备工具箱”中将出现这两个设备。
安川MP2300控制器与昆仑通态触摸屏的通讯设计

安川MP2300控制器与昆仑通态触摸屏的通讯设计发表时间:2019-07-22T15:41:56.210Z 来源:《科技新时代》2019年5期作者:康茂[导读] 本文设计了基于Modbus TCP协议的通讯方案,使MP2300控制器与触摸屏实现数据交换,通讯性能稳定,满足实际使用要求。
佛山市多谱光电科技有限公司 528200 摘要本文介绍安川MP2300控制器与昆仑通态触摸屏的通讯实现方法,详细介绍基于Modbus TCP协议的通讯系统构成、MP2300参数设置和昆仑通态触摸屏的通讯设置,采用MSG-RCV函数实现MP2300与昆仑通态触摸屏数据交互。
关键字 MP2300控制器;触摸屏;Modbus TCP;MSG-RCV;1 引言在工业控制领域中,大多数设备都是采用PLC控制和人机界面作为系统控制方式。
PLC作为逻辑控制、运动控制及过程控制等的控制核心,而参数设置、状态监控、报警提示等信息由人机界面实现。
人机界面有多种形式实现,本文使用触摸屏与PLC控制器实现通讯,进行数据交互。
Modbus TCP具有公开协议、应用范围广、灵活性、性能稳定等特点,因此本文以昆仑通态触摸屏和安川MP2300控制器实例介绍怎样通过Modbus TCP协议构建通讯系统。
2 通讯系统设计安川MP2300是一款采用选配件插槽的运动控制一体机,要实现Modbus TCP通讯功能,需要选配一个具有支持TCP/IP协议的通讯模块218IF-01。
218IF-01模块可支持:Memobus、扩展Memobus、Melsec、Modbus TCP和无协议等。
触摸屏选用昆仑通态的TPC1062K型号,该触摸屏具有10.2英寸的TFT液晶显示,以太网接口,支持Modbus TCP协议。
在此系统中,MP2300作为服务器端,触摸屏做客户端。
3 Modbus TCP通讯实现要实现MP2300与触摸屏Modbus TCP通讯,需要进行相应的218IF-01通讯设置、触摸屏通讯设置和MP2300调用MSG-RCV通讯函数。
ATMEGA16单片机与MCGS通信(MODBUS-RTU协议)

#include <avr/io.h>#include <avr/interrupt.h>#include <util/delay.h>#include "ds18b20.h"#define uchar unsigned char#define uint unsigned intvolatile uchar reve_data,renum=0,mend=0,nend=0,a1=1,a2=1,a3=1,a4=1,a5=1,a6=1,a7=1,a8=1,a9=1; void INT_Init();#define BAUD 38400 //波特率38.4kbp/svolatile uchar rx[7]={0x01,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00};uchar tx[30];volatile uchar crcl=0x00,crch=0x00;uchar led=0xff;//发送字符void send_char( uchar data ){/* 等待发送缓冲器为空 */while ( !( UCSRA & (1<<UDRE)) );/* 将数据放入缓冲器,发送数据 */UDR = data;}void inti_port(){DDRB=0xff;PORTB=0xff;DDRC=0xff;PORTC=0x00;}//CRC效验,将结果存储到CRCok变量中。
checkcrc(uchar *q,uchar nend){uint wcrc=0xffff;int j=0,i=0;for(i=0;i<nend;i++){wcrc ^= *q++;for(j=0;j<8;j++){if(wcrc&1){wcrc>>=1;wcrc ^= 0xa001;}else{wcrc>>=1;}}}crcl = wcrc;crch = wcrc>>8;}int main(void){inti_uart();inti_port();INT_Init();sei();while(1){gettemp();_delay_ms(1050);}}SIGNAL(SIG_UART_RECV){rx[renum++]=UDR;if(renum==8){renum=0;switch(rx[1]){case 0x01:if(!rx[3]){tx[0]=rx[0];//leD灯tx[1]=rx[1];tx[2]=0x01;DDRB=0X00;tx[3]=PORTB;DDRB=0XFF;checkcrc(tx,4);tx[4]=crcl;tx[5]=crch;send_string(tx,6);break;}else{tx[0]=rx[0];//继电器和蜂鸣器tx[1]=rx[1];tx[2]=0x01;DDRC=0X00;tx[3]=PORTC;tx[3]>>=7;DDRC=0XFF;checkcrc(tx,4);tx[4]=crcl;tx[5]=crch;send_string(tx,6);break;}case 0x04:tx[0]=rx[0];tx[1]=rx[1];tx[2]=rx[5]<<1;tx[3]=0x00;tx[4]=teml;tx[5]=0x00;tx[6]=temh;checkcrc(tx,nend=tx[2]+3);tx[tx[2]+3]=crcl;tx[tx[2]+4]=crch;send_string(tx,mend=tx[2]+5);break;case 0x05:DDRB=0XFF;switch(rx[3]){case 0x00:if(!rx[4])PORTB &= ~(1<<PB0);elsePORTB |= (1<<PB0);break;case 0x01:if(!rx[4])PORTB &= ~(1<<PB1);elsePORTB |= (1<<PB1);break;case 0x02:if(!rx[4])PORTB &= ~(1<<PB2);elsePORTB |= (1<<PB2);break;case 0x03:if(!rx[4])PORTB &= ~(1<<PB3);elsePORTB |= (1<<PB3);break;case 0x04:if(!rx[4])PORTB &= ~(1<<PB4);elsePORTB |= (1<<PB4);break;case 0x05:if(!rx[4])PORTB &= ~(1<<PB5);elsePORTB |= (1<<PB5);break;case 0x06:if(!rx[4])PORTB &= ~(1<<PB6);elsePORTB |= (1<<PB6);break;case 0x07:if(!rx[4])PORTB &= ~(1<<PB7);elsePORTB |= (1<<PB7);break;case 0x08:if(rx[4])PORTC |= (1<<PC7);elsePORTC &= ~(1<<PC7);break;}send_string(rx,8);break;default : break;}}}//*****************************红外线接收**********************************************////外部中断初始化void INT_Init(void){MCUCR |= _BV(ISC01); //选择外部中断0,下降沿触发中断MCUCR &= ~_BV(ISC00); //10:INT0的下降沿产生异步中断请求GICR |= (1 << INT0); //使能外部中断请求0DDRD &= ~_BV(PD2); //设置为输入,PORTD |= _BV(PD2); //使能上拉电阻}SIGNAL(SIG_INTERRUPT0){cli();uchar i,j,k = 0,addr[4] = {0};renum=0;GICR &= ~(1 << INT0); //禁止外部中断INT0 关闭外部中断,开始接受数据 for(i = 0;i < 14;i++){_delay_us(400);if(PIND & (1 << PD2)) //9MS内有高电平,则判断为干扰,退出处理程序 {GICR |= (1 << INT0); //使能外部中断INT0return;}}while(!(PIND & (1 << PD2))); //等待9ms低电平过去for(i = 0;i < 4;i++) //{for(j = 0;j < 8;j++)//{while(PIND & (1 << PD2)); //等待4.5ms高电平过去while(!(PIND & (1 << PD2))); //等待变高电平while(PIND & (1 << PD2))//计算高电平时间{_delay_us(100);k++;if(k >= 30) //高电平时间过长,则退出处理程序{GICR |= (1 << INT0); //使能外部中断INT0return; //}}addr[i] = addr[i] >> 1; //接受一位数据if(k >= 8){addr[i] = addr[i] | 0x80; //高电平时间大于0.56,则为数据1 }k = 0; //计时清零}}switch(addr[3]){DDRB=0XFF;case 0x07: if(a1){PORTB &= ~(1<<PB0);a1=0;}else{PORTB |= (1<<PB0);a1=1;}break;//1case 0x0b: if(a2){PORTB &= ~(1<<PB1);a2=0;}else{PORTB |= (1<<PB1);a2=1;}break;//2case 0x0f: if(a3){PORTB &= ~(1<<PB2);a3=0;}else{PORTB |= (1<<PB2);a3=1;}break;//3case 0x13: if(a4){PORTB &= ~(1<<PB3);a4=0;}else{PORTB |= (1<<PB3);a4=1;}break;//4case 0x17: if(a5){PORTB &= ~(1<<PB4);a5=0;}else{PORTB |= (1<<PB4);a5=1;}break;//5case 0x1b: if(a6){PORTB &= ~(1<<PB5);a6=0;}else{PORTB |= (1<<PB5);a6=1;}break;//6case 0x1f: if(a7){PORTB &= ~(1<<PB6);a7=0;}else{PORTB |= (1<<PB6);a7=1;}break;//7case 0x23: if(a8){PORTB &= ~(1<<PB7);a8=0;}else{PORTB |= (1<<PB7);a8=1;}break;//8case 0x03: if(a9)//蜂鸣器和继电器{PORTC |= (1<<PC7);a9=0;}else{PORTC &= ~(1<<PC7);a9=1;}break;//8case 0x27: PORTB=0X00;break;//9case 0x2b: PORTB=0XFF;break;//空格*/ default : break;}GICR |= (1 << INT0); //使能外部中断INT0sei();}#ifndef __ds18b20__H#define __ds18b20__H#include <avr/io.h>#include <util/delay.h>#include <avr/interrupt.h>#define uchar unsigned char#define uint unsigned int#define CLR_DIR_1WIRE DDRC &= ~(1<<PC6)//不再变化#define SET_DIR_1WIRE DDRC |= (1<<PC6) //IO改为输入口,高阻态,外部上拉电阻拉高#define SET_OP_1WIRE PORTC|= (1<<PC6) //改为输出口,输出低电平#define CLR_OP_1WIRE PORTC &=~(1<<PC6)#define CHECK_IP_1WIRE ( PINC & 0x40)void init_1820(void);void write_1820(unsigned char x);unsigned char read_1820(void);void gettemp(void);volatile uint Temperature;volatile unsigned char temh,teml;volatile uchar Num[4];void init_1820(void){SET_DIR_1WIRE; //设置PA0 为输出 SET_OP_1WIRE; //输出1CLR_OP_1WIRE; //输出0_delay_us(480); //480us以上SET_OP_1WIRE; //输出1CLR_DIR_1WIRE; //设置PA0 为输入 _delay_us(20); //15~60uswhile(CHECK_IP_1WIRE);SET_DIR_1WIRE;SET_OP_1WIRE;_delay_us(140); //60~240ussei();}void write_1820(unsigned char x){unsigned char m;for(m=0;m<8;m++){CLR_OP_1WIRE;if(x&(1<<m)) //写数据了,先写低位的! SET_OP_1WIRE;else{CLR_OP_1WIRE;}_delay_us(40); //15~60usSET_OP_1WIRE;}SET_OP_1WIRE;}unsigned char read_1820(void){unsigned char temp,k,n;temp=0;for(n=0;n<8;n++){CLR_OP_1WIRE;SET_OP_1WIRE;CLR_DIR_1WIRE;k=(CHECK_IP_1WIRE); //读数据,从低位开始 if(k)temp|=(1<<n);elsetemp&=~(1<<n);_delay_us(50); //60~120usSET_DIR_1WIRE;}return (temp);}void gettemp(void) //读取温度值{cli();init_1820(); //复位18b20write_1820(0xcc); // 发出转换命令write_1820(0x44);//_delay_ms(10); //不延时也好使,不知道怎么回事! init_1820();write_1820(0xcc); //发出读命令write_1820(0xbe);teml=read_1820(); //读数据temh=read_1820();sei();}#endif。
三菱FX2nPLC与昆仑通态(MCGS)无线通讯经典案例

三菱FX2nPLC与昆仑通态(MCGS)无线通讯经典案例■ 系统组成昆仑通态使用三菱 PLC FX2N 通信口扩展 485 接口通过专用协议对 PLC 站点相应寄存器进行读写操作, 从而实现对站点工作状态的控制。
这种情况下三菱PLC专用无线通讯终端——DTD435MC,可以使计算机远程无线监控远程站点。
西安达泰电子,组态王无线,工业无线通讯,无线plc,达泰电子,无线收发模块,工厂改造成功案例,PLC无线通讯实例■ 昆仑通态组态搭建首先创建工程画面,本实例通过组态软件实时控制 PLC 相应输出寄存器,演示无线通信实时性和稳定性,分别创建 Y000-Y007 等八个按键,用于写输出状态,创建 8 个文本显示框分别显示当前本地按键状态(0 或者 1)0,表示断开状态,1 表示导通状态,再创建 8 个指示灯分直接读取 PLC 端的输出寄存器状态,工程界面如下图所示:西安达泰电子,组态王无线,工业无线通讯,无线plc,达泰电子,无线收发模块,工厂改造成功案例,PLC无线通讯实例剩余步骤详见下文说明文档■ PLC参数设定PLC 按照以下参数设定,专用通信协议,7 E 1,波特率为 9600,H/W 类型选择为 485,传送顺序格式与组态软件相同,这里为格式 4,站号设置为 0 与设备地址对应。
设置超时判定时间 50 以上:西安达泰电子,组态王无线,工业无线通讯,无线plc,达泰电子,无线收发模块,工厂改造成功案例,PLC无线通讯实例■ 实例总结使用两块DTD435MC无线通讯终端,可以取代原有的485通讯线,实现三菱FX2N系列PLC与昆仑通态组态软件的无线通信,并能实时稳定的进行检测控制。
■完整例程下载【西安达泰电子提供】三菱PLC和昆仑通态无线通信(通信口).pdf■ 无线通讯方案的好处1. 节能环保:功耗小,节省大量供电费用2. 高效:解决移动设备的布线困扰,接电即用3. 可靠:达泰电子专注工业无线通讯领域17年。
昆仑通态人机界面与单片机通信实战教程二:脚本驱动的设计

昆仑通态⼈机界⾯与单⽚机通信实战教程⼆:脚本驱动的设计⼤家好,我是『芯知识学堂』的SingleYork,前⾯给⼤家介绍了“昆仑通态⼈机界⾯与单⽚机通信实战教程⼀:⼯程界⾯的设计”,今天笔者就要来给⼤家介绍“昆仑通态⼈机界⾯与单⽚机通信实战教程⼆:脚本驱动的设其实昆仑通态的软件也⾃带了很多标准设备的驱动,如:西门⼦PLC的驱动、三菱PLC的驱动等,直接加载驱动就可以⽤了,但是对于我们⾃⼰开发的单⽚机板的话,就需要⾃⼰编写驱动了。
⼀说到脚本驱动,⾃然就⽀持标准的modbus协议,也⽀持⾃定义协议,对于我们这些不是很复杂的设备来说,个⼈觉得,没必要去深⼊研究modbus协议,尤其是菜鸟,⾃定义协议可能会更加实⽤,所以,笔者重点给⼤家介绍“⾃动义协议”。
我们先来看⼀下,我们之前设计好的HDMI⼯程:从这个HDMI⼯程中我们可以看到,⼀共有14个输⼊状态、12个输出状态和12个输出控制,其中:14个输⼊状态可以⽤2个字节(BYTE),按位操作来实现状态的显⽰;12个输出状态也可以⽤2个字节(BYTE),按位操作来实现状态的显⽰;12个输出控制,我们可以也可以⽤2个字节(BYTE)来按位控制,也可以⽤12个BYTE来按控制,只是按位操作来控制的话,可能操作会⿇烦⼀些,为了操作简单,我们就⽤12个BYTE来实现控制吧;这样⼀来,我们就可以制定以下通信协议:(1)触摸屏读指令(0x80:⼀次性读取多个数据)格式(⼗六进制):主机发送(触摸屏):帧头(2)+ 长度(1)+ 功能码(1)+ 起始地址(2)+和校验(从长度位开始累加)从机应答(单⽚机):帧头(2)+ 长度(1)+ 功能码(1)+ 数据⼀(输⼊状态⼀:X00-X07)+数据⼆(输⼊状态⼆:X10-X17)+ 数据三(输出状态⼀:Y00-T07))+ 数据四(输出状态⼆:Y10-X17)+和校验(从例:主机发送:37 73 04 80 0000 84从机返回:5A A5 06 80 00 00 00 00 86(2)触摸屏写指令(0x81:写单个寄存器操作)格式(⼗六进制):主机发送(触摸屏):帧头(2)+ 长度(1)+ 功能码(1)+ 寄存器地址(2)+寄存器值(2)+和校验(从长度位开始累加)例:37 73 06 81 0000 0001 88写指令从机就不设置单独的返回指令了,在写完之后,可以通过读指令来查询状态来判断有没有写成功。
NA200H PLC与昆仑通态触摸屏以太网通讯

NA200H PLC与昆仑通态触摸屏以太网通讯2016-7-11陈云目录NA200H PLC与昆仑通态触摸屏以太网通训 (1)1、NA200HPLC通讯口设置 (2)1.1NA200HPLC通讯口定义 (2)1.2NA200HPLC通讯口设置 (3)2、NA200HPLC内部测点与MODBUS协议对应关系 (3)3、昆仑通态通触摸屏通讯口 (5)4、昆仑通态通触摸屏通讯设置 (5)4.1设备管理添加添加MODBUS TCP设备 (5)4.2MODBUS TCP设备设置 (6)4.3增加PLC通讯变量 (7)5、M ODBUS协议对昆仑通态通触摸屏例程画面 (8)NA200H PLC本体提供带有一个以太网口,4路内置串口,RS485接口。
以太网接口支持100M以太网,支持MODBUS/TCP协议,4个通讯口都支持Modbus RTU主从站通讯。
本文介绍NA200HPLC与昆仑通态触摸屏通过以太网进行通讯。
1、NA200HPLC通讯口设置1.1NA200HPLC通讯口定义⏹以太网接口定义模块提供1个RJ45接口的以太网,通过以太网与上位机软件通讯。
定义如下图所示:⏹串口接口定义CPU提供4个RS485接口,其中COM1采用DB9F接口方式,COM2既可选择DB9F接口也可采用端子接线方式连接设备(二种方式选择一种),COM3和COM4采用端子接线方式(RS485端子接线定义见CPU模块端子定义),支持波特率9600-115200bps。
DB9F接口定义如下图所示:端子接线的RS485接口定义如下表C2+RS485接口2信号线AC2-RS485接口2信号线BC3+RS485接口3信号线AC3-RS485接口3信号线BC4+RS485接口4信号线AC4-RS485接口4信号线B本文介绍以太网与触摸屏连接使用,所以使用RJ45口与触摸屏连接,连接网线使用标准的直连线即可。
1.2NA200HPLC通讯口设置NA200HPLC的通讯口设置如下图图1.2.1以太网设置:IP地址,PLC以太网口的地址,必须设置。
MA01系列与昆仑通态组态屏通讯例程

MA01系列串口IO联网模块与昆仑通态触摸屏通信例程一、案例简介本案例主要讲解MA01系列串口IO设备与昆仑通态组态屏(以下简称组态屏)操作细则,本文MA01系列以MA01-AACX2240为例,昆仑通态组态屏以TPC7062TX为例。
二、硬件准备MA01-AACX2240串口IO联网模块一台;USB方形口数据线一根;昆仑通态组态屏TPC7062TX一台;12V电源一个;24V电源一个;开关按钮(自锁型)一个;信号发生器一个;通讯电缆若干;电脑一台;三、软件准备MCGS组态软件;亿佰特IO模块配置测试工具V1.6上位机,可在亿佰特官网相对应位置下载;四、工程创建1、新建工程项目选择触摸屏的型号。
如图所示:在设备窗口,建立串口父设备,因为MA01-AACX2240支持标准的ModBus协议,所以建立莫迪康RTU子设备。
如图所示:双击通用串口父设备,设置串口通信参数,串口端口号选择COM2(COM2为RS485通讯);设置通信波特率,数据位数,停止位数,数据校验方式等,与MA01-AACX2240一致。
如图所示:双击子设备,设置设备的地址为1(与MA01-AACX2240一致,MA01-AACX2240地址为1)。
如图所示:2、定义变量可在用户手册中查找MA01-AACX2240相关通道的寄存器地址。
如图所示:增加通道,根据查找的寄存器地址,建立对应的通道,以DO为例,通道类型选择【0区】输出继电器,通道地址设置为1(MCGS通道地址编号=ModBus寄存器地址号+1),通道个数为4。
如图所示:点击快速连接变量,然后自定义变量连接,对应数据对象的别名,设置开始通道以及通道个数。
如图所示:按照上面的方式,新增AI和DI通道。
完成后,如图所示:3、建立组态界面1)、在工作台中点击用户窗口,然后在用户窗口中点击新建窗口,然后进入新建的窗口进行编辑,如图所示:2)、这里以DO为例,首先建立一个控制DO状态的按钮,点击工具箱里的标准按钮,然后在窗口拖动建立一个按钮。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/***********************************************备注:modbus RTU协议,rs485通讯单片机为从机PLC或者PC为上位机*********************************************/#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit rx_led=P0^0;//接收指示灯sbit tx_led=P0^1;//发送指示灯sbit ctrl_485=P3^2;//485接发发送转换控制sbit dm=P1^4;sbit wm=P1^5;sbit led_cs=P1^6;sbit b7=P2^7;//波特率设置位unsigned int crc=0;uchar sendBuf[20],receive_count=0,a[10];uchar send_count= 0,send_num=0,addr_dip=0;uchar aaa,bbb;uint crc16(unsigned char *puchMsg, unsigned int usDataLen);void beginsend(void);void check_modbus(void);void display(uint date);void delay(uint z);uchar code duan[]={0x3F,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7C,0x39,0x5E,0x79,0x71 };//此数组为!!! 0~9 A B C D E F !!!uchar code wei[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};//此数组表示数码管显示的位数void display(uint date) //num 表示在第几位显示words 表示显示的字符{P2=duan[date/100];P1=wei[0];delay(1);P1=0xff;P2=duan[date%100/10];P1=wei[1];delay(1);P1=0xff;P2=duan[date%10];P1=wei[2];delay(1);}/*************延时*****************/void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=113;y>0;y--);}/************串口初始化*****************/ void uart_init(void){TMOD=0x20;//定时器1,模式2SCON=0x50;//串口通讯方式1TH1=0xfd;//波特率9600TL1=0xfd;if(b7==1)PCON=0x00;elsePCON=0x80;TI=0;//发送中断标志位清零RI=0;//接收中断标志位清零TR1=1;//启动定时器1EA=1;ES=1;}/**************定时器0初始化**************/ void timer0_init(void){TMOD=TMOD&0xf0;TMOD=TMOD|0x01;TH0=0; //16位定时计数器TL0=0;ET0=1; //允许定时器中断}void main(void){dm=0;wm=0;led_cs=1;uart_init();timer0_init();ctrl_485=0;//先置为接收while(1){RI=0;delay(1);rx_led=1;tx_led=1;if(P2^0==0)bbb++;if(bbb==10)aaa++;display(aaa);}}void beginsend(void){ctrl_485=1; //开始置位发送状态 TI=0;send_count = 0;SBUF = sendBuf[0];send_num--;}void time0() interrupt 1///定时器中断{TR0=0;RI=0;check_modbus();receive_count=0;}void ser() interrupt 4{if(TI){if(send_count < send_num){TI=0;tx_led=0;SBUF = sendBuf[++send_count]; }else{receive_count=0;ctrl_485=0;TI=0;}else if(RI){RI=0;rx_led=0;TR0=1;a[receive_count++]=SBUF;TH0=0xf4;TL0=0x1e;}}void check_modbus(void){uchar di,addr;if(receive_count>7)////////////////////address 03 00 00 00 01 crc crc{receive_count=0;crc=crc16(a,6);addr=1; //仪表栈号设置为1// addr=P2>>4;// addr=~(addr&0x0f);// addr=addr&0x0f;// di=~(P2&0X0f);// di=di&0x0f;di=aaa;if(a[0]==addr&&a[1]==0x03&&(crc==((a[7]&0x00ff)|(0xff00&(a[6]<<8))))) {sendBuf[0]=a[0];sendBuf[1]=a[1];sendBuf[2]=0x02; //数据长度为2sendBuf[3]=0x00;//数据高八位为0sendBuf[4]=di; //数据低八位为P2口数据crc=crc16(sendBuf,5); //计算5个数据的CRC校验码sendBuf[5]=crc>>8;sendBuf[6]=crc&0xff;send_num=7;beginsend();}}}/***********************CRC校验*************************/ // CRC 高位字节值表unsigned char code auchCRCHi[260] = {0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40} ;// CRC低位字节值表unsigned char code auchCRCLo[260] = {0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,0x43, 0x83, 0x41, 0x81, 0x80, 0x40} ;unsigned int crc16(unsigned char *puchMsg, unsigned int usDataLen) {unsigned char uchCRCHi = 0xFF ; //* 高CRC字节初始化unsigned char uchCRCLo = 0xFF ; //* 低CRC 字节初始化unsigned long uIndex ; // CRC循环中的索引while (usDataLen--) // 传输消息缓冲区{uIndex = uchCRCHi ^ *puchMsg++ ; // 计算CRCuchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;uchCRCLo = auchCRCLo[uIndex] ;}return (uchCRCHi << 8 | uchCRCLo);}。