×
单片机 > 单片机程序设计 > 详情

c51 串口连接接收与发送

发布时间:2020-06-08 发布时间:
|

调试通过。

 

#include
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define Fclk  11059200UL   /*使用11.0592M体*/
#define BitRate   9600UL       /*波特率定义为9600*/


#define DEBUG0

sbit sda= P1^2;              //2ic串行数据
sbit scl= P1^5;              //2ic串行时钟
sbit WP = P3^2;              //2ic硬件写保
sbit a0=ACC^0;
sbit a1=ACC^1;
sbit a2=ACC^2;
sbit a3=ACC^3;
sbit a4=ACC^4;
sbit a5=ACC^5;
sbit a6=ACC^6;
sbit a7=ACC^7;

sbit led_g= P3^4;          //red led
sbit led_r= P2^3;          //green led
sbit kr   = P2^1;          //kr  
    
void outChar(uchar c);
void outStr(uchar *buf,uchar len);

uchar xKey;
uint  Life;
uint  KB_Life;

uchar recvBuf[16+6];
uchar exeCmd;
uchar sendBuf[16+6];


unsigned  char checksum,count3;
bit read_flag=0;

volatile  uchar Sending ;
volatile  uchar  Accepting ;
volatile  uchar  len,temp,i;
volatile  unsigned int j;

//延时10微秒(包括调用和返回的时间),base=12M
void Delay(void)
{
   P3_5 = ~P3_5;
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
}
/*********************************************************
*        AT24C01读写函数                                 *
**********************************************************/
void Start(void) //起始条件
{  
 scl=0;
 sda=1;
 scl=1;
 sda=0;
 scl=0;
}
void Stop(void)  //停止条件
{   
 scl=0;
 sda=0;
 scl=1;
 sda=1;
 scl=0;
}
void WaitAck(void)
{
   scl=0;
   sda=0;
   scl=1;
   scl=0;
   sda=1;
}
void Ack(void)   //应答位
{
   scl=0;
   _nop_();
   scl=1;
   _nop_();
   scl=0;
   _nop_();
   sda=1;
   _nop_();
}
void NoAck(void) //反向应答位
{
   scl=0;
   sda=1;
   scl=1;
   scl=0;
   sda=1;
}
uchar Read(void) //读一个字节的数据,并返回该字节值

 scl=1;_nop_();_nop_();_nop_();
 a7=sda;_nop_();_nop_();scl=0;_nop_();sda=1;_nop_();scl=1;_nop_();_nop_();
 a6=sda;_nop_();_nop_();scl=0;_nop_();sda=1;_nop_();scl=1;_nop_();_nop_();
 a5=sda;_nop_();_nop_();scl=0;_nop_();sda=1;_nop_();scl=1;_nop_();_nop_();
 a4=sda;_nop_();_nop_();scl=0;_nop_();sda=1;_nop_();scl=1;_nop_();_nop_();
 a3=sda;_nop_();_nop_();scl=0;_nop_();sda=1;_nop_();scl=1;_nop_();_nop_();
 a2=sda;_nop_();_nop_();scl=0;_nop_();sda=1;_nop_();scl=1;_nop_();_nop_();
 a1=sda;_nop_();_nop_();scl=0;_nop_();sda=1;_nop_();scl=1;_nop_();_nop_();
    a0=sda;_nop_();_nop_();scl=0;_nop_();_nop_(); sda=1;_nop_();_nop_(); 
 return(ACC); 
}
void Send(uchar Data)  //发送数据子程序,Data为要求发送的数据
{
 ACC=Data;
 scl=0;
 sda=a7;_nop_();_nop_();scl=1;_nop_();_nop_();scl=0;_nop_();_nop_();
 sda=a6;_nop_();_nop_();scl=1;_nop_();_nop_();scl=0;_nop_();_nop_();
 sda=a5;_nop_();_nop_();scl=1;_nop_();_nop_();scl=0;_nop_();_nop_();
 sda=a4;_nop_();_nop_();scl=1;_nop_();_nop_();scl=0;_nop_();_nop_();
 sda=a3;_nop_();_nop_();scl=1;_nop_();_nop_();scl=0;_nop_();_nop_();
 sda=a2;_nop_();_nop_();scl=1;_nop_();_nop_();scl=0;_nop_();_nop_();
 sda=a1;_nop_();_nop_();scl=1;_nop_();_nop_();scl=0;_nop_();_nop_();
 sda=a0;_nop_();_nop_();scl=1;_nop_();_nop_();scl=0;_nop_();_nop_();
}
void RdFromROM(uchar *Data,uchar Address,uchar Num)
{
   uchar i;
   
   Start();
   Send(0xa0);    //读操作
   Ack();
   Send(Address); //读的地址
   Ack();
   
   Start();
   Send(0xa1);
   Ack();

   for(i=0;i   { 
      Data[i]=Read(); 
      WaitAck();          
   }   
   NoAck();
   Stop();
}
void WrToROM(uchar *Data,uchar Address,uchar Num)
{
   uchar i;

   Start();
   Send(0xa0);    //写操作 
   Ack();

   Send(Address);//写的地址
   Ack();
   
   for(i=0;i   {
   Send(Data[i]);
      Ack();
   }   
   Stop();
   Delay();
   Delay();
   Delay();
}

/***********************************************************************/
//初始化串口通讯参数 
void InitialUart()   
{
   PCON = 0x00;   
   TMOD = 0x21;     
   TH0 = 0x52;   //0x4c;
   TL0 = 0x00;   //0x00;
   TR0 = 1;      //开启定时器
   ET0 = 1;      //开启定时器1的中断
 /*
   TH1  = 0xFD;   //Baud:9600  fosc=11.0592MHz
   TL1 = 0xFD; 
   TR1  = 1;      //启动定时器1   
   SCON = 0x50;   //串口工作模式为1,允许接收串行数据          
   ES = 1;        //开启串口中断

   EA = 1;        //开启中断
 */
 EA=0; //暂时关闭中断
 TMOD&=0x0F;  //定时器1模式控制在高4位
 TMOD|=0x20;    //定时器1工作在模式2,自动重装模式
 SCON=0x50;     //串口工作在模式1
 TH1=256-Fclk/(BitRate*12*16);  //计算定时器重装值
 TL1=256-Fclk/(BitRate*12*16);
 PCON|=0x80;    //串口波特率加倍
 ES=1;         //串行中断允许
 TR1=1;        //启动定时器1
 REN=1;        //允许接收 
 EA=1;         //允许中断
 PS=1;
 }

//向串口发送一字符   
/*
void OutChar(uchar c)
{
   SBUF=c;
   while(TI==0);
   TI=0;
}
*/
void OutChar(uchar c)
{
   SBUF=c;
   Sending=1;
   while(Sending);
}

 

void OutStr(uchar *buf,uchar len)
{
   uchar i;
   uchar check = 0x00;
   OutChar(buf[0]);
   for(i=1;i   {
      OutChar(buf[i]);
   check ^= buf[i];
   }
   OutChar(check);
}

/**************************************  
*功能: 串口中断函数                  *
**************************************/
void UartISR(void) interrupt  4     using 3
{
 //  uchar len, i;
 //  unsigned int j=0;
   if(RI)
   { 
     RI=0;
  if(!read_flag)
  {
   len=SBUF;
   recvBuf[0]=len;
   read_flag=1;
  }
  else
  {
     ++i;
     recvBuf[i]=SBUF;
    if(i==len)
    {
        exeCmd = 1;
        read_flag=0;
     i=0; 
    }
   
     }   
   /*
    SCON =0x40;     //接收不允许
          tChar(0x88);    //发送数据
     OutChar(len);
       OutChar(recvBuf[0]);
         OutChar(recvBuf[1]);
      OutChar(recvBuf[2]);
      OutChar(recvBuf[3]);
      OutChar(0x88);
      OutChar(0x68);
                     
     outStr(sendBuf,len);
         SCON =0x50;     //接收允许
 */
   }
  else
  {
   TI=0;
 Sending=0;
   }

}

 

/*
void COMISP(void) interrupt 4 
{
   uchar len, i;
   unsigned int j=0;
   if(RI)
   {  
  len=SBUF;
  recvBuf[0] = len;
  RI=0; 
  for(i=0;i  {
   while(!RI)
   {
    j++;
    if(j>1000)  break;
   }
   if(j<1000)
   {
    recvBuf[i+1]=SBUF;
    RI=0;
     j=0;
   }
   else
   {
       break;
   }
  }
  if(i==len)
  {
     exeCmd = 1; 
  }
 }
}
*/

 

/*时间中断*/
void Timer1ISR (void) interrupt 1 using 3
{
 TH0 = 0x52; //0x4c;
 TL0 = 0x00; //0x00;

 if(Life>0)
 {
  Life --; 
       //kr = 0x01;
 }
 
 if(0==Life)
 {
    if(0==KB_Life)
    {
   kr = 0x00; //开继电器
      led_g = 0;
    }
    KB_Life ++;
    if(KB_Life>100)
    {
        kr = 0x01; //关继电器
     led_g = 1;
     Life  = 6000;
        KB_Life=0;
    }
 }
}
//通讯接口处理
void CommPress()
{
   uchar check; //校对码
   uchar i;

   if(!exeCmd) return;
   exeCmd = 0;
   //起始字是否正确
   if(0x0b != recvBuf[1])
   {
      OutChar(0x30);
   return;           
   }
   //校验符是否正确
   check = 0x00;
   for(i=1;i   if(check!=recvBuf[recvBuf[0]])
   {
      OutChar(0x31);
   return;
   }
   switch(recvBuf[2])
   {
   case 0x01 : //版本
     sendBuf[0] = 12;
     sendBuf[1] = 0x0B;
     sendBuf[2] = 0x01;
     sendBuf[3] = 0x30;
     strcpy(sendBuf+4,"09110803");
     outStr(sendBuf,12);        
      break;
   case 0x61:  //设置因子
   //Life = abcd
   break;
   case 0x62: //读取生命
     sendBuf[0] = 6;
     sendBuf[1] = 0x0B;
     sendBuf[2] = 0x62;
     sendBuf[3] = 0x30;
     sendBuf[4] = Life / 255;
     sendBuf[5] = Life % 255;
     outStr(sendBuf,6);
   break;
   case 0x63: //写入生命
        Life = recvBuf[3] *255+ recvBuf[4];
      break;
      case 0x71 : //读24c01
           sendBuf[0] = 6+recvBuf[4];
     sendBuf[1] = 0x0B;
     sendBuf[2] = 0x71;
     sendBuf[3] = 0x30;
     sendBuf[4] = recvBuf[3]; //address
     sendBuf[5] = recvBuf[4]; //length
     RdFromROM(sendBuf+6,recvBuf[3],recvBuf[4]);
     outStr(sendBuf,6+recvBuf[4]);
      break;
      case 0x72 : //写24c01 
     WrToROM(recvBuf+5,recvBuf[3],recvBuf[4]);
     sendBuf[0] = 6;
     sendBuf[1] = 0x0B;
     sendBuf[2] = 0x72;
     sendBuf[3] = 0x30;
     sendBuf[4] = recvBuf[3]; //address
     sendBuf[5] = recvBuf[4]; //length
     outStr(sendBuf,6);
      break;
      case 0x81:  //绿灯
        led_g = recvBuf[3];
      break;      
      case 0x82:  //红灯
           led_r = recvBuf[3];
      break;
      case 0x83:  //继电器
        kr = recvBuf[3];
     led_r = 0;
      break;
   }
}

main()
{
  exeCmd = 0;
  WP=0;
  Life = 6000;
  KB_Life = 0;
  InitialUart();
  i=0;
  j=0;

#ifdef DEBUG0
OutChar(0x67);
sendBuf[0] = 6;
sendBuf[1] = 0x0B;
sendBuf[2] = 0x72;
sendBuf[3] = 0x30;
sendBuf[4] = 0x44;
sendBuf[5] = 0x55;
outStr(sendBuf,6);
#endif

//led_g = 0;
  led_r = 0;
 
  while(1)
  {
     P3_5 = ~P3_5;
  CommPress();
  }
}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32 USB HID 键盘