打印

rs485通信 MAX488全双工

[复制链接]
4555|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lin34337151|  楼主 | 2010-6-21 11:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ok 0x00;  //地址接收成功,给主机返回OK
#define over 0x01; //本次通信成功,给主机返回OVER结束
#define succ 0x02;  //本次通信成功
#define fail 0x04;  //表示本次通信不成功
sbit key1=P1^2;
sbit key2=P1^3;
sbit key3=P1^4;
sbit key4=P1^5;
/******ch1-ch10控制十路分区********/
sbit ch1=P0^0;
sbit ch2=P0^1;
sbit ch3=P0^2;
sbit ch4=P0^3;
sbit ch5=P0^4;
sbit ch6=P0^5;
sbit ch7=P0^6;
sbit ch8=P0^7;
sbit ch9=P2^7;
sbit ch10=P2^6;   
sbit alarmout=P2^2;
sbit gaodi=P2^1;
sbit scl=P1^0;
sbit sda=P1^1;
sbit CLK_165=P2^4;
sbit LD_165=P2^5;
sbit DATA_165=P2^3;
sbit ALARM=P3^7;
uchar table[2];
uchar bdata numl,numh;
sbit numl0=numl^0;
sbit numl1=numl^1;
sbit numl2=numl^2;
sbit numl3=numl^3;
sbit numl4=numl^4;
sbit numl5=numl^5;
sbit numl6=numl^6;
sbit numl7=numl^7;
sbit numh0=numh^0;
sbit numh1=numh^1;
sbit numh2=numh^2;
sbit numh3=numh^3;
sbit numh4=numh^4;
sbit numh5=numh^5;
sbit numh6=numh^6;
sbit numh7=numh^7;
void delay(uchar z)                    //长延时函数
{
int x,y;
for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}
void delay1()                         // 短延时函数
{;;}
/***********I2C总线通信,24C02*********************/
void start()                     //开始信号
{
sda=1;
delay1();
scl=1;
delay1();
sda=0;
delay1();
}
void stop()                      //停止信号
{
sda=0;
delay1();
scl=1;
delay1();
sda=1;
delay1();
}
void respons()                   //应答信号
{
uchar i;
scl=1;
delay1();
while((sda==1)&&(i<250))i++;
scl=0;
delay1();
}
void write_byte(uchar date)   //写字节函数
{
uchar i,temp;
temp=date;
    for(i=0;i<8;i++)
{
  temp=temp<<1;
  scl=0;
     delay1();
  sda=CY;
  delay1();
  scl=1;
  delay1();
}
scl=0;
delay1();
sda=1;
delay1();
}
uchar read_byte()        //读字节函数
{
uchar i,k;
scl=0;
delay1();
sda=1;
delay1();
for(i=0;i<8;i++)
{
  scl=1;
  delay1();
  k=(k<<1)|sda;
  scl=0;
  delay1();
}
return k;
}
void write_add(uchar address,uchar date)       //把数据写入确定地址
{
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
    delay(3);
}
uchar read_add(uchar address)     //从确定地址读数据
{
uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
/******74LS165并口转串口输入********/
uint shift()                               //两个165级联函数,数据并入串出
{
     uint i,Read_data=0x0000;
     uint data_buf;
     LD_165=0;
     delay1();
     LD_165=1;
     for(i=0;i<16;i++)
     {
          Read_data<<=1;
          if(DATA_165)
          {
             Read_data|=0x0001;
          }
             CLK_165=0;
                _nop_();
                CLK_165=1;
             delay1();
     }
     data_buf=Read_data;                        //数据保存在data_buf
     return(data_buf);
}
/************4个I/O口扫描12个按键************/     
void scansky(uchar a,uchar b,uchar c,uchar d,uchar shu,uchar e,uchar add)        //键盘扫描函数
{   
      uchar temp,num;
   key1=a;
   key2=b;
   key3=c;
   key4=d;
   temp=P1;
   temp=temp&shu;      
   if(temp!=shu)
   {   
    delay(8);
    temp=P1;                       //去抖
    temp=temp&shu;
    if(temp!=shu)
    {
     temp=P1;
        temp=temp&shu;
        if(temp==e)
     {
       while(temp!=shu)       //等待松手
       {
             temp=P1;
          temp=temp&shu;
              }
                          num=read_add(add);
                          delay(2);                                       
                 num++;
                 if(num==2)
                 num=0;
        write_add(add,num);
        delay(5);   
               }
            }
       }
}
/* 串口初始化函数 **串口通信芯片使用MAX488全双工通信*/
void init_serial()
{
TMOD = 0x20;    // 定时器T1使用工作方式2
TH1 = 250;
TL1 = 250;
TR1 = 1;     // 开始计时
PCON = 0x80;    // SMOD = 1
SCON = 0xd0;    // 工作方式,9位数据位,波特率9600kbit/s,允许接收
}
/* 接收数据函数 */
uchar recive(uchar addrass)
{
     uchar i,temp;
     /* 接收地址 */
     RI = 0;
     while(!RI);
     temp=SBUF;
     RI = 0;
        if((RB8==1)&&(addrass==temp)) //如果地址接收成功请求主机发送数据,给主机返回OK   
        {
             TI=0;
             TB8=0;
             SBUF=ok;
             while(!TI);
             TI=0;        
        }
     /* 接收数据 */
        for(i=0;i<2;i++)
        {
          while(!RI);
          table[i]=SBUF;
          RI = 0;
        }  
        if((table[1]&0xfc)==0xfc)  // 接收到的数据跟事先预设好的数据校检,成功,发送OVER结束
     {
             TI=0;
             TB8=0;
             SBUF=over;
             while(!TI);
             TI=0;
                return succ;
        }
        else
        return fail;
}
void init()      //主函数初始化  关闭所有分区
{
         write_add(1,0);  //把数据写入24c02
         write_add(2,0);
         write_add(3,0);
         write_add(4,0);
         write_add(5,0);
         write_add(6,0);
         write_add(7,0);
         write_add(8,0);
         write_add(9,0);
         write_add(0,0);
         alarmout=1;
}   
void main()
{
     uchar num,read_date,flag;
     uint temp;
     init();
     init_serial();
     while(1)
     {      
             flag=recive(0x00);    //0x00从机地址
             if(flag==0x02)
             {
                     numl=table[0];
                     numh=table[1];
                     write_add(1,numl0);    //把数据写入24c02
                     write_add(2,numl1);
                     write_add(3,numl2);
                     write_add(4,numl3);
                     write_add(5,numl4);
                     write_add(6,numl5);
                     write_add(7,numl6);
                     write_add(8,numl7);
                     write_add(9,numh0);
                     write_add(0,numh1);                     
             }
             if(ALARM==0)
             {
                    delay(5);
                    if(ALARM==0)
                    {
                            while(!ALARM);
                            num++;
                            num=num%2;
                            if(num==1)
                            {
                                 ch1=0;
                                 ch2=0;
                                 ch3=0;
                                 ch4=0;
                                 ch5=0;
                                 ch6=0;
                                 ch7=0;
                                 ch8=0;
                                 ch9=0;
                                 ch10=0;
                                 alarmout=0;
                            }
                     }
              }
             if(num!=1)
             {
                     temp=shift();      
                     if(((gaodi==0)&&((temp&0x0001)==0x0001))||((gaodi==1)&&((temp&0x0001)==0x0000)))   //第一分区,在高或低电平判断74LS165是否有有效信号输入
                            ch1=0;
                     else
                     {     
                            scansky(1,1,1,0,0x1c,0x18,1);    // 扫描CH1建
                            read_date=read_add(1);           //读取24c02数据
                            if(read_date==1)
                            ch1=0;
                            else
                            ch1=1;
                     }
                    if(((gaodi==0)&&((temp&0x0002)==0x0002))||((gaodi==1)&&((temp&0x0002)==0x0000)))
                            ch2=0;
                    else
                    {      // ch2=~ch2;
                            scansky(1,1,0,1,0x2c,0x28,2);     // 扫描CH2建
                            read_date=read_add(2);
                            if(read_date==1)
                            ch2=0;
                            else
                            ch2=1;
                    }
                    if(((gaodi==0)&&((temp&0x0004)==0x0004))||((gaodi==1)&&((temp&0x0004)==0x0000)))
                            ch3=0;
                    else
                    {      
                            scansky(1,0,1,1,0x34,0x30,3);      // 扫描CH3建
                            read_date=read_add(3);
                            if(read_date==1)
                            ch3=0;
                            else
                            ch3=1;
                    }
                    if(((gaodi==0)&&((temp&0x0008)==0x0008))||((gaodi==1)&&((temp&0x0008)==0x0000)))
                            ch4=0;
                    else
                    {
                            scansky(1,1,1,0,0x1c,0x14,4);      // 扫描CH4建
                            read_date=read_add(4);
                            if(read_date==1)
                            ch4=0;
                            else
                            ch4=1;
                    }
                    if(((gaodi==0)&&((temp&0x0010)==0x0010))||((gaodi==1)&&((temp&0x0010)==0x0000)))
                            ch5=0;
                    else
                    {
                            scansky(1,1,0,1,0x2c,0x24,5);      // 扫描CH5建
                            read_date=read_add(5);
                            if(read_date==1)
                            ch5=0;
                            else
                            ch5=1;
                    }
                    if(((gaodi==0)&&((temp&0x0020)==0x0020))||((gaodi==1)&&((temp&0x0020)==0x0000)))
                            ch6=0;
                    else
                    {
                            scansky(0,1,1,1,0x38,0x30,6);      // 扫描CH6建
                            read_date=read_add(6);
                            if(read_date==1)
                            ch6=0;
                            else
                            ch6=1;
                    }
                    if(((gaodi==0)&&((temp&0x0040)==0x0040))||((gaodi==1)&&((temp&0x0040)==0x0000)))
                            ch7=0;
                    else
                    {
                            scansky(1,1,1,0,0x1c,0x0c,7);      // 扫描CH7建
                            read_date=read_add(7);
                            if(read_date==1)
                            ch7=0;
                            else
                            ch7=1;
                    }
                    if(((gaodi==0)&&((temp&0x0080)==0x0080))||((gaodi==1)&&((temp&0x0080)==0x0000)))
                            ch8=0;
                    else
                    {
                            scansky(1,0,1,1,0x34,0x24,8);      // 扫描CH8建
                            read_date=read_add(8);
                            if(read_date==1)
                            ch8=0;
                            else
                            ch8=1;
                     }
                    if(((gaodi==0)&&((temp&0x0100)==0x0100))||((gaodi==1)&&((temp&0x0100)==0x0000)))
                            ch9=0;
                    else
                    {
                            scansky(0,1,1,1,0x38,0x28,9);      // 扫描CH9建
                            read_date=read_add(9);
                            if(read_date==1)
                            ch9=0;
                            else
                            ch9=1;
                    }
                    if(((gaodi==0)&&((temp&0x0200)==0x0200))||((gaodi==1)&&((temp&0x0200)==0x0000)))
                            ch10=0;
                    else
                    {
                            scansky(1,1,0,1,0x2c,0x0c,0);         //扫描CH10
                            read_date=read_add(0);
                            if(read_date==1)
                            ch10=0;
                            else
                            ch10=1;
                    }
                    if(((gaodi==0)&&((temp|0xfc00)!=0xfc00))||((gaodi==1)&&((temp&0x03ff)!=0x03ff))||(num==1))  // 当74LS165有有效信号或NUM==1,开启报警输出
                    alarmout=0;
                    else
                    alarmout=1;

            }
      }
}

相关帖子

沙发
lin34337151|  楼主 | 2010-6-21 11:16 | 只看该作者
写这个函数是想通过主机(STC89C52RC)远程控制它,控制十个分区继电器的开关,老感觉串口通信这个地方有问题,高手指点一下,看能不能实现

使用特权

评论回复
板凳
ajax_wh| | 2010-6-23 14:50 | 只看该作者
哈哈!程序太长了!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

113

主题

285

帖子

3

粉丝