⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zhukong.c

📁 单片机485通信及驱动T6963控制器
💻 C
字号:
/**************************************************************************************/
/*                                主控单片机                                          */
/*                          功能1  :主控单片机与PC串口通信                           */
/*                          功能2  : 主控单片机与从机485总线通信                      */
/*                          功能3  : 主控单片机液晶显示                               */
/*                          Author : 蒋铃锋                                           */
/*                          日期   : 2005.10.27                                       */
/**************************************************************************************/

#include <W77C32.H>

#define uchar unsigned char
#define uint unsigned int

sbit RTS=P1^0;
bit TFF0=0;
///////////////////////////////////////////////////////////////////////////////

void init(void) ;
void IFready(void);
void send(void);
void delay1S(uchar time);

/////////////////////////////////////////////////////////////////////////////////
void F_data(unsigned char addr,unsigned char *buff);
void Time0(void);
void delay(unsigned int i);
void delay1(unsigned int i);

unsigned char buff[4]={0};
/////////////////////////////////////////////////////////////////////////////



uchar receive0=0xAA;   //接收PC机的请求发送
uchar idata send0[3]={0xBB,0xBB,0xBB};  //发送给PC机的确认
uchar idata send1[3]={0xAB,0xAB,0xAB};  //数据的起始位
uchar idata send2[2]={0x00,0x00};    //数据的结束位
uchar xdata senddata[24][3];

uint sum=0;                  //所有数据位的和
uchar  parity=0;                //校验位




void main()
{
uchar i,j;
uchar MA_NUM;     //机号0-23
uchar MA_ADDR;     //从机硬件地址
uchar temp;

init();

for (i=0;i<24;i++)            //初始化数据区
for (j=0;j<3;j++)
{senddata[i][j]=0;}

while(1)
  {
   for (MA_NUM=0;MA_NUM<24;MA_NUM++)          //采集所有从机(24台)的数据
  {  temp=MA_NUM<<3 ;
     MA_ADDR=(temp|0x07) ;       ////计算从机硬件地址  P2口为硬件地址

     for(i=0;i<4;i++)
       buff[i]=0;               //初始化缓冲区

   F_data(MA_ADDR,buff);

   for(i=0;i<3;i++)
  senddata[MA_NUM][i]=buff[i];    //采集第MA_NUM台从机数据 ,只需前3 个字节
                                   //第4个字节为校验位,如果没收到数据,则为0
    }
    
IFready();
send();
delay1S(1);     //延时1秒
 }
} 

void init(void)
{
RCAP2H=0xff;  RCAP2L=0xb2;           //(RCAP2H,RCAP2L)=0xff64  4800波特  (RCAP2H,RCAP2L)=0xffB2  9600波特
TH2=0xff;     TL2=0xb2;              //T2波特率计算公式:晶振频率/(32*(65536-(RCAP2H,RCAP2L))

T2CON=0x30;   //用定时器2做串口0的波特率发生器
TCLK=1;       //T2发送时钟标志
RCLK=1;      // T2接收时钟标志

TR2=1;       // 打开T2中断
REN=1;       //打开串口0接收功能
PCON=0x00;   //SMOD=0;波特率不加倍
//SM0=0;
SM1=1;       //模式1
//SM2=0;
//ES=1;       //打开串行口0中断   ????? 如果用查询方式收,则=0 ?????
EA=1;       //打开所有中断?????????????????????????????????????????
ET2=0;      //关闭T2的中断
PMR|=0x01;  //使用片上SRAM

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
 TMOD=0x21;            //定时器0,方式1 定时器2,方式2
 TH1=0XFB;
 TL1=0XFB;
 //TH1=0Xe6;
 //TL1=0Xe6;
 TH0=-60000/256;       //定时30MS
 TL0=-(60000%256);
 PCON=0X00;
 TR1=1;
 SCON1=0XD8;            //TB8=1;  sm2=0;
// EA=1;
 ET0=1;                //使能T0定时器中断
 ET1=0;               //关断T1中断
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

}

void IFready(void)
{ uchar i;
  //uchar test;
 do{
   if(RI==0)
   {for (i=0;i<3;i++)
     {SBUF=send0[i];
      while(TI==0);
      TI=0;       //是否发送完一个字节
      }
     delay1S(1);
      }
   //while(RI==0);
  else
   RI=0;           //是否接收到一个字节
         }while((SBUF^receive0)!=0); //PC 机未准备好
}


void send(void)                //PC机准备好
{uchar i;
 uchar j;
 uchar temp=3;
// uchar xdata senddata[24][3];

for(i=0;i<3;i++)               //发送起始位
{SBUF=send1[i];
while(TI==0);TI=0;
}

delay1S(1);

PMR|=0x01;

/*for(i=0;i<24;i++)
for(j=0;j<3;j++)
{
senddata[i][j]=temp;
temp++;
}              */


for(i=0;i<24;i++)            //发送数据位
for(j=0;j<3;j++)
{
SBUF=senddata[i][j];
sum+=senddata[i][j];
while(TI==0);TI=0;
}

parity=sum%256;
sum=0;               //发送校验位
SBUF=parity;
while(TI==0);TI=0;

for(i=0;i<2;i++)               //发送结束位
{SBUF=send2[i];
while(TI==0);TI=0;
}


}

void delay1S(uchar time)       //time为所需延时的秒数
{

 unsigned char num0;
 unsigned char num1;
 unsigned char num2;
 unsigned char temp;

for(temp=0;temp<time;temp++)
for(num0=100;num0>0;num0--)
for(num1=147;num1>0;num1--)
for(num2=200;num2>0;num2--)
{}
}



 //////////////////////////////////////////////////////////////////////////////////////////////////////
  void F_data(unsigned char addr,unsigned char *buff)
{
   int i,A_sign=0;
   RTS=0;         //主机抢总线,发送地址信息
   delay(1);       //延时1ms
   SBUF1=addr;
   while(TI_1!=1);
   TI_1=0;
   delay1(2);     //延时2位波特率时间160微秒
   RTS=1;         //放总线


   while(RI_1!=1)   //2.接收从机发回的地址确认信号
  {
    TR0=1;
    if(TFF0==1)      //如果从机30MS不回发确认信息,强制退出,进入下一从机
    {
     RI_1=0;
     TR0=0;
     TFF0=0;
     TH0=-60000/256;
     TL0=-(60000%256);
     return;
    }
    }
    RI_1=0;
    delay1(2);
    TB8_1=0;         //以下发送均为数据信息
    TR0=0;
    TH0=-60000/256;
    TL0=-(60000%256);
    if(SBUF1!=addr)         //如果从机回复地址有误,主机强制该从机复位,进入下一从机
      {
        RTS=0;         //主机抢总线,发送地址信息
        delay(1);       //延时1ms
        SBUF1=0XFF;
        while(TI_1!=1);
        delay1(2);
        TI_1=0;
        TB8_1=1;
        return;    //////////////
      }
       else
       {
        RTS=0;         //主机抢总线,发送地址信息
        delay(1);       //延时1ms
        SBUF1=0x00;
        while(TI_1!=1);
        delay1(2);
        TI_1=0;
        }
        RTS=1;        //放总线

      for(i=0;i<3;i++)
      {
        while(RI_1!=1)   //2.接收从机发回数据
        {
           TR0=1;
           if(TFF0==1)      //如果从机30MS不回发确认信息,强制退出,进入下一从机
            {
               RI_1=0;
               TR0=0;
               TFF0=0;
               TH0=-60000/256;
               TL0=-(60000%256);
               TB8_1=1;              //置地址信息
               return;
            }
         }
       RI_1=0;
       delay1(2);
       TR0=0;
       TH0=-60000/256;
       TL0=-(60000%256);
      *(buff+i)=SBUF1;
      }
       while(RI_1!=1)   //接收从机发回校验信号
        {
           TR0=1;
           if(TFF0==1)      //如果从机30MS不回发确认信息,强制退出,进入下一从机
            {
               RI_1=0;
               TR0=0;
               TFF0=0;
               TH0=-60000/256;
               TL0=-(60000%256);
               return;
            }
       }
       RI_1=0;
       delay1(2);
       TR0=0;
       TH0=-60000/256;
       TL0=-(60000%256);
      *(buff+3)=SBUF1;
       if(*(buff+3)!=(*(buff+2)+*(buff+1)+*(buff))%0X100)
       {
         A_sign=1;
       }
        TB8_1=1;                //置地址信息
       return;
  }

 void Time0(void) interrupt 1 using 2     //定时器0中断程序
 {
 //tim++;
 //if(tim%8==0)
  TFF0=1;
 }

void delay(unsigned int i)     //延时ims
 {
  i=i*1000;
  while(i--);
 }

 void delay1(unsigned int i)    //延时i个波特率时间80微秒
 {
  i=i*260;
  while(i--);
 }
///////////////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -