目錄: 1、單片機串口通信的應用 2、PC控制單片機IO口輸出 3、單片機控制實訓指導及綜合應用實例 4、單片機給計算機發送數據: [實驗任務] 單片機串口通信的應用,通過串口,我們的個人電腦和單片機系統進行通信。 個人電腦作為上位機,向下位機單片機系統發送十六進制或者ASCLL碼,單片機 系統接收后,用LED顯示接收到的數據和向上位機發回原樣數據。 [硬件電路圖] [實驗原理] RS-232是美國電子工業協會正式公布的串行總線標準,也是目前最常用的串 行接口標準,用來實現計算機與計算機之間、計算機與外設之間的數據通訊。 RS-232串行接口總線適用于:設備之間的通訊距離不大于15m,傳輸速率最大為 20kBps。RS-232協議以-5V-15V表示邏輯1;以+5V-15V 表示邏輯0。 我們是 用MAX232芯片將RS232電平轉換為TTL電平的。 一個完整的RS-232接口有22 根線,采用標準的25芯插頭座。我們在 這里使用的是簡化的9芯插頭座。 注意我們在這里使用的晶振是11.0592M的,而不是12M。因為波特率的設置 需要11.0592M的。 “串口調試助手V2.1.exe” 軟件的使用很簡單,只要將串口選擇‘CMO1’波 特率設置為‘9600’ 數據位為 8 位。打開串口(如果關閉)。然后在發送區里 輸入要發送的數據,單擊手動發送就將數據發送出去了。注意,如果選中‘十六 進制發送’那么發送的數據是十六進制的,必須輸入兩位數據。如果沒有選中, 則發送的是ASCLL碼,那么單片機控制的數碼管將顯示ASCLL碼值。 數字 | 二進制 | Px0~Px7 | Abcdefg p | 十六進制 | 0 | 00111111 | 00000011 | 11111100 | 0xco | 1 | 00000110 | 10011111 | 01100000 | 0xf9 | 2 | 01011011 | 00100101 | 11011010 | 0xa4 | 3 | 01001111 | 00001101 | 11110010 | 0xb0 | 4 | 00110110 | 10010011 | 01101100 | 0x99 | 5 | 01101101 | 01001001 | 10110110 | 0x92 | 6 | 01111101 | 01000001 | 10111110 | 0x82 | 7 | 00000111 | 00011111 | 11100000 | 0xf8 | 8 | 01111111 | 00000001 | 11111110 | 0x80 | 9 | 01101111 | 00001001 | 11110110 | 0x90 | A | 01110111 | 00010001 | 11101110 | 0x88 | B | 01111100 | 11000001 | 00111110 | 0x83 | C | 00111001 | 01100011 | 10011100 | 0xc6 | D | 01011110 | 10000101 | 01111010 | 0xa1 | E | 01111001 | 01100001 | 10011110 | 0x86 | F | 01110001 | 01110001 | 10001110 | 0x8e | | | | | |
ASCII常用代碼表 [C語言源程序] #include "reg52.h" //包函8051 內部資源的定義 unsigned char dat; //用于存儲單片機接收發送緩沖寄存器SBUF里面的內容 sbit gewei=P2^4; //個位選通定義 sbit shiwei=P2^5; //十位選通定義 sbit baiwei=P2^6; //百位選通定義 unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,}; //1~10 void Delay(unsigned int tc) //延時程序 { while( tc != 0 ) {unsigned int i; for(i=0; i<100; i++); tc--;} } void LED() //LED顯示接收到的數據(十進制) { gewei=0; P0=table[dat%10]; Delay(10); gewei=1; shiwei=0; P0=table[dat/10]; Delay(10); shiwei=1; baiwei=0; P0=table[dat/100]; Delay(10); baiwei=1; } ///////功能:串口初始化,波特率9600,方式1///////// void Init_Com(void) { TMOD = 0x20; PCON = 0x00; SCON = 0x50; TH1 = 0xFd; TL1 = 0xFd; TR1 = 1; } /////主程序功能:實現接收數據并把接收到的數據原樣發送回去/////// void main() { Init_Com();//串口初始化 while(1) { if ( RI ) //掃描判斷是否接收到數據, { dat = SBUF; //接收數據SBUF賦與dat RI=0; //RI 清零。 SBUF = dat; //在原樣把數據發送回去(接收數據為發送數據的ASCII碼,如發送q顯示為113) } LED(); //顯示接收到的數據 } } ///這一個例子是以掃描的方式編寫的,還可以以中斷的方式編寫,請大家思考////// [實驗任務]PC控制單片機IO口輸出 #include "reg52.h" //包函8051 內部資源的定義 unsigned char dat; //用于存儲單片機接收發送緩沖寄存器SBUF里面的內容 void Delay(unsigned int tc) //延時程序 { while( tc != 0 ) {unsigned int i; for(i=0; i<100; i++); tc--;} } ///////功能:串口初始化,波特率9600,方式1///////// void Init_Com(void) { TMOD = 0x20; PCON = 0x00; SCON = 0x50; TH1 = 0xFd; TL1 = 0xFd; TR1 = 1; } /////主程序功能:實現接收數據并把接收到的數據原樣發送回去/////// void main() { Init_Com();//串口初始化 while(1) { if ( RI ) //掃描判斷是否接收到數據, { dat = SBUF; //接收數據SBUF賦與dat if(dat==0x00) //如果PC發送十六進制00,單片機P1口全亮。 P1=0x00; else if(dat==0x01) P1=0x01; else if(dat==0x02) P1=0x02; else if(dat==0x03) P1=0x03; else if(dat==0x04) P1=0x04; RI=0; //RI 清零。 SBUF = dat; //在原樣把數據發送回去(接收數據為發送數據的ASCII碼,如發送q顯示為113) } } } [實驗任務]單片機控制實訓指導及綜合應用實例 #include "reg52.h" //包函AT89S52 內部資源的定義(注視參看書160頁) #define uchar unsigned char //宏定義 uchar led [10]={0xbf,0x06,0xdb,0xcf,0x66,0xed,0xfd,0x87,0xff,0xef}; //數字1~10,字符串 uchar led1[64]; //存儲接收數據 unsigned int i,j,t,k; sbit P32=P3^2; void scjs(void)interrupt 4 //定義中斷 { ES=0;// 使能串行口的中斷 k=1; while(1) { RI=0; led1[k-1]=SBUF; //將接收數據送段碼表 k++; TH0=0x3c; //t0定時50sm內接收不到數據跳過接收 TL0=0xb0; TR0=1; while(!RI) { if(!TF0) goto FH; } } FH:TF0=0;//TF0不清零不能重新接收 TR0=0; P32=1; for(j=1;j<k;j++) { SBUF=led[j-1];//數據送回給pc while(!TI); TI=0; } P32=0; } delay(t) { ES=1; SCON=0x50; for(i=0;i<t;i++); ES=0; SCON=0x00; } void main (void) { int a,c; TMOD=0x21; TH1=0Xfd; TL1=0xfd; SCON=0x50; PCON=0x00; IE=0x90; TR1=1; k=1; P32=0; while(1) { ES=0; SCON=0x00; for(a=0;a<=k+1/k*8;a++) { for(c=5;c>=0;c--) { if(a+c<k+1/k*8+1) { if(k==1)SBUF=led[a+c]; else SBUF=led1[a+c]; } else SBUF=0x00; while(!TI); TI=0; } delay(39000); } } } #include "reg52.h" //包函8051 內部資源的定義 #define uchar unsigned char sbit P3_2=P3^2; uchar zdzt=0x0c; uchar zsgw=0x02; uchar zsdw=0x00; uchar bs=0; uchar zqsbw=0; uchar zqssw=0; uchar zqsgw=0; uchar yxsj=0x11; uchar zs=20; int zqs=0; uchar zqsgzj=0x00; uchar zqsdzj=0x00; uchar zsscgw=0x1f; uchar zsscdw=0x00; uchar bzsj; uchar ztsj; void key (void); void keyprc(); void binbcd(); void disp(); void delay(); code uchar tab[13]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x39}; code uchar zssc[160]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c, 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f, 0x6f,0x77,0x7c,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f, 0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f, 0x77,0x7c,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f,0x06, 0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,}; void key(void) { TR0=0; if(!(P2&0X01)) { delay(); while(!(P2&0X01)); zdzt=0x0a; disp(); } else if(!(P3&0X08)) { delay(); while(!(P3&0X08)); zdzt=0x0b; disp(); } else if(!(P3&0X10)) { delay(); while(!(P3&0X10)); zs=zs+1; keyprc(); disp(); } else if(!(P2&0X02)) { delay(); while(!(P2&0X02)); zs=zs-1; keyprc(); disp(); } } void keyprc() { if(zs<20) zs=20; if(zs>99) zs=99; zsgw=zs/10; zsdw=zs%10; } void djzd(void) interrupt 1 { TH0=zssc[(zs-20)*2]; TL0=zssc[(zs-20)*2+1]; if(zdzt==0x0a) yxsj=yxsj<<1|yxsj>>7; else if (zdzt==0x0b) yxsj=yxsj<<7|yxsj>>1; else if(zdzt==0x0c) { P1=0xff; goto LP; } P1=yxsj; bs++; if(bs==48) { bs=0; zqs++; } LP:binbcd(); disp(); } void binbcd() { zqsbw=zqs/100; zqssw=zqs%100/10; zqsgw=zqs%10; } void disp() { TR1=0; ES=0; SCON=0x00; TMOD=0x01; SBUF=tab[zqsgw]; while(!TI);TI=0; SBUF=tab[zqssw]; while(!TI);TI=0; SBUF=tab[zqsbw]; while(!TI);TI=0; SBUF=tab[zsdw]; while(!TI);TI=0; SBUF=tab[zsgw]; while(!TI);TI=0; SBUF=tab[zdzt]; while(!TI);TI=0; TMOD=0x02; TH1=0Xfd; TL1=0xfd; SCON=0x50; TR1=1; ES=1; } void delay() { int k; for(k=0;k<1200;k++); } void sin()interrupt 4 { P1=0xff; ES=0; bzsj=SBUF; RI=0; while(!RI); RI=0; ztsj=SBUF; if(bzsj==0x30) zdzt=ztsj-0x37; if(bzsj==0x31) { if(ztsj==0x49) zs++; else zs--; } ES=1; P3_2=0; keyprc(); zqs=0; disp(); } main() { TMOD=0x21; TH1=0xfd; TL1=0xfd; SCON=0x50; PCON=0x00; IE=0X92; PS=1; TR1=1; P3_2=0; TH0=0x1f; TL0=0x00; SP=0x60; disp(); while(1) { key(); if(zdzt==0x0c) { TR0=0; P1=0xff; } else TR0=1; } } 單片機給計算機發送數據: #include "reg52.h" //包函8051 內部資源的定義 unsigned char dat; //用于存儲單片機接收發送緩沖寄存器SBUF里面的內容 unsigned char fan; int i,j; void Delay() //延時程序 { for(i=0; i<100; i++) for(j=0; j<100; j++); } void delays() { int k; for (k=0;k<1200;k++); } ///////功能:串口初始化,波特率9600,方式1///////// void Init_Com(void) { TMOD = 0x20; PCON = 0x00; SCON = 0x50; TH1 = 0xFd; TL1 = 0xFd; TR1 = 1; } /////主程序功能:實現接收數據并把接收到的數據原樣發送回去/////// void main() { Init_Com();//串口初始化 while(1) { if ( RI ) //掃描判斷是否接收到數據, { dat = SBUF; //接收數據SBUF賦與dat if(dat==0x30) //如果PC發送十六進制00,單片機P1口全亮。 {P1=0x00; Delay(); } else if(dat==0x31) {P1=0x01; Delay();} else if(dat==0x32) {P1=0x03; Delay();} else if(dat==0x33) {P1=0x07; Delay(); } else if(dat==0x34) {P1=0x0f; Delay(); } else if(dat==0x35) {P1=0x1f; Delay();} else if(dat==0x06) {P1=0x3f; Delay(); } else if(dat==0x07) {P1=0x7f; Delay();} else if(dat==0x08) {P1=0xff; Delay(); } else if(!(P2&0x01)) { delays(); while(!(P2&0x01)); fan = 0x36;} else if(!(P2&0x02)) { delays(); while(!(P2&0x02)); fan = 0x37;} else if(!(P2&0x04)) { delays(); while(!(P2&0x04)); fan = 0x38;} else if(!(P2&0x08)) { delays(); RI=0; //RI 清零。 SBUF =dat; //在原樣把數據發送回去(接收數據為發送數據的ASCII碼,如發送q顯示為113) } } }
|