关于51单片机串口通讯中向上位机发送字符的讨论
在调试串口通讯过程中搞清楚几个配合问题:
- 使用Keil带的C51库函数puts、printf之前必须置TI=1;
- 蓝色(一)处可以使用ES=0、ES=1,这时串口中断中(二)处,有无TI=0均可;
- 如果(一)处不使用ES=0、ES=1,这是串口中断中(二)处,不能使用TI=0;
- puts发送完字符串后自动发换行符'\n',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!\n"); 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://common.cnblogs.com/images/loading.gif)
![](https://img2018.cnblogs.com/i-beta/948553/202002/948553-20200203172850794-1979885668.png)