关于51单片机串口通讯中向上位机发送字符的讨论

在调试串口通讯过程中搞清楚几个配合问题:

  1. 使用Keil带的C51库函数puts、printf之前必须置TI=1;
  2. 蓝色(一)处可以使用ES=0、ES=1,这时串口中断中(二)处,有无TI=0均可;
  3. 如果(一)处不使用ES=0、ES=1,这是串口中断中(二)处,不能使用TI=0;
  4. puts发送完字符串后自动发换行符' ',printf需要手工加上换行符;
  1 #include<reg52.h>
  2 #include<stdio.h>
  3 
  4 unsigned char recievedFlag, recievedChar, sentFlag, ms50Count, secondCount;
  5 
  6 void Init();
  7 void Delay(unsigned int);
  8 void Display(unsigned int);
  9 
 10 void main()
 11 {
 12     Init();
 13     while(1)
 14     {
 15         if(recievedChar)
 16         {
 17             //ES = 0;-----(一)
 18             switch(recievedChar)
 19             {
 20                 case 0x01:
 21                     recievedChar = 0;
 22                     TI = 1;//puts, printf前必须TI=1 ------(三)
 23                     puts("Turn On Ad!");
 24                     break;
 25                 case 0x02:
 26                     recievedChar = 0;
 27                     TI = 1;    
 28                     printf("Turn off Ad!
");
 29                     break;
 30                 default:
 31                     recievedChar = 0;
 32                     TI = 1;    
 33                     puts("Error!");
 34                     break;
 35             }
 36             //ES = 1;-----(一)
 37         }
 38         //if(secondCount)
 39         //{
 40         //    secondCount = 0;
 41         //}
 42         //Display(4);
 43     }
 44 }
 45 
 46 void Init()
 47 {
 48     //配置定时器/计数器工作方式寄存器TMOD,不能位寻址
 49     //            TMOD结构
 50     //    D7        D6        D5        D4        D3        D2        D1        D0
 51     //    GATE     C/-T    M1        M0       GATE      C/-T       M1        M0
 52     //    --------------------------------       ---------------------------------
 53     //            定时器/计数器1                        定时器/计数器0
 54     //    ------------------------------------------------------------------------
 55     TMOD = 0x21;
 56     //    0          0        1        0        0         0         0         1
 57     //    --------------------------------       ---------------------------------
 58     //方式2:8位初值自动重装的8位定时器    方式1:16位定时器
 59     //----------------------------------------------------------------------------
 60     //定时器0初始化为50ms触发中断 
 61     TH0 = (65536 - 45872)/256;
 62     TL0 = (65536 - 45872)%256;
 63     //定时器1初始化成9600
 64     TH1 = 0xfd;//9600波特率时,计时器高八位为0xfd,低八位满后由CPU自动提供给低八位
 65     TL1 = 0xfd;//
 66     //TCON定时器/计数器控制寄存器,可位寻址,用来控制定时器的启、停,标识溢出和中断情况
 67     //        TCON结构
 68     //    D7        D6        D5        D4        D3        D2        D1        D0
 69     //    TF1       TR1       TF0       TR0       IE1       IT1       IE0       IT0
 70     //-----------------------------------------------------------------------------
 71     TR0 = 1;//Timer0启动
 72     TR1=1;//Timer1启动    
 73     //串口
 74     SM0=0;//SM0=0,SM1=1时,串口工作在方式1,既:10位异步收发(8位数据),波特率可变(由定时器1的溢出率控制)
 75     SM1=1;//
 76     REN=1;//串口接收启动
 77     //SCON = 0x50;
 78     //设置中断允许寄存器IE,可位寻址
 79     //        IE结构
 80     //    D7        D6        D5        D4        D3        D2        D1        D0
 81     //    EA        --        ET2       ES        ET1       EX1       ET0       EX0
 82     //----------------------------------------------------------------------------
 83     //以下几行可用IE = 0x92替代,既:10010010
 84     EA=1;//全局中断允许
 85     ET0 = 1;//开定时器0中断
 86     //ET1 = 1;//Timer1用于串口时钟,置于方式2:8位自动重装模式,不能手工设置ET1=1
 87     ES=1;//打开串口中断;
 88 }
 89 
 90 void timer0() interrupt 1
 91 {
 92     TH0 = (65536 - 45872) / 256;
 93     TL0 = (65536 - 45872) % 256;
 94     ms50Count++;
 95     if(ms50Count==20)
 96     {
 97         ms50Count = 0;
 98         secondCount++;
 99     }
100 }
101 
102 void serial() interrupt 4
103 {
104     if(RI)
105     {
106         RI = 0;
107         recievedFlag = 1;
108         recievedChar = SBUF;
109     }
110     if(TI)
111     {
112         //TI = 0;------(二)
113         sentFlag = 1;
114     }
115 }
 
原文地址:https://www.cnblogs.com/jqdy/p/12256454.html