求 MAX485串口程序 例子简单的最好。我会写323的程序,但是485的好像和232的不一样,有

2020-01-21 21:46发布

不知道你那边RS485硬件是怎么接法的?一般串口用就可以了,
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
12条回答
snail0204
2020-01-22 05:14

(原文件名:HubUp_485.JPG)

一个RS485中继器,分两个单片机,例子是与上位机通讯的单片机的,仅供参考!

//Program(cpu 8052) of Part of RS-485 repeater (UpLink)  in C51
//Started at 2002/07/17
//Author FenglinYao at Nanjing
//说明:
      // 1、平时UpLink部分监视上位机状态,DownLink部分巡检下位机报警数据。
      // 2、如果UpLink部分收到登录命令,则关闭DownLink部分巡检通道,打开上位机——下位机通道。
      // 3、如果UpLink部分收到退出登录命令,则关闭上位机——下位机通道,恢复DownLink部分巡检。
      // 4、如果UpLink部分收到报警查询命令,则转换为上位机与DownLink部分通讯。
      // 5、初始化时DownLink部分从UpLink部分获取波特率。

//-----------------------------------------------------------------------------------------
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define nop _nop_();
#define ETX 0X03        /* 消息结束标识 */
#define STX 0X02        /* 消息开始标识 */

bdata uchar Status1    _at_   0x20;       //中继器状态标志
sbit  Write_Not_Need           = Status1^0;       //显示是否需要写24C04
sbit  Log_In                   = Status1^1;       //上位机已登陆到中继器标志位
sbit  Log_Out                  = Status1^2;       //上位机退出登陆标志位
sbit  Ask_for_Alarm            = Status1^3;       //上位机查询报警标志位
sbit  Ask_for_Baud             = Status1^4;       //交换波特率状态
sbit  Init                     = Status1^5;       //单片机正处于初始化状态
sbit  Power_Off                = Status1^6;       //电源电压低标志位
sbit  Alarm_Data_Interchange   = Status1^7;       //交换报警数据状态

bdata uchar Status2    _at_   0x21;       //中继器状态标志
sbit  Read_Error               = Status2^0;       //读24C04错误
sbit  Write_Error              = Status2^1;       //写24C04错误
sbit  Data_Received            = Status2^2;       //发出数据已被接收到
sbit  Data_Ver_Send            = Status2^3;       //发出数据偶校验标志
sbit  BroadCasting             = Status2^4;       //收到上位机对下位机的广播信号(时间、日期)
sbit  Com1Data_Sent            = Status2^5;       //串口1已发送一字节
sbit  tem_bit                  = Status2^6;       //临时位变量
sbit  Com1_Finished            = Status2^7;       //串口1数据已接收完毕

bdata uchar Status3    _at_   0x22;       //中继器状态标志
sbit  Alarm_Over               = Status3^0;       //掉电时下位机侧传来的报警数据结束
sbit  PowerTest                = Status3^1;       //掉电中断口检测位
sbit  OK                       = Status3^2;       //临时变量
sbit  Com1_deal                = Status3^3;       //串口收到数据要进行处理
sbit  Com2_Finished            = Status3^4;       //并口数据接收完毕
sbit  PTN                      = Status3^5;       //并口有数据需发送
sbit  PTI                      = Status3^6;       //并口数据已发出
sbit  notusedbit               = Status3^7;       //

bdata uchar ParData    _at_   0x23;       //并行输出通讯缓冲区
sbit  ParData0                 = ParData^0;
sbit  ParData1                 = ParData^1;
sbit  ParData2                 = ParData^2;
sbit  ParData3                 = ParData^3;
sbit  ParData4                 = ParData^4;
sbit  ParData5                 = ParData^5;
sbit  ParData6                 = ParData^6;
sbit  ParData7                 = ParData^7;

bdata uchar PaOData    _at_   0x24;       //并行读入通讯缓冲区
sbit  PaOData0                 = PaOData^0;
sbit  PaOData1                 = PaOData^1;
sbit  PaOData2                 = PaOData^2;
sbit  PaOData3                 = PaOData^3;
sbit  PaOData4                 = PaOData^4;
sbit  PaOData5                 = PaOData^5;
sbit  PaOData6                 = PaOData^6;
sbit  PaOData7                 = PaOData^7;

bdata uchar SData    _at_   0x25;       //串行通讯缓冲区
sbit  SD_0                   = SData^0;
sbit  SD_1                   = SData^1;
sbit  SD_2                   = SData^2;
sbit  SD_3                   = SData^3;
sbit  SD_4                   = SData^4;
sbit  SD_5                   = SData^5;
sbit  SD_6                   = SData^6;
sbit  SD_7                   = SData^7;
bdata uchar Repeater_Address   _at_ 0x26;          //中继器地址
sbit  RA_0                   = Repeater_Address^0;
sbit  RA_1                   = Repeater_Address^1;
sbit  RA_2                   = Repeater_Address^2;
sbit  RA_3                   = Repeater_Address^3;
sbit  RA_4                   = Repeater_Address^4;
sbit  RA_5                   = Repeater_Address^5;
sbit  RA_6                   = Repeater_Address^6;
sbit  RA_7                   = Repeater_Address^7;

bdata uchar Repeater_Status   _at_ 0x27;          //中继器状态标志位
sbit  DHead_Arrived          = Repeater_Status^0;
sbit  Sdog_Feed              = Repeater_Status^1;
sbit  Dog_Feedback           = Repeater_Status^2;
sbit  Sdog_Play              = Repeater_Status^3;
sbit  Ask_for_Status         = Repeater_Status^4;
sbit  RS_5                   = Repeater_Status^5;
sbit  RS_6                   = Repeater_Status^6;
sbit  RS_7                   = Repeater_Status^7;

uchar data baud               _at_ 0x30;          //通讯参数-波特率的设置参数
uchar data W_P_Data_Buf1      _at_ 0x32;          //Com1写数据缓冲区指针1
uchar data R_P_Data_Buf1      _at_ 0x33;          //Com2读数据缓冲区指针1
uchar data W_P_Data_Buf2      _at_ 0x34;          //并口写数据缓冲区指针2
uchar data R_P_Data_Buf2      _at_ 0x35;          //并口读数据缓冲区指针2
uchar data W_P_24C32Buf       _at_ 0x36;          //写24C32缓冲区指针
uchar data R_P_24C32Buf       _at_ 0x37;          //读24C32缓冲区指针
uchar data Buf_of_Com1        _at_ 0x38;          //串口1缓冲区
uchar data Buf_of_Com2        _at_ 0x39;          //并口缓冲区
uchar data i,j,k,l            _at_ 0x3a;          //临时变量
uchar data ErrorCode          _at_ 0x3e;          //用于返回出错代码
uint  data ET                 _at_ 0x3f;          //用于测试
uchar data Timer_tem1         _at_ 0x41;          //时间临时变量
uchar data Timer_1m           _at_ 0x42;          //分
uchar data Timer_1s           _at_ 0x43;          //秒
uchar data Timer_1h           _at_ 0x44;          //小时
uchar data Timer_1d           _at_ 0x45;          //天
uchar data Timer_dog          _at_ 0x46;          //按秒记数,上位机巡检过清零,溢出时复位
uchar data Tem_Buf            _at_ 0x47;          //串口溢出后临时缓冲区
uchar data Timer_tem          _at_ 0x48;          //时间临时变量
uchar data PAlarmData         _at_ 0x49;          //保存报警数据到24C04时的报警堆栈区指针
uchar data sum                _at_ 0x4a;          //作校验和运算用
uchar data Buf_of_Com2a       _at_ 0x4b;
uchar data Buf_of_Com2b       _at_ 0x4c;
uchar data m,n                _at_ 0x4d;          //临时变量
uchar data ExchangeTemp       _at_ 0x4e;
uchar data Timer_Error        _at_ 0x4f;
uchar data StackBuf[32]       _at_ 0x50;          //堆栈区


uchar idata Timer_Over;
uchar idata Com_Buff[32];                          //并口收数据缓冲区
uchar idata Data_Buf[32];                          //串口收数据缓冲区
uchar idata Buf_of_WR[32];                         //页读写24C64的缓冲区

sbit PData0=P1^0;
sbit PData1=P1^1;
sbit PData2=P1^2;
sbit PData3=P1^3;
sbit PData4=P1^4;
sbit PData5=P1^5;
sbit PData6=P1^6;
sbit PData7=P1^7;
sbit TXD2=P2^7;
sbit RXD2=P2^6;
sbit DogHand=P2^5;
sbit LED=P2^4;
sbit sda=P2^3;
sbit scl=P2^2;
sbit WDI=P2^1;
sbit DR1=P2^0;
sbit PTest=P3^2;
sbit PR1=P3^4;
sbit PR2=P3^3;
sbit AnS=P3^5;
sbit Bd1=P3^6;
sbit Bd2=P3^7;

char code RepeaterVer[32]={"Repeater1.1 Author Yaofenglin NJ"};  //记录中继器的版本及相关资料
char code NumConver[16]={"0123456789abcdef"};
char code LetterConver[26]={"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};


void  sc_recieve(void);

//------------------------- 用于掉电保护,提醒保存未中继的报警数据到24C04 ------------------------------------
void Int0(void) interrupt 0
{
    Power_Off=1;
    REN=0;
    EX0=0;
}
//------------------------- 用于掉电保护,保存未中继的报警数据到24C04-----------------------------------------


//----------------------------------------定时中断0,发送并口数据----------------------------------------
void int_time_1ms(void) interrupt 1       //total 160T, Max 56T in use,Min 14T,Normal 38T
{
   if(PTN)
     {
        P1=ParData;
        nop; nop; nop;                    //等待数据稳定
        PR1=0;
        nop; nop; nop; nop; nop; nop;  nop;
        nop; nop; nop; nop; nop; nop;  nop;      //等待下位机侧中断
        PTN=0;
        nop;
        PR1=1;
       if(ParData==0x03)  {   nop; nop; nop; nop; nop; nop; nop; nop;
                                  nop; nop; nop; nop; nop; nop; nop; P1=0xff;  }
      }
}
//------------------------------------定时中断0,发送并口数据--------------------------------------

//----------------------------------------外部中断1,接收并口数据----------------------------------------
void parData_Receive(void) interrupt 2  using 3
{
     AnS=0;
     Buf_of_Com2=P1;        nop;
     Buf_of_Com2a=P1;       nop;
     Buf_of_Com2b=P1;
    if(Buf_of_Com2==Buf_of_Com2a)  Buf_of_Com2=Buf_of_Com2a;
       else   Buf_of_Com2=Buf_of_Com2b;
     if(Buf_of_Com2==0x02)   W_P_Data_Buf2=0;
     if(W_P_Data_Buf2==0)
        {
           if(Buf_of_Com2==0x02)
             {    DHead_Arrived=1;
                  Com_Buff[W_P_Data_Buf2]=Buf_of_Com2;
                  W_P_Data_Buf2++;
                 goto L3;
              }
         }
     if((W_P_Data_Buf2>0)&&(W_P_Data_Buf2<32))
         {
             Com_Buff[W_P_Data_Buf2]=Buf_of_Com2;
             W_P_Data_Buf2++;
          }
     if(W_P_Data_Buf2==32)
         W_P_Data_Buf2=0;
L3:  if((Buf_of_Com2==0x03)&&( W_P_Data_Buf2!=0))
        {    DHead_Arrived=0; Com2_Finished=1;  }
           else   AnS=1;
}
//----------------------------------------外部中断1,接收并口数据----------------------------------------


//--------------------------------------定时中断2,使用定时器2-------------------------------------------
void int_time_st(void) interrupt 5   using 2           //1.25ms
{
   Timer_tem++;
   if(Timer_tem>8)
     {
       Timer_tem-=8;
       Timer_tem1++;
     }
    Timer_Over++;
    if (Timer_tem1>100)
         {
            Timer_1s++;
            Timer_dog++;
            Timer_tem1-=100;
            LED=!LED;
         }
     if ((Timer_tem1%16)==0)   Sdog_Feed=1;
     if ((Timer_tem1%16)==1)   Sdog_Play=1;
     if (Timer_1s>59)   { Timer_1m++; Timer_1s-=60; }
     if (Timer_1m>59)   { Timer_1h++; Timer_1m-=60; }
     if (Timer_1h>23)   { Timer_1d++; Timer_1h-=24; }
     if (Timer_1d>29)   { Timer_1d-=30;  }
        TF2=0;
}
//-----------------------------------------定时中断2结束----------------------------------------------------


//------------------------------------串口中断,接收和发送串口数据------------------------------------
void rs_485() interrupt 4   using 1
{
  if(RI)
   {
        sc_recieve();
        RI=0;
   }
   else { Com1Data_Sent=1;  TI=0; }
}
//------------------------------------串口中断,接收和发送串口数据------------------------------------

//------------------------------------------------串口数据接收---------------------------------------------------
void  sc_recieve(void)
  {
     Buf_of_Com1=SBUF;
    if(W_P_Data_Buf1!=0)
        {
           Data_Buf[W_P_Data_Buf1]=Buf_of_Com1;
           W_P_Data_Buf1++;
        }
     if((Buf_of_Com1==0x02)&!Com1_Finished)  W_P_Data_Buf1=0;
     if(W_P_Data_Buf1==0)
        {
           if(Buf_of_Com1==0x02)
             {
                  BroadCasting=0;                      //接收前清零
                  Data_Buf[W_P_Data_Buf1]=Buf_of_Com1;
                  W_P_Data_Buf1++;
              }
         }
    if(W_P_Data_Buf1==32)   W_P_Data_Buf1=0;
    if(W_P_Data_Buf1!=0)
      {
        while(PTN) nop;
        if((PAlarmData!=0)&Ask_for_Alarm&(Buf_of_Com1==0x03))  Buf_of_Com1=0x04;
         ParData=Buf_of_Com1;
         Data_Ver_Send=0;
         PTN=1;
       }                                               //串口1送来数据一律转发给下位机侧
    if(Buf_of_Com1==0x03)
      {                                               //已登陆时收到结束符即认为该数据包有效,
         if((Log_In)|(Data_Buf[1]==Repeater_Address)) //否则只有中继器地址相同时才认为有效
           {
             W_P_Data_Buf1=0;
             Com1_Finished=1;
           }
       }
    if((W_P_Data_Buf1==2)&&((Data_Buf[1]==Repeater_Address)||(Data_Buf[1]==0x01)))
        Com1_deal=1;
    if((W_P_Data_Buf1==3)&&(Data_Buf[2]==0x01))
        BroadCasting=1;                               //上位机对下位机进行广播
    if(Com1_deal)
      {
         if(W_P_Data_Buf1==5)
             {
              if((Data_Buf[3]=='Q')&&(Data_Buf[4]=='?'))   Ask_for_Alarm=1;
              if((Data_Buf[3]=='S')&&(Data_Buf[4]=='?'))   Ask_for_Status=1;
              if((Data_Buf[3]=='?')&&(Data_Buf[4]=='?'))   Ask_for_Alarm=1;
              if((Data_Buf[3]=='L')&&(Data_Buf[4]=='I'))   Log_In=1;
              if((Data_Buf[3]=='L')&&(Data_Buf[4]=='O'))   Log_Out=1;
              Com1_deal=0;
             }
      }
   }
//------------------------------------------------串口数据接收---------------------------------------------------


//------------------------------喂狗程序------------------------------------
void Feed_dog(void)
{
    WDI=!WDI;
}
//------------------------------喂狗程序------------------------------------


//-------------------------------------------发送命令-----------------------------------------
void  Send_command(uchar let1,let2)
  {
     Ask_for_Baud=1;
     Data_Buf[0]=STX;
     Data_Buf[1]=Repeater_Address;
     Data_Buf[2]=0x00;
     Data_Buf[3]=let1;
     Data_Buf[4]=let2;
     Data_Buf[5]=0x30;
     Data_Buf[6]=0x30+baud;
     sum=Data_Buf[0]+Data_Buf[1]+Data_Buf[2]+Data_Buf[3]+Data_Buf[4]+Data_Buf[5]+Data_Buf[6];
  //   for(i=0;i<7;i++) sum+=Data_Buf;
     sum=~sum+1;
     Data_Buf[7]=NumConver[sum/16];
     Data_Buf[8]=NumConver[sum%16];
     Data_Buf[9]=ETX;
     W_P_Data_Buf1=0;
     PTN=0;
     do  {
           ParData=Data_Buf[W_P_Data_Buf1];
           Data_Ver_Send=0;
           PTN=1;    Timer_Over=0;
           while(PTN&(Timer_Over<2))  nop;
           for(i=0;i<2;i++) nop;
           while(!AnS&(Timer_Over<2))  nop;
           W_P_Data_Buf1++;
         }
     while(Data_Buf[W_P_Data_Buf1]!=ETX);
      ParData=Data_Buf[W_P_Data_Buf1];
      Data_Ver_Send=0;
      PTN=1;        Timer_Over=0;
     while(PTN&(Timer_Over<4))  nop;
     for(i=0;i<2;i++) nop;
     while(!AnS&(Timer_Over<4)) nop;
      AnS=0;
     for(i=0;i<2;i++) nop;
      AnS=1;
      W_P_Data_Buf1=0;
  }
//-------------------------------------------发送命令-----------------------------------------

bit Ver_Command(void)
  {
      WDI=!WDI;
      Timer_Over=0;
     while(!Com2_Finished&(Timer_Over<10))   nop;
         if((Com_Buff[3]=='B')&&(Com_Buff[4]=='D'))
          {
            sum=Com_Buff[0]+Com_Buff[1]+Com_Buff[2]+Com_Buff[3]+Com_Buff[4]+Com_Buff[5]+Com_Buff[6];
//         for(i=0;i<7;i++) sum+=Com_Buff;
            if(Com_Buff[7]>96)  Com_Buff[7]-=87; else Com_Buff[7]-=48;
            sum+=Com_Buff[7]*16;
            if(Com_Buff[8]>96)  Com_Buff[8]-=87; else Com_Buff[8]-=48;
            sum+=Com_Buff[8];
            if(sum==0)
             {
                AnS=1;
                Com2_Finished=0;
                W_P_Data_Buf2=0;
               return(0);
             }
           }
         if((Com_Buff[3]=='B')&&(Com_Buff[4]=='K')&&(Com_Buff[W_P_Data_Buf2-1]==ETX))
           {
          sum=Com_Buff[0]+Com_Buff[1]+Com_Buff[2]+Com_Buff[3]+Com_Buff[4]+Com_Buff[5]+Com_Buff[6]+
              Com_Buff[7]+Com_Buff[8]+Com_Buff[9]+Com_Buff[10]+Com_Buff[11]+Com_Buff[12]+Com_Buff[13]+
              Com_Buff[14]+Com_Buff[15]+Com_Buff[16]+Com_Buff[17]+Com_Buff[18]+Com_Buff[19]+Com_Buff[20];
//                for(i=0;i<21;i++) sum+=Com_Buff;
        if(Com_Buff[21]>96)  Com_Buff[21]-=87; else Com_Buff[21]-=48;
          sum+=Com_Buff[21]*16;
        if(Com_Buff[22]>96)  Com_Buff[22]-=87; else Com_Buff[22]-=48;
          sum+=Com_Buff[22];
                if(sum==0)
                  {
                    AnS=1;
                    Com2_Finished=0;
                    W_P_Data_Buf2=0;
                    return(0);
                   }
          }
       AnS=1;
       Com2_Finished=0;
       ET++;
       W_P_Data_Buf2=0;
       return(1);
   }
//-------------------------------------------发送、校验波特率和中继器地址-----------------------------------------


//----------------------------------初始化子程序------------------------------------------
void Init1(void)
{
    EA=0;
    P3=0xff;
    P1=0xff;
    P2=0xff;
    P0=0xff;
    Status1=0;
    Status2=0;
    Status3=0;
    ParData=0;
    SData=0;
    Timer_dog=0;
    Repeater_Address=P0;
    tem_bit=RA_0;  RA_0=RA_7;   RA_7=tem_bit;
    tem_bit=RA_1;  RA_1=RA_6;   RA_6=tem_bit;
    tem_bit=RA_2;  RA_2=RA_5;   RA_5=tem_bit;
    tem_bit=RA_3;  RA_3=RA_4;   RA_4=tem_bit;
    Repeater_Address=~Repeater_Address;
    Repeater_Address+=16;
    baud=P3;
    baud>>=6;
   if((baud==0)|(baud==3))
    {
       PCON&=0X7f;
       TH1 = 0xfd;                  //设置波特率为9.6k
    }
   if(baud==1)
    {
        PCON|=0x80;
        TH1 = 0xfd;                 //设置波特率为19.2k
    }
   if(baud==2)
    {
        PCON|=0x80;
        TH1 = 0xff;                 //设置波特率为57.6k
    }
    SCON=0x50;                   //定义串口使用8位数据,波特率由T1决定的方式
    TMOD=0x22;                   //定义定时器0,1为自动重载的八位计数器
    TH0=0x60;                    //定义T0的溢出时间为160T
    ET0=1;
    TR0=1;                       //开定时器0
    TR1=1;                       //开定时器1
    RCAP2H=0xfb;
    RCAP2L=0x80;
    C_T2=0;
    RCLK=0;
    TCLK=0;
    ET2=1;
    TR2=1;                        //定时器2溢出时间为1.25ms
    ES=1;                         //开窜口中断
    PT0=1;                        //定时中断0中断优先处理
    EX0=1;                        //允许掉电中断
    IT1=1;                        //中断1设为边沿触发方式
    EX1=1;
    PX1=1;
    ET=0;
//    PS=1;
    Timer_tem1=0;
    PAlarmData=0;
//    W_P_Com_Buff=0;
//    R_P_Com_Buff=0;
    W_P_Data_Buf1=0;
    R_P_Data_Buf1=0;
    W_P_Data_Buf2=0;
    R_P_Data_Buf2=0;
    DR1=0;
    for(i=0;i<32;i++)  Com_Buff=0;
    for(i=0;i<32;i++)  Data_Buf=0;
    for(i=0;i<32;i++)  Buf_of_WR=0;
    REN=0;
    EA=1;                        //开中断
  }
//----------------------------------初始化子程序------------------------------------------


//--------------------------24C04的读写操作函数集----------------------------

void start_24(void)                  //提供I2C总线的起使位
{
   scl=1; nop; sda=0; nop ;scl=0; nop; sda=1;
}

void stop_24(void)                   //提供I2C总线的停止位
{
   sda=0; scl=1; nop; sda=1; scl=0;
}

void init_24(void)                   //I2C总线初始化
{
   scl=0;  stop_24();
}

unsigned char read_24(void)
{
    sda=1;
    for(k=0;k<7;k++)
     {
      scl=1; nop; SD_0=sda; nop; scl=0; nop;
      SData<<=1;
     }
    scl=1; nop; SD_0=sda; nop; scl=0; nop;
    scl=1; nop; sda=1;    nop; scl=0;
    return(SData);
}

unsigned char Sread_24(void)
{
    sda=1;
    for(k=0;k<7;k++)
     {
      scl=1; nop; SD_0=sda; nop; scl=0; nop;
      SData<<=1;
     }
    scl=1; nop; SD_0=sda; nop; scl=0; nop;
    sda=0; scl=1; nop;  scl=0;  sda=1;
    return(SData);
}


bit  write_24(unsigned char dd)
{
   bit sample1;
   SData=dd;
   for(k=0;k<8;k++)
    {
       sda=SD_7; nop; scl=1; nop; scl=0; nop;
       SData<<=1;
     }
   sda=1; nop; scl=1; nop; sample1=sda;  nop; scl=0; nop; nop;
   return(!sample1);
}

bit Sread64(unsigned int address)         //读取24C64指定地址的十六字节数据
{
   unsigned char Addr_Hi,Addr_Lo;
   Addr_Hi=(address&0x1fff)/256;
   Addr_Lo=(address&0xff);
   start_24();
    if(write_24(0xa0))
      {  if(write_24(Addr_Hi))
           { if(write_24(Addr_Lo))
               {  start_24();
                  if(write_24(0xa1))
                     {
                        for(i=0;i<31;i++)
                          Buf_of_WR=Sread_24();
                          Buf_of_WR[31]=read_24();
                          stop_24();  return(1);
                      }
                  else { Read_Error=1;  stop_24(); return(0); }
                }
               else { Read_Error=1;  stop_24(); return(0); }
           }
          else { Read_Error=1;  stop_24();  return(0); }
      }
    else { Read_Error=1;  stop_24();  return(0); }
}


/*
unsigned char read(unsigned int address)         //读取24C04指定地址的一字节数据
{
   unsigned char dd,ee;
   dd=((address&0x7ff)/256)<<1;                  //得到块地址
   start_24();
   ee=0xa0|dd;
    if(write_24(ee))
      {  if(write_24(address))
           {
               if(write_24(0xa1|dd))
                 {  dd=read_24(); stop_24(); Read_Error=0; return(dd); }
               else { Read_Error=1;  stop_24(); return(0); }
           }
          else { Read_Error=1;  stop_24();  return(0); }
      }
    else { Read_Error=1;  stop_24();  return(0); }
}
*/
unsigned char read64(unsigned int address)         //读取24C64指定地址的一字节数据
{
   unsigned char Addr_Hi,Addr_Lo,dd;
   Addr_Hi=(address&0x1fff)/256;
   Addr_Lo=(address&0xff);
   nop;
   start_24();
   nop;
    if(write_24(0xa0))
      {  if(write_24(Addr_Hi))
           { if(write_24(Addr_Lo))
               {  start_24();
                  if(write_24(0xa1))
                     {  dd=read_24(); stop_24(); Read_Error=0; return(dd); }
                  else { Read_Error=1;  stop_24(); return(0); }
                }
               else { Read_Error=1;  stop_24(); return(0); }
           }
          else { Read_Error=1;  stop_24();  return(0); }
      }
    else { Read_Error=1;  stop_24();  return(0); }
}

/*
bit write(unsigned int address,unsigned char dd)    //写入24C04指定地址的一字节数据
{
   unsigned char ddd;
    ddd=((address&0x7ff)/256)<<1;
    start_24();
    if(write_24(0xa0|ddd))
      {  if(write_24(address))
            {  if(write_24(dd));  stop_24();
                Timer_Over=0;  while(Timer_Over<10) nop;  return(1);   }
      }
     Write_Error=1;
     stop_24();
     return(0);
}
*/
bit write64(unsigned int address,unsigned char dd)    //写入24C64指定地址的一字节数据
{
   unsigned char Addr_Hi,Addr_Lo;
   Addr_Hi=(address&0x1fff)/256;
   Addr_Lo=(address&0xff);
    start_24();
    if(write_24(0xa0))
      {  if(write_24(Addr_Hi))
          { if(write_24(Addr_Lo))
              {  if(write_24(dd))
                   {  stop_24(); Timer_Over=0;  while(Timer_Over<8) nop; return(1); }
              }
          }
      }
     Write_Error=1;
     stop_24();
     return(0);
}

bit Swrite64(unsigned int address)
{
   unsigned char Addr_Hi,Addr_Lo;
   Addr_Hi=(address&0x1fff)/256;
   Addr_Lo=address&0xff;
          start_24();
        if(write_24(0xa0))
          {  if(write_24(Addr_Hi))
               { if(write_24(Addr_Lo))
                    for(i=0;i<32;i++)
                      { if(!(write_24(Buf_of_WR)))
                          {  stop_24(); return(0); }
                      }
               }
           }
        Write_Error=0;
        stop_24();
        Timer_Over=0;  while(Timer_Over<8) nop;
        return(1);
   }

bit clear(void)
{
   unsigned int Ver1;
   for(i=0;i<16;i++)
     {
       for(j=0;j<32;j++)   Buf_of_WR[j]=0;
        Swrite64(32*i);
        WDI=!WDI;
     }
     Ver1=0;
   for(i=0;i<16;i++)
     {
        Sread64(32*i);
        for(j=0;j<32;j++)   Ver1+=Buf_of_WR[j];
        WDI=!WDI;
     }
   if(Ver1==0) return(1); else return(0);
   }

void SaveTo_24C04(bit First,uchar Location)
   {
    if(First)
      {
        if(Com_Buff[5]==0) Write_Not_Need=1; else  Write_Not_Need=0;
        for(j=0;j<8;j++)
         {
            Buf_of_WR[2*j]=Com_Buff[2*j+5];
            Buf_of_WR[2*j+1]=Com_Buff[2*j+6];
           if(Buf_of_WR[2*j]==0)
            { ExchangeTemp=PAlarmData;  PAlarmData=(32*Location-64)+j+ExchangeTemp;   Alarm_Over=1;   break; }
         }
       }
    else
     {
     for(j=0;j<8;j++)
       {
          if(Alarm_Over) break;
          Buf_of_WR[2*j+16]=Com_Buff[2*j+5];
          Buf_of_WR[2*j+17]=Com_Buff[2*j+6];
         if(Buf_of_WR[2*j+16]==0)
          { ExchangeTemp=PAlarmData;  PAlarmData=(32*Location-64)+j+8+ExchangeTemp;   Alarm_Over=1;  break; }
       }
     if(!Write_Not_Need)  Swrite64(32*Location+ExchangeTemp);
     }
   }
//-----------------------------24C04的读写操作函数集----------------------------


//---------------------------------主程序体-------------------------------------

void main(void)
{
     SP=0X4f;
     Init1();
     init_24();
   if(Sread64(0))
     {
        if(Buf_of_WR[8]!='1'||Buf_of_WR[10]!='1'||Buf_of_WR[19]!='Y')
         {
              OK=clear();
             for(i=0;i<32;i++)   Buf_of_WR=RepeaterVer;   //初使化24C64
              Swrite64(0);
              write64(32,0);
         }
     }
   PAlarmData=read64(32);
   tem_bit=1;
   while(tem_bit)
    {
      nop;
      Send_command('B','D');
      tem_bit=Ver_Command();
    }
    Send_command('O','V');
    for(i=0;i<32;i++)   Data_Buf=0;
    REN=1;
   while(1)
    {
ml:  //  if(Timer_dog>240)   while(1)   //调试时停用
                       nop;          //4分钟内没有检测到上位机巡检则复位

       if(Power_Off)                             //检测到电源电压底的转储过程
         {
           REN=0;
           for(l=0;l<14;l++)
             {
               for(n=0;n<2;n++)
                 {
                    tem_bit=1;
                   while(tem_bit)
                     {
                       Send_command('B','K');            //要求下位机侧将报警信息按16字节(8个报警数据)一组发给上位机侧
                       tem_bit=Ver_Command();
                      }
                    Send_command('O','V');
                    if(n==0)
                         SaveTo_24C04(1,l+2);
                     else
                         SaveTo_24C04(0,l+2);
                  }
                 if(Alarm_Over)  { write64(32,PAlarmData);  break;  }     //写报警数据指针
               }
            while(!PowerTest)  { PowerTest=PTest;    WDI=!WDI;  }         //试图等待电压恢复正常
            while(1) nop;                                                 //复位
           }


        if(Ask_for_Alarm|Ask_for_Status)                                  //上位机报警查询
          {
              Timer_dog=0;
              Timer_Over=0;
            while(!Com1_Finished&( Timer_Over<8)) nop;         //等待上位机发送数据完毕
             if(Com1_Finished) { DR1=1;  Com1_Finished=0; }
             else { Ask_for_Alarm=0; Ask_for_Status=0; goto ml; }
              PAlarmData=read64(32);
            if((PAlarmData==0)|Ask_for_Status)                                   //如果24C04内没有掉电时未来得及中继的数据
             {
               if(Timer_Error>2)    Timer_dog=241;             //下位机侧3次无应答复位中继器
                Timer_Over=0;
               while(!Com2_Finished&( Timer_Over<20)) nop;     //等待下位机侧发送报警数据完毕
                AnS=1;
               if(!Com2_Finished)
                { Timer_Error++;  DR1=0; Ask_for_Alarm=0; P1=0xff; Ask_for_Status=0; goto ml; }
                else { Com2_Finished=0;  Timer_Error=0; }
             }
            else
             {
               AnS=0;
               Com_Buff[0]=STX;
               Com_Buff[1]=Repeater_Address;
               Com_Buff[2]=read64(2*PAlarmData+62);
               Com_Buff[3]='A';
               Com_Buff[4]='L';
               Com_Buff[5]=0x30;
               Com_Buff[6]=read64(2*PAlarmData+63);
               sum=0;
               for(i=0;i<7;i++) sum+=Data_Buf;
               sum=~sum+1;
               Com_Buff[7]=NumConver[sum/16];
               Com_Buff[8]=NumConver[sum%16];
               Com_Buff[9]=ETX;
               W_P_Data_Buf2=10;
             }
              R_P_Data_Buf2=0;   DR1=1;
            while(R_P_Data_Buf2<W_P_Data_Buf2)
             {
                 SBUF=Com_Buff[R_P_Data_Buf2];
               //  Timer_Over=0;
                while(!Com1Data_Sent) nop;
                 Com1Data_Sent=0;
                 R_P_Data_Buf2++;
              }
          if(PAlarmData!=0)
           {
             PAlarmData--;
             write64(32,PAlarmData);
           }
            R_P_Data_Buf2=0;
            W_P_Data_Buf2=0;
            AnS=1;
            DR1=0;
            if(Ask_for_Alarm) Ask_for_Alarm=0;  else Ask_for_Status=0;
          }

          if(Log_Out&!Log_In)                 //防止Log_Out标志位干扰程序运行
            {
               Log_Out=0;
              while(!Com1_Finished)  nop;
               Com1_Finished=0;
            }
            
          WDI=DogHand;

          if(Log_In)                            //上位机登陆到下位机
             {
L1:              Timer_Over=0;
               while(!Com1_Finished)            //等待上位机发送数据完毕
                 {
                     nop;
             //      if(Timer_Over>40) break;
                 }
                Com1_Finished=0;
               if(Log_Out|BroadCasting)
                 {
                    BroadCasting=0;
                    Log_In=0;
                    Log_Out=0;
                    goto  L2;
                  }
                Timer_Over=0;
              while(!Com2_Finished)            //等待下位机侧发送数据完毕
                 {
                   if(!DHead_Arrived&(Timer_Over>20))  { Log_In=0; goto L2; }     //25mS收不到起始符退出
                   if(DHead_Arrived&(Timer_Over>60))   { Log_In=0; goto L2; }     //75mS左右收不到结束符退出
                   if(Com1_Finished)                   { Log_In=0; goto L2; }     //在等下位机响应时,上位机可要求中断
                 }
                DR1=1;
                Com2_Finished=0;
                R_P_Data_Buf2=0;
              while(R_P_Data_Buf2<W_P_Data_Buf2)
                {
                   SBUF=Com_Buff[R_P_Data_Buf2];
                    Timer_Over=0;
                  while(!Com1Data_Sent&(Timer_Over<2)) nop;
                   Com1Data_Sent=0;
                   R_P_Data_Buf2++;
                }
                   R_P_Data_Buf2=0;
                   W_P_Data_Buf2=0;
                   AnS=1;
                   Feed_dog();
                   DR1=0;
                  goto L1;
                   nop;
       L2:         nop;
               }


          }                 //End   while(1)
}                      //End   main()


//--------------------------------主程序体结束-------------------------------------

一周热门 更多>