在調試串口通訊過程中搞清楚幾個配合問題:
- 使用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 }

