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

📄 51串口协议.c

📁 自己编的C51串口
💻 C
字号:
#include   <reg51.h>  
#include   <stdio.h>   


unsigned char Fun01_Len = 5; 
unsigned char Fun05_Len = 6; 
unsigned char *P1Addr;        
unsigned char SendBuf[5];  
unsigned char RcvBuf[16];      

void UART_Init()
{
 SCON = 0x50;  //选择工作方式一,并允许接收
 //PCON = 0x80;  //SMOD为1
 REN = 1;
 RI = 0;
 TI = 0;
}

void timer_Init()
{
 TMOD |= 0x20;  //选择定时器一,方式二工作
 TH1 = 0xfa;    //24MHz  9600波特率      TH1 = 256 - 24M/(32*12*9600);
 TL1 = 0xfa;
 TR1 = 1;       //开始计时
}

void system_Init()
{
 UART_Init();
 timer_Init();
}

void UART_Rcv()
{
                                     
 unsigned char i = 0;     
 while(!RI);  //允许接收位为0,等待
 RcvBuf[i++] = SBUF;    //此时接收到的是设备地址
 RI = 0;      //硬件自动置1,所以要把它清0
       
 if(RcvBuf[0] == 0x01)  //如果从机地址吻合,则继续执行,否则什么也不干
 {      
  while(!RI);
  RcvBuf[i++] = SBUF;   //此时接收到的是功能代码,包括(01、03、05、16)
  RI = 0;
  if(RcvBuf[1] == 0x01) //当前为读线圈命令,即读取P1口状态的命令
  {     
   while(i   < Fun01_Len)
   {
    while(!RI);
    RcvBuf[i++] = SBUF;
    RI = 0;
   }
   //此时,RcvBuf里面装的是01功能的一个数据帧,接下来应该对这些数据进行分析
  }
  else if(RcvBuf[1] == 0x05) //当前为更新P1口状态命令
  {     
   while(i   < Fun05_Len)
   {
     while(!RI);
    RcvBuf[i++] = SBUF;
    RI = 0;
   }
   //此时,RcvBuf里面装的是03功能的一个数据帧,接下来应该对这些数据进行分析 
  }
 }

}

void UART_Send() //由于对于03功能发送的前面5位都是固定的,所以可以先发出去
{
 unsigned char i = 0;
 while(i   < 5)
 {
  SBUF = SendBuf[i++];
  while(!TI);
  TI = 0;
 }
}

void process()        
{          
 unsigned char i;    
 SendBuf[0] = RcvBuf[0];        
 SendBuf[1] = RcvBuf[1];   
        
 //判断各种情况
 if(RcvBuf[0] == 0x01 && RcvBuf[1] == 0x01) //表示为当前设备,且功能码为01读P1口状态
 {
  SendBuf[2] = 0x01;
  P1Addr = (char *)P1;       
  SendBuf[3] = *P1Addr;            //一个字节为P1口的值
  SendBuf[4] = *P1Addr;         //一个字节数的CRC低字节就为本身
  SendBuf[5] = 0x00;          //高位为00
  for(i= 0; i  <6; i++)
  {
   //SBUF = 0x00;
      //while(!TI);
   //TI = 0;
   SBUF = SendBuf[i];
   while(!TI);
   TI = 0;
  }
 }           
 else if(RcvBuf[0] == 0x01 && RcvBuf[1] == 0x05) //表示为当前设备,且功能码为05更新P1口的值
 {       
  i = 0;
  while(i   < Fun05_Len)
  {
   //SBUF = 0x00;
   //while(!TI);
   //TI = 0;       
   SBUF = RcvBuf[i];  //05更新P1口值功能发送和接收时的格式是一致的,而且固定。(可省略CRC校验)
   //printf("RcvBuf[%d]: %bx\n",i,RcvBuf[i]);
   //printf("%bx\n",SBUF);
   while(!TI);
   TI = 0;
   i++;
  }
 }
}

void main()
{      
 system_Init();
 while(1)
 {
  UART_Rcv();
  process();
 }
}

⌨️ 快捷键说明

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