您现在所在的是:

单片机论坛

回帖:4个,阅读:1571 [上一页] [1] [下一页]
2040
245484515
文章数:352
年度积分:50
历史总积分:2040
注册时间:2010/11/30
发站内信
发表于:2011/11/21 9:49:53
#0楼
很多时候,工业控制或者产品设计方面受到PLC这种功能确定,扩展麻烦,成本昂贵等方面的制约因素,需要独立开发一种特殊功能,但是又需要连接触摸屏通讯,工程师在这个方面往往需要花费很大功夫,现在我要帮大家解决的问题就是 单片机与人机界面触摸屏通讯的最简单,最有效的 2种方法,其实就是分为2种通讯协议,即工业标准的 Modbus RTU协议和 工程师自己定义的  自由协议。
  本实例采用广州市微嵌计算机科技有限公司(公司网站:http://www.wqlcd.com)的人机界面作为参考,因为公司提供一系列的技术支持和公布单片机源代码,加上公司的人机界面支持自由协议等等先天优势,开发工程方便有效。
     方案比较:
方案一  modbus—rtu协议:
    优点:工业标准通讯协议,具有通用性,,传输数据量大
    缺点:需要时间去了解协议的格式和以及按照规定编写通讯程序(我们提供MODBUS-RTU源代码,客户直接移植就可以,不必费心)
方案二   自由协议:
    优点:数据格式客户自己定义,灵活多变,定制性强,可以模拟任何已知报文的通讯协议
    缺点:传输数据量不大,通用性不强,移植不方便

 工程师可以根据以上两种通讯协议的优缺点来选择理想的方案;

现在我们重点介绍广州市微嵌计算机科技有限公司的人机界面的自由通讯协议。

首先下载人机界面的组态软件:http://www.wqlcd.com/new/league.asp?keyno=34

下载安装好软件之后,新建一个工程文件,型号对应的是公司出产产品型号,通讯设置分为COM1,COM2设置,因为人机界面有2个串口,这两个串口既可以做RS232,又可以做RS485,根据客户工程需求接线,通讯协议对应的就是单片机工程师需要用的协议,其中Modbus rtu协议,自由协议Free Protocol,当然还包括西门子200,台达PLC,欧姆龙,三菱等协议,这里我们选择COM1自由协议Free Protocol,通讯速率57600,数据位8,1位停止位,偶校验:
附件

首先我们随便建一个比较简单实用的画面,用位按钮开关控制单片机的LED灯,采集单片机的数据(AD采集)显示在组态软件的数码管(可以电脑串口连接单片机在线模拟,方便开发工程)。
附件

然后我们要把位按钮的属性绑定到人机界面的系统寄存器,然后再用人机界面内置的宏指令通讯函数output函数把寄存器数据传输给单片机,让单片机接收这个指令之后进行动作控制,方法实现如下:
附件
我们把位按钮1绑定到人机界面系统寄存器LB的第0个里面,再用一个LED指示灯观察按钮的状态(绑定系统寄存器LB0)
附件
对于数码管显示,属性设置原来差不多,但是需要用input函数将从单片机采集的数据存储到人机界面系统寄存器,再通过宏指令函数映射显示出来,方法如下:
附件
我们将通道一绑定到系统寄存器LD的第1个寄存器,LD是数据寄存器,LB是布尔量的位寄存器,注意两种寄存器的区别。
接下来我们要用到人机界面的组态软件内置的通讯函数,数学运算函数和其他函数了。由“设定”菜单那里进入到宏指令编辑器进入宏指令编辑:
附件
点击新增,我们写一个宏指令通讯函数,向单片机发送控制指令和接受数据:
附件
具体编程如下:
宏指令test
void Macro_main( )
{
unsigned char dat[4];
unsigned short dat1[4];
int re_dat;
Input( 1, dat, 4, re_dat);
/*如果不明白函数使用,可以点击函数向导按钮查找函数使用说明:
附件
【描述】
第一个参数channel表示通道,如果通道为com1,则channel=1;如果通道为com2,则channel=2,数据类型为int。
第二个参数pString表示写入通道的字符串的地址,数据类型为unsigned char *。
第三个参数count表示字符串中的字符个数,数据类型为int。
第四个参数result表示Output函数运行后返回的结果,如果result大于0,则表示读写有效,数据类型为int。
注意:此函数只能用在freeprotocol(自由协议通道)中。

【用法】
Input(channel,pString,count,result);

【举例】
char srt[9];
int result;
Input(1,str[0],9,result);

*/
       dat1[0]=dat[0];
dat1[1]=dat[1];
dat1[2]=dat[2];
dat1[3]=dat[3];
SetWordData(0,1,1,16, dat1[0]);
SetWordData(0,1,2,16, dat1[1]);
SetWordData(0,1,3,16, dat1[2]);
SetWordData(0,1,4,16, dat1[3]);
}


test2:用于发送指令到单片机进行控制,主要用到output函数
static unsigned char key[3];
void Macro_main( )
{
bool key_data[16];
int re_dat;
GetByteData(0, 1,0, 9, 0,key_data);
    key[0] = key_data[7]<<7 |  key_data[6]<<6 |  key_data[5]<<5 |  key_data[4]<<4 |  key_data[3]<<3 |  key_data[2]<<2 |  key_data[1]<<1 | key_data[0];
    //key[1]=key_data[15]<<7 |  key_data[14]<<6 |  key_data[13]<<5 |  key_data[12]<<4 |  key_data[11]<<3 |  key_data[10]<<2 |  key_data[9]<<1 | key_data[8];
     key[1]=key_data[8];
Output( 1, key, 2, re_dat);
     
}

对应单片机下位机的编程,作为单片机开发者应该都知道如何编程了,这里我就提供这个例子的51单片机源代码供大家参考:
附件:
[本地下载]
单片机测试板原理图(配合源代码使用):
附件:
[本地下载]
技术支持QQ:605440535
[此贴子已经被作者于2011/11/21 10:08:34编辑过]
2040
245484515
文章数:352
年度积分:50
历史总积分:2040
注册时间:2010/11/30
发站内信
发表于:2011/11/21 13:46:12
#1楼
人机界面宏指令使用说明书
资料下载:
附件:
[本地下载]

附件:
[本地下载]
2040
245484515
文章数:352
年度积分:50
历史总积分:2040
注册时间:2010/11/30
发站内信
发表于:2011/11/24 8:33:20
#2楼
附录:人机界面内置通讯函数详细说明

Output();
【描述】
第一个参数channel表示通道,如果通道为com1,则channel=1;如果通道为com2,则channel=2,数据类型为int。
第二个参数pString表示从通道输出的字符串的地址,数据类型为unsigned char *。
第三个参数count表示字符串中的字符个数,数据类型为int。
第四个参数result表示Output函数运行后返回的结果,如果result大于0,则表示读写有效,数据类型为int。
注意:此函数只能用在freeprotocol(自由协议通道)中。
【用法】
Output(channel,pString,count,result);
【举例】
char srt[9];
int result;
Output(1,str[0],9,result);



Input();
【描述】
第一个参数channel表示通道,如果通道为com1,则channel=1;如果通道为com2,则channel=2,数据类型为int。
第二个参数pString表示写入通道的字符串的地址,数据类型为unsigned char *。
第三个参数count表示字符串中的字符个数,数据类型为int。
第四个参数result表示Output函数运行后返回的结果,如果result大于0,则表示读写有效,数据类型为int。
注意:此函数只能用在freeprotocol(自由协议通道)中。
【用法】
Input(channel,pString,count,result);
【举例】
char srt[9];
int result;
Input(1,str[0],9,result);

GetWordData();
【描述】
函数功能:从通道中读取Word数据。
第一个参数channel表示通道,数据类型为unsigned char。
第二个参数slaveID表示从机号,数据类型为unsigned char。
第三个参数address表示系统通道地址,数据类型为unsigned short。
第四个参数count表示要读出的字的个数,数据类型为unsigned short。
第五个参数表示命令号,数据类型为unsigned char。
第六个参数pvalue用来保存从系统通道读出的count个字,数据类型为unsigned short *。
【用法】
GetWordData(channel,slaveID,address,count,cmd,pvalue);
【举例】
unsigned short wordData[10];
GetWordData(0, 1,8000, 10, 0,wordData);
从系统通道 8000地址中读取10个数据到wordData

SetWordData();
【描述】
函数功能:从通道中写入一个Word数据。
第一个参数channel表示通道,数据类型为unsigned char。
第二个参数slaveID表示从机号,数据类型为unsigned char。
第三个参数address表示系统通道地址,数据类型为unsigned short。
第四个参数cmd表示命令号,数据类型为unsigned char。
第五个参数pvalue用来保存写入系统通道的字,数据类型为unsigned short。
【用法】
SetWordData(channel,slaveID,address,cmd,source);
【举例】
unsigned short wordData = 1;
SetWordData(0, 1,1000,0,wordData);
把wordData中的Word数据写到系统通道 1000地址处


附录二:
使用自由协议来模拟modbus-RTU

//COM1:freeprotocol
//COM2:modbus-RTU
/*自由协议通道采集数据存放在系统通道,在界面显示
  modbus通道采集到的数据,处理后,发送到自由协议的设备上*/
unsigned char command[32];

unsigned char response[32];

unsigned char temp1,temp2;

unsigned short address, checksum;

unsigned short read_no, return_value1, return_value2,return_value3,read_data[2], i;

unsigned short com2_data;
/****************以上是新建需要使用的变量***********/

Fill(command, 0, 32);// initialize command[0]~command[31] to 0

Fill(response, 0, 32);  //把command 和response 初始化

command[0] = 0x1;// 设置发送字符窜的第一个数据  station number

command[1] = 0x3;// 设置发送字符窜的第二个数据 read holding registers (function code is 0x3)

address = 0;// starting address (4x_1) is 0

HiByte(address, command[2]);//设置发送字符窜的第三个数据

LoByte(address, command[3]);//设置发送字符窜的第四个数据

read_no = 2;// the total words of reading is 2 words

HiByte(read_no, command[4]);//设置发送字符窜的第五个数据

LoByte(read_no, command[5]);//设置发送字符窜的第六个数据

CRC(command, 6,checksum);// calculate 16-bit CRC

LoByte(checksum, command[6]); //设置发送字符窜的第七个数据

HiByte(checksum, command[7]); //设置发送字符窜的第八个数据

Output(1,command,8, return_value1); //把设置好的8个数据,从通讯口1发送出去,具体参数设置参考Output()使用

Input(1,response,9,return_value2); //从通讯口1等待接收9个字符数据,并且放在response[0]~response[8],具体参数设置参考Intput()使用

CRC(response, 7,checksum); //对采集上来的9个数据中前7个进行了CRC-16校验,校验结果存放在checksum

LoByte(checksum, temp1);  //把checksum的低8位放在temp1

HiByte(checksum, temp2);  //把checksum的高8位放在temp1

if(temp1==response[7]&&temp2==response[8])    //CRC校验码进行对比判别时候接收正确

{  
                                                                          //CRC检验正确后,把采集来的数据中指定需要的数据放在read_data[]
read_data[0] = response[4] + (response[3] << 8);    

read_data[1] = response[6] + (response[5] << 8);

SetWordData(0 ,1 ,0 ,2,0 , read_data); // 通过SetWordData()函数,把read_data送到系统寄存器中,具体使用需要参考SetWordData()函数使用
}

GetWordData( 2, 1, 2, 2, 3, &com2_data);   // 通讯口2,使用的是modbus-RTU协议,

command[0] = 0x1;// station number

command[1] = 0x6;// wirte holding registers (function code is 0x6)

address=10;

checksum=0;

HiByte(address, command[2]);

LoByte(address, command[3]);

HiByte(com2_data, command[4]);

LoByte(com2_data, command[5]);

CRC(command, 6,checksum);// calculate 16-bit CRC

LoByte(checksum, command[6]);

HiByte(checksum, command[7]);

Output(1,command,8, return_value3);  //发出定义好8个字符串

2040
245484515
文章数:352
年度积分:50
历史总积分:2040
注册时间:2010/11/30
发站内信
发表于:2011/11/24 8:42:58
#3楼
资料下载:人机界面与单片机自由通讯协议工程实例下载
附件:
[本地下载]
附件:
[本地下载]
1558
风的旋律
文章数:95
年度积分:69
历史总积分:1558
注册时间:2013/11/19
发站内信
发表于:2015/1/6 20:01:44
#4楼
学习了

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 非法和不良信息举报

工控网客服热线:0755-86369299
版权所有 工控网 Copyright©2024 Gkong.com, All Rights Reserved

62.4004