EDABOSS电子论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 729|回复: 1

[转帖] 四路开关量输入

[复制链接]

13

主题

0

回帖

127

E币

技术员

Rank: 2

积分
26
发表于 2017-5-12 15:28:46 | 显示全部楼层 |阅读模式
本文以51单片机控制四路开关量输入/六路开关量输出为例,设计了一个简单的上位机下位机通信作品,作为模块学习和整理,供读者参考!
四路开关量输入/六路开关量输出C语言程序
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
uchar indata[4];
uchar outdata[4];
volatile uchar temp1 = 0,temp2 = 0;
uchar i,j;
void initial_comm(void)
{
       SCON= 0x50;         //设定串行口工作方式:mode 1 ; 8-bit UART,enable ucvr                        
       TMOD= 0x21;      //TIMER 1;mode 2  ;8-Bit Reload                 
       PCON= 0x80;      //波特率不加倍SMOD = 1        
       TH1= 0xfa;       //baud:  9600fosc = 11.0596            
       IE= 0x90;           // enable serial interrupt         
       TR1= 1;     // timer 1   
}
void uart_send(void)
{     
       ES= 0;
       if(indata[3]== indata[0]^indata[1]^indata[2])   
       {
              if(indata[1]==0x01)
              {
                     temp1= P0;
                     temp1= temp1&0x0f;
                     outdata[0]= 0xee;
                     outdata[1]= 0x02;
                     outdata[2]= temp1;
                     outdata[3]= outdata[0]^outdata[1]^outdata[2];
                     for(i=0;i<4;i++)
                     {
                            SBUF= outdata;
                            while(TI== 0);
                            TI= 0;
                     }                  
             }
                        
              if(indata[1]==0x03)
           {                  
                     temp2= indata[2];
                     P1= temp2;  
              }                  
              if(indata[1]==0x04)
              {
                     outdata[0]= 0xee;
                     outdata[1]= 0x05;
                     outdata[2]= temp2;
                     outdata[3]= outdata[0]^outdata[1]^outdata[2];
                     for(i=0;i<4;i++)
                     {
                            SBUF= outdata;
                            while(TI== 0);
                            TI= 0;
                     }            
              }
       }
       ES= 1;         
}
void main()
{
       initial_comm();
       ES= 1;
       while(1)
       {
              uart_send();
       }
}
void uart_receive(void)  interrupt 4
{
       RI= 0;
       for(j=0;j<4;j++)
       {
              indata[j]= SBUF;
              while(RI==0);
              RI=0;
       }
}
               四路开关量输入/六路开关量输出通讯协议
通信设置:波特率 9600b/s   
1位起始位   8位数据位  无校验位  1位停止位
命令格式
区别码(1字节)+  Command1字节) +  Content1字节)+Xor1字节)
区别码: 上位发送/单片机接收:0xff  
     单片机发送/上位机接收 :0xee
Command = 0x01   上位机命令单片机读取四路输入开关量的输入状态
      如:0xff+ 0x01 + 0x00 + Xor
Command = 0x02  单片机返回四路输入状态给上位机
此时,Content 的1字节中的低四位分别表示四路开关量的输入状态        
1表示输入高电平,0表示输入低电平
              第一路输入(第0位)
              第二位输入(第1位)
              第三路输入(第2位)
              第四路输入(第3位)
       如:假设某一时刻四路输入开关量的输入状态为0x03,上位机读取其状态为:
          0xee + 0x02 + 0x03  + Xor  
Command = 0x03  上位机命令单片机控制六路输出的输出状态
          此时,Content1字节中的低六位分别表示六路开关量的输出状态        
1表示输出高电平,0表示输出低电平
              第一路输出(第0位)
              第二路输出(第1位)
              第三路输出(第2位)
              第四路输出(第3位)
              第五路输出(第4位)
              第六路输出(第5位)
       如:上位机欲设置某一时刻六路输出开关量的输出状态为0x01
           0xff + 0x03 + 0x01  + Xor
Command = 0x04   上位机命令单片机读取六路输出开关量的输出状态
       如:0xff+ 0x04 + 0x00 + Xor
Command = 0x05   单片机返回六路输出状态给上位机
          此时,Content 1字节中的低六位分别表示六路开关量的输出状态      
1表示输出高电平,0表示输出低电平
              第一路输出(第0位)
              第二路输出(第1位)
              第三路输出(第2位)
              第四路输出(第3位)
              第五路输出(第4位)
              第六路输出(第5位)
如: 某一时刻六路输出开关量的输出状态为0x01,上位机读取其状态为:
           0xee + 0x05 + 0x01  + Xor
Content:表示四路输入开关量的输入状态(数据)或者六路输出开关量的输出状态(数据),在不使用它的命令格式中,它的值无意义,为通信方便,在不使用它的命令格式中,规定其值为0x00
Xor :从第一个字节开始到Xor的前一个字节(总共3个字节),做异或运算

积分规则
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|EDABOSS电子论坛

GMT+8, 2024-4-23 22:14 , Processed in 0.037670 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表