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

📄 serial.c

📁 rs485串口通讯程序,对大家很有帮助,
💻 C
字号:

#include <reg52.h>
#define uchar  unsigned char

bit receive;  //接收标志
bit re_finish;//接收一串字符完成标志
sbit lck = P3^5;//HC574锁存信号
sbit LED = P1^3;//串口通信指示
sbit addr0 = P1^4;//系统片选地址线0
sbit addr1 = P1^5;//系统片选地址线1
sbit addr2 = P1^6;//系统片选地址线2
sbit addr3 = P1^7;//系统片选地址线3

uchar  i,buffer[8];//串口缓冲区
uchar  cash[8];    //数码管显示缓冲区
uchar  sbuffer,number;//发送字符个数
uchar  sendFINS ;  //发送完成标志
uchar  copyOK , cmd_numb ;//发送缓冲区填充完成标志

//数码管位扫描数据
uchar code scan[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//row0--row7

//数码管数字码表

uchar code table[18] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,//0,1,2,3,4,5
                       0x82,0xf8,0x80,0x90,0x88,0x83,//6,7,8,9,a,b
                       0xc6,0xa1,0x86,0x8e,0xbf,0xff};//c,d,e,f,-,空格

void  delay(unsigned int loop); //延时函数声明


/********************************系统初始化函数************************/

void initial(void)
{  uchar j;
  
   
   SCON=0x50;           //串口工作方式1,允许接收
   PCON=0x80;           //波特率翻倍
   TCON=0;              
   TMOD=0x26;           //T1用于串口波特率控制
   TL1=0xfa;            //初始化T1,波特率为9600(晶振11.0592M)
   TH1=0xfa;                    
   TR1=1;               //开定时器
   EA=1;                //开总中断
   ES=1;                //开串口中断
   copyOK = 0;         //缓冲区准备好标志清零
   receive = 0;        //接收标志清零
   re_finish = 0;      //接受完成标志清零
   cmd_numb = 0;       //接受计数器清零
   P1 = 0xb0;           //RS485允许接收
  for(j=0; j<8; j++)   //串口缓冲区清空
      buffer[j] = 17;  //table[18]为空显示   
  for(j=0; j<8; j++)   //串口缓冲区清空
      cash[j] = 17;  //table[18]为空显示 
  cash[0] = 15;   
 }                        


/************************向串口发送字符串*************************/

void  send(void)
 { 
   P1 = 0xf0;
   if(copyOK)  //串口准备好且缓冲区准备好
    { 
     i = 0;                 
     REN = 0;               //发送过程中禁止接收数据
     copyOK = 0;            //清缓冲区准备好标志
     SBUF = cash[i++];      //发送字符串首字符
     number = 7;            //置发送计数器
      }
   else
       return;              //没准备好则返回
  }


/*****************************串口中断响应处理函数***********************/

void serial(void) interrupt 4
{  uchar k;
  if(RI)//为接收中断
     {      
      RI=0;                                         //清接收中断标志
       LED = ~LED;                                  //闪串口指示LED
      sbuffer = SBUF;                               //读取串口缓冲区数据

      if((sbuffer == 's') && (receive == 0))       //判断是否为数据头 ,是数据头则准备接收
       {     
           receive = 1;     //开始接收标志                         
           cmd_numb = 0;    //清接收计数器
           re_finish = 0;   //清接收完成标志
          }
      else if(sbuffer == 'e')   //判断数据尾     
        { 
          if(cmd_numb<8)//接收到的字符少于8个
            for(k=cmd_numb;k<8;k++)//则空位填空显示
              buffer[k] = 17;
          re_finish = 1;         //置接收完成标志      
          receive =0;            //清接收标志
          }
      else if(receive){     //判断当前是否处于接收状态
                   
          buffer[cmd_numb++] = sbuffer-'0';  //当前字符送缓冲区
         }      
      else                    //无效命令则返回
         return;
       }
    else{ 
     TI=0;                   //为单个字符发送完中断
     if(!number)             //字符串发送完
      { REN = 1;             //单片机允许接收
        P1 = 0xbf;           //RS485允许接收
       }
     else{                  //字符串未发送完
        SBUF =  cash[i++];   //发送下一字符
		number--;           //发送字符数减一
       }             
     }
   }

/*****************************延时函数**********************/
void  delay(unsigned int loop) 
{  unsigned int i ;          //loop 为执行空指令的次数,改变它可一改变延时时长
  for(i=0;i<loop;i++);      //循环执行空指令loop次,达到延时目的
 }


/******************************数码管显示扫描*************************/

void ledscan()
{  uchar i;  

    for(i=0;i<8;i++){
       P2 = 0xff;//关闭所有数码管
       addr3 = 0;
       addr0 = 0;
       addr1 = 1;
       addr2 = 0;//开发板上U4(74HC574)的片选地址
       P0 =table[cash[i]]; //取一行显示数据 
       addr3 = 1; 
       addr3 = 0;//在U4的11脚(锁存信号)产生上升沿
       P2 = scan[i];//取row0--row7行扫描数据
       delay(50); //延时50us
       }
 }

/********************************主函数****************************/

main()
{
  initial(); 
  while(1){//主循环
    if(re_finish){//把串口缓冲区的内容送到显示缓冲区    
    cash[0] = buffer[0];
    cash[1] = buffer[1];
    cash[2] = buffer[2];
    cash[3] = buffer[3];
    cash[4] = buffer[4];
    cash[5] = buffer[5];
    cash[6] = buffer[6];
    cash[7] = buffer[7];
    re_finish = 0;//接收完成标志
    copyOK=1;//发送缓冲区填充完成标志
    send();  //把显示缓冲区的内容发送给电脑
    }
   ledscan(); //循环扫描数码管   
   }
 }
/**********************************结束****************************/

⌨️ 快捷键说明

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