89C51串口通信时钟


实验目的

  1. 了解单片机串口通信基本原理
  2. 掌握串口中断与定时中断编写以及工作模式原理
  3. 掌握串口收发寄存器的使用

实验要求

  1. 通过电脑下发指令给单片机
  2. 若为 ‘0x01’ 指令,单片机将8位数码管全部显示为0
  3. 若为 ‘0x02’ 指令,8位数码管显示当前时间
  4. 每过一分钟,单片机向电脑报告当前时间
  5. 电脑可以下发指令设置时间

所用工具

  1. Keil uVision4 编译软件
  2. stc-isp 串口助手
  3. Proteus 8 仿真软件
  4. Configure Virtual Serial Port Driver 虚拟串口工具

具体实现代码

#include <reg51.h>  //头文件
#include <string.h>// 引用字符串比较函数


unsigned char segdata[10] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 段码表
unsigned char bitdata[8] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};  //位选
unsigned char tempdata[8];   
unsigned char temp[18]={0}; //数据接收缓存区
unsigned int index=0;
unsigned char ch,biao;  //接收数据标志位biao  ch数据接收字节
    
unsigned char shi = 12;  //时
unsigned char fen = 1;  //分
unsigned char miao = 56;  //秒

unsigned char hour,min,sen; 
unsigned char flag=0,flg=0,count=0;  //flag 点闪标志  flg 一分标志位 count计数 
static int a; 
//延时
void delay_us(unsigned long i){
    
    while(i--);
}

//显示
void display()
{
       unsigned char i = 0; 
            for(;i<8;i++){    
         P2=bitdata[i];    
       P1 = tempdata[i];            
         delay_us(100);    
    }
}
 
//清除函数
void clean(){
    unsigned char k;
    for(k=0;k<index;k++){
        temp[k]=0;
        index=0;
    }
    
}
 
//头部比较
int  compared_head(char cmd_head[])    
 {
     unsigned char m;
     for(m=0;m<4;m++) { 
     
         if(!(temp[m+1]==cmd_head[m]))
         {
             return 0;  
         }
             }
    return 1;      
 }
 
//帧尾比较
int Compare_end(unsigned char start,unsigned char num,char end[]) 
{
     unsigned char n;
     for(n=0;n<num;n++)
     {
         if(!(temp[start+n]==end[n]))
         {
            return 0; 
         }
     }
     return 1;
 }
 
//数据处理
int infodata(){
    
    if(temp[0]=='$'){
        if(compared_head("set:")){

                    if(temp[7]=='-'){

                                if(temp[10]=='-'){

                                            if(Compare_end(13,5,"clock")){
                                return 1;
                        }
                    }}}}                    
                        return 0;                            
}


//串口初始化
void uart_init()
{
       SCON = 0x50;
       TMOD |= 0x20;
         PCON=0x00;
       TH1 =TL1=0xfd;  
       TR1 = 1;
         ET1=0;
        EA = 1;
        ES = 1;
    
}
//发送一个字节
void uart_send_byte(unsigned char byte)
{
       SBUF = byte;
       while(!TI);
       TI = 0;
}
//发送一个字符串
void uart_send_str(unsigned char *s)
{
       while(*s != '\0') 
         {
                uart_send_byte(*s);
                s++;
     }     
}
//串口中断函数
void uart_isr() interrupt 4
{
  
    if(RI)
      {    
                ch=SBUF;
                if(ch!='#'){      
                temp[index++] = ch;
                }else{
                    index=0;
                    biao=1;
                }
                RI = 0;
                
                    
                }            
            
        if(TI){
            TI=0;
        }
    
        
}
    
         

//定时中断初始化
void timer0_init(void)
{
       EA = 1;
       TMOD |= 0x01;
       TH0 = (65535 - 50000) / 256;
       TL0 = (65535 - 50000) % 256;
       ET0 = 1;
       TR0 = 1;
} 
 
 //定时中断函数
void timer0_isr() interrupt 1
{    
      
       TH0 = (65535 - 50000)/256;
       TL0= (65535 - 50000)%256;
       a++;
         if(a==20)  
         {
                a = 0;
          miao++;
                    count++;
                    if(count==60){
                        count=0;
                        flg=1;
                    }
                    flag=~flag;
          if(miao==60)
          {
                            
                           miao = 0;
                           fen++;
                           if(fen == 60)
                             {
                                    fen  = 0;
                                  shi++;
                                    if(shi == 24)
                                        {
                                                shi = 0;
                    }    
               }      
          }                        
     }
     tempdata[0] = segdata[shi / 10];
     tempdata[1] = segdata[shi % 10];
     
     tempdata[3] = segdata[fen / 10];
     tempdata[4] = segdata[fen % 10];
        
         
     tempdata[6] = segdata[miao / 10];
     tempdata[7] = segdata[miao % 10];     
            
         if(flag){
              tempdata[2] = 0x40;
        tempdata[5] = 0x40;
             
         }else{
              tempdata[2] = 0x00;
        tempdata[5] = 0x00;
         }     
}     


//主函数
void main()
{  
    unsigned int j=0;
      timer0_init();
      uart_init();
      while(1)
        {
            
            if(flg){
                flg=0;
                uart_send_str("now time is:\n");
                uart_send_byte((shi/10)+0x30);
                uart_send_byte((shi%10)+0x30);
                uart_send_byte(':');
                uart_send_byte((fen/10)+0x30);
                uart_send_byte((fen%10)+0x30);
                uart_send_byte(':');
                uart_send_byte((miao/10)+0x30);
                uart_send_byte((miao%10)+0x30);
                uart_send_str("\r\n"); 
            }
                        
                if(!strncmp("0x01",temp,4)){
                                clean();
                                    while(1){
                            unsigned char i = 0; 
                            for(;i<8;i++){    
                         P2=bitdata[i];    
                         P1 = segdata[0];            
                         delay_us(100);                
                } 
                if(!strncmp("0x02",temp,4)){
                            clean();    
                                break;
                            }        
                }        
            }    
        
        if(biao){
            biao=0;
            if(infodata()){
            hour = ((unsigned int)temp[5] - 48) * 10 + ((unsigned int)temp[6]  - 48);
          min= ((unsigned int)temp[8] - 48)* 10 + ((unsigned int)temp[9]  - 48);
          sen = ((unsigned int)temp[11] - 48)* 10 + ((unsigned int)temp[12]  - 48);        
}
            if(hour>=0&&hour<=24&&min>=0&&min<60&&sen>=0&&sen<60){
                shi=hour;
                fen=min;
                miao=sen;
                    }else{
                         uart_send_str("The Time is error");
                         uart_send_str("\r\n");
                    }
                
//          uart_send_str(temp);    
//            uart_send_str("\r\n");
            clean();
        }
            display();
    }
    }

实验效果图

时钟显示

电脑发送指令0x01

设置时钟

返回时间


文章作者: 时光路人
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 时光路人 !
评论
  目录