電子工藝課存檔 proteus和C語言
開學初裝了Proteus 8 Professional和Keil uVision4
2020-06-17安裝vspdpro-jie.exe
1.串列埠除錯助手直接執行,無需安裝。
2.Virtual Serial Port Driver,先執行vspdpro安裝,完成安裝後,將vspdpro-jie.exe複製到安裝目錄,C:\Program Files\Eltima Software\Virtual Serial Port Driver Pro 9.0,執行vspdpro-jie.exe
C:\Program Files\Eltima Software\Virtual Serial Port Driver Pro 9.0
以下是全部程式,從入門到入門
花樣流水燈
/* Main.c file generated by New Project wizard * * Created: 週四 4月 2 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> #include <stdio.h> #include < intrins.h> void delay(void) //延遲函式,當程式輸出一個電訊號後,CPU做無意義運算,讓這個狀態維持一段時間(約0.5毫秒),View Code//人眼就能感受到LED燈被點亮了 { unsigned int i,j; for(i=0;i<10;i++) for(j=0;j<5000;j++) { } } void main(void) { // Write your code here unsigned char a,b; signed int i; a=1; b=1; while (1) { for(i=0; i<16; i++) { P1=a;//P1在安裝好的keil目錄的reg51.h被定義好,是微控制器P1埠(共8個)的資料暫存器,//即給它賦值就代表了讓P1.0-P.7輸出(1,高電平,0,低電平),以驅動外接的LED燈被點亮 P2=b; delay(); a=_crol_(a,1);//定義在intrins.h裡的標準C函式,使得a無符號 字元型變數(8位二進位制數)迴圈左移, //然後當把a賦值給P1後,使得P1口每一位(P.0-P1.7)逐次輸出一個1(5v高電平) b=_crol_(b,1); } b=_cror_(b,1); for(i=0; i<15; i++)//流水燈都往右 { P1=a; P2=b; delay(); a=_crol_(a,1); b=_cror_(b,1); } for(i=0; i<15; i++)//流水燈都往左 { P1=a; P2=b; delay(); a=_cror_(a,1); b=_crol_(b,1); } a=_cror_(a,1); for(i=0; i<15; i++)//流水燈相對而行 { P1=a; P2=b; delay(); a=_cror_(a,1); b=_cror_(b,1); } for(i=0; i<16; i++) { P1=a; P2=b; delay(); a=_crol_(a,2); b=_crol_(b,2); } } }
流水燈都往左,流水燈都往右,流水燈相對而行,流水燈相向而行
按鈕控制流水燈花樣
/* Main.c file generated by New Project wizard * * Created: 週三 4月 22 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ /* 按button0, 流水燈下移;按button1,流水燈上移; 按button2,流水燈雙燈下移;按button3,流水燈雙燈上移; 按button4, 流水燈雙燈下移兩格;按button5,流水燈雙燈上移兩格; 按button6, 流水燈三燈下移;按button7,流水燈四燈間隔閃爍; */ #include<reg52.h> //庫檔案 #include<intrins.h> #define uchar unsigned char//巨集定義無符號字元型 #define uint unsigned int //巨集定義無符號整型 /******************************************************************** 初始定義 *********************************************************************/ uchar a,b,c,d; //定義字元型變數 uchar flag; sbit BY0=P2^0; //定義按鍵的輸入端(為微控制器P2口的P2.0按鍵) sbit BY1=P2^1; //定義按鍵的輸入端(為微控制器P2口的P2.1按鍵) sbit BY2=P2^2; sbit BY3=P2^3; sbit BY4=P2^4; sbit BY5=P2^5; sbit BY6=P2^6; sbit BY7=P2^7; /******************************************************************** 延時函式 *********************************************************************/ void delay10ms(void) //延時程式 { uchar i,j; for(i=20;i>0;i--) for(j=248;j>0;j--); } void delay(void) //延遲函式,當程式輸出一個電訊號後,CPU做無意義運算,讓這個狀態維持一段時間(約0.5毫秒), //人眼就能感受到LED燈被點亮了 { unsigned int i,j; for(i=0;i<10;i++) for(j=0;j<5000;j++) { } } /******************************************************************** 按鍵判斷函式 *********************************************************************/ void key1() //按鍵判斷程式 { unsigned int k; if(P2!=0xFF)//是否有鍵按下,進一步通過區分P2的8位二進位制數值來判斷哪個鍵按下了 { delay10ms(); //延時,軟體去幹擾,機械按鍵在按下和鬆開時,狀態進入穩定前會有微小的不穩定抖動態,重複判斷,確定按鍵的狀態 if(BY0==0) flag=0; else if(BY1==0) flag=1; else if(BY2==0) flag=2; else if(BY3==0) flag=3; else if(BY4==0) flag=4; else if(BY5==0) flag=5; else if(BY6==0) flag=6; else flag=7; } } void key() //按鍵判斷程式 { unsigned int i,j=1; if(P2!=0XFF){//判斷是否有鍵按下 沒有鍵被按下時全部為‘1’ for(i=0;i<=7;i++){ if((P2&j)==0){//微控制器P2口的P2.i按鍵被按下 為‘0' delay10ms(); //延時,軟體,機械按鍵在按下和鬆開時,狀態進入穩定前會有微小的不穩定抖動態,重複判斷,確定按鍵的狀態 if((P2&j)==0){//確認按鍵按下 flag=i;//flag用於標識最近一次按下的鍵 } while((P2&j)==0);//按鍵鎖定 return ; } j*=2; } } } /******************************************************************** 主函式 *********************************************************************/ void main() { a=0xFE, b=0xFC, c=0xF8, d=0xAA; flag=-1; while(1) { key(); //呼叫按鍵判斷函式 switch(flag) { case 0: P0=a; delay(); a=_crol_(a,1); break; case 1: P0=a; delay(); a=_cror_(a,1); break; case 2: P0=b; delay(); b=_crol_(b,1); break; case 3: P0=b; delay(); b=_cror_(b,1); break; case 4: P0=b; delay(); b=_crol_(b,2); break; case 5: P0=b; delay(); b=_cror_(b,2); break; case 6: P0=c; delay(); c=_crol_(c,1); break; case 7: P0=d; delay(); d=_cror_(d,1); break; default: break; } } } /******************************************************************** 結束 *********************************************************************/View Code
按button0, 流水燈下移;按button1,流水燈上移;
按button2,流水燈雙燈下移;按button3,流水燈雙燈上移;
按button4, 流水燈雙燈下移兩格;按button5,流水燈雙燈上移兩格;
按button6, 流水燈三燈下移;按button7,流水燈四燈間隔閃爍;
外部中斷控制流水燈花樣
/* Main.c file generated by New Project wizard * * Created: 週三 5月 6 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> #define uint unsigned int #define uchar unsigned char //花樣顯示,23個狀態 uchar tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F, 0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0XFE,0XFF, 0xAA,0x55,0xAA,0x55,0xAA,0x55,0xFF}; //中斷顯示,10個狀態,0號中斷 uchar tab1[ ]={0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00}; //中斷顯示,10個狀態,2號中斷,中斷一次切換中斷顯示 uchar tab2[ ]={0x3C,0xC3,0x3C,0xC3,0x3C,0xC3,0x3C,0xC3,0x3C,0xC3}; uchar tab3[ ]={0x5A,0xA5,0x5A,0xA5,0x5A,0xA5,0x5A,0xA5,0x5A,0xA5}; uchar tab4[ ]={0xF0,0x0F,0xF0,0x0F,0xAA,0x55,0xAA,0x55,0x00,0xFF}; uint count=-1; //ms延時程式 void delay_ms(uint x) { uint t; while(x--) for(t = 0; t < 120; t++); } void intrp0( ) interrupt 0 { uchar i; for(i=0;i<10;i++) { P0=tab1[i]; delay_ms(300); } } void intrp2( ) interrupt 2 { uchar i; count=(count+1)%3; if(count==0) { for(i=0;i<10;i++) { P1=tab2[i]; delay_ms(300); } } else if(count==1) { for(i=0;i<10;i++) { P1=tab3[i]; delay_ms(300); } } else { for(i=0;i<10;i++) { P1=tab4[i]; delay_ms(300); } } } void main( ) { IT0=1; EX0=1; EA=1; IT1=1; EX1=1; while(1) { uchar x; for(x=0;x<23;x++) { P0=tab[x]; P1=tab[x]; delay_ms(500); } } }View Code
流水燈正常執行,外部中斷0觸發時P0口顯示花樣,外部中斷1觸發時P1口顯示花樣
定時器實現方波
/* Main.c file generated by New Project wizard * * Created: 週三 5月 20 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> sbit P2_0=P2^0; void timer0 (void) interrupt 1 { P2_0 = !P2_0; //P2.0取反 TH0 = 55536/256; //計數初值重灌載 TL0 = 55536%256; } void main (void) { TMOD = 0x01; //T0定時方式1 P2_0=0; TH0=55536/256; //預置計數初值 定時10ms TL0=55536%256; EA=1; ET0=1; TR0=1; while(1); }View Code
電子琴
/* Main.c file generated by New Project wizard * * Created: 週三 5月 20 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include<reg52.h> //庫檔案 #include<intrins.h> #define uchar unsigned char//巨集定義無符號字元型 #define uint unsigned int //巨集定義無符號整型 /******************************************************************** 初始定義 *********************************************************************/ unsigned int T[8]={63628,63835,64021,64103,64260,64400,64524,64580};//低1-低7和中1 音符的頻率所對應的T值 unsigned int T_value; unsigned int count=0;//中斷服務程式執行的次數,確保一次按鍵只響一聲 sbit BY0=P1^0; //定義按鍵的輸入端(為微控制器P1口的P1.0按鍵) sbit BY1=P1^1; //定義按鍵的輸入端(為微控制器P1口的P1.1按鍵) sbit BY2=P1^2; sbit BY3=P1^3; sbit BY4=P1^4; sbit BY5=P1^5; sbit BY6=P1^6; sbit BY7=P1^7; sbit P2_0=P2^0; /******************************************************************** 延時函式 *********************************************************************/ void delay10ms(void) //延時程式 { uchar i,j; for(i=20;i>0;i--) for(j=248;j>0;j--); } /******************************************************************** 中斷函式 *********************************************************************/ void timer(void) interrupt 1//定時計數器T0 中端號為1 { P2_0=!P2_0; TH0=T_value/256; TL0=T_value%256; count++; if(count==2) { count=0; ET0=0; TR0=0; } } /******************************************************************** 主函式 *********************************************************************/ void main() { TMOD=0x01; //T0定時方式1 EA=1; P0=0xFF;//燈初始狀態為全關 while(1) { P0=0xFF; if(P1!=0)//是否有鍵按下,進一步通過區分P1的8位二進位制數值來判斷哪個鍵按下了 { delay10ms(); //延時,軟體去幹擾,機械按鍵在按下和鬆開時,狀態進入穩定前會有微小的不穩定抖動態,重複判斷,確定按鍵的狀態 while(BY0==0) { P0=0xFE;//1111 1110 T_value=T[0]; ET0=1;//開T0中斷 TR0=1;//啟動定時器0 } while(BY1==0) { P0=0xFD;//1111 1101 T_value=T[1]; ET0=1; TR0=1; } while(BY2==0) { P0=0xFB;//1111 1011 T_value=T[2]; ET0=1; TR0=1; } while(BY3==0) { P0=0xF7;//1111 0111 T_value=T[3]; ET0=1; TR0=1; } while(BY4==0) { P0=0xEF;//1110 1111 T_value=T[4]; ET0=1; TR0=1; } while(BY5==0) { P0=0xDF;//1101 1111 T_value=T[5]; ET0=1; TR0=1; } while(BY6==0) { P0=0xBF;//1011 1111 T_value=T[6]; ET0=1; TR0=1; } while(BY7==0) { P0=0x7F;//0111 1111 T_value=T[7]; ET0=1; TR0=1; } } } } /******************************************************************** 結束 *********************************************************************/View Code
8個音符較少,可彈奏粉刷匠和小毛驢
unsigned int T[8]={63628,63835,64021,64103,64260,64400,64524,64580};//低1-低7和中1 音符的頻率所對應的T值
用8255實現數碼管60秒計時
/* Main.c file generated by New Project wizard * * Created: 週三 6月 3 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> #include <intrins.h> #include <absacc.h> #define uint unsigned int #define uchar unsigned char //P0.5和P0.6決定A0和A1,決定選擇的暫存器組 #define portA 0X00 #define portB 0x20 #define portC 0x40 #define Cont 0x60 sbit P1_0=P1^0; sbit P1_1=P1^1; uint ten=0; uint one=0; uint count=0;//計數滿20次為1s uchar table[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};//共陰數碼管段碼錶 //工作方式1最大計時65.536ms,我們要計算一秒,則計時20次50ms較好, //要計算的機器週期數=50ms/1μs=50000,計數初值=2^16-50000=15536 //中斷函式定時計數器T0 中端號為1 void timer0(void) interrupt 1 { TH0=15536/256; TL0=15536%256; count++; if(count==20) { count=0; one++; } if(one==10) { one=0; ten++; if(ten==6) { ten=0; } } } void show() { PBYTE[portA]=table[ten]; PBYTE[portB]=table[one]; } void main(void) { PBYTE[Cont]=0x81;//將控制字寫入8255的控制口地址 1000 0001 TMOD=0x01;//T0定時方式1 EA=1; TH0=15536/256; TL0=15536%256; ET0=1;//開T0中斷 TR0=1;//啟動計時器 while(1) { show(); if(P1_0==0)//P1.0處按鍵按下,計時暫停,或者是P1==255-1 { TR0=0;//關閉定時器0 } if(P1_1==0)//P1.1處按鍵按下,計時重置 { ten=0; one=0; TR0=1; } } }View Code
序列口通訊
要使用串列埠除錯助手和vspdpro
/* Main.c file generated by New Project wizard * * Created: 週三 6月 17 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> #include <stdio.h> unsigned char table[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};//共陰數碼管段碼錶 unsigned char mystr[]={0x68,0x65,0x6c,0x6c,0x6f};//hello unsigned int num = 9; sbit P2_0 = P2^0; unsigned int i; //延時函式 void delay_ms(unsigned int x){ unsigned int t; while(x--) for(t=0;t<120;t++); } //序列口初始化 void csh() { SCON=0x50;//設定序列口工作方式,SM0=0,SM1=1,REN=1,TI=RI=0 PCON=0; //波特率不加倍 TH1=0xFD; //波特率設定為9600,計數初值查表可得,晶振頻率為11.0592MHz TL1=0XFD; TMOD=0X20;//T1工作於方式2定時方式 TR1=1; //啟動T1 } //按鍵判斷函式 void key() { num = 0; if(P1==255-1) {//P1.0按下,下面類似 num = 1; } else if(P1==255-2) { num = 2; } else if(P1==255-4) { num = 3; } else if(P1==255-8) { num = 4; } else if(P1==255-16) { num = 5; } else if(P1==255-32) { num = 6; } else if(P1==255-64) { num = 7; } else if(P1==255-128) { num = 8; } if(num != 0) { P0=table[num]; SBUF = num+0x30; while(!TI); TI = 0; } } void showString(){ for(i=0;i<5;i++){ SBUF=mystr[i]; while(!TI); TI=0; } } void main() { csh(); //序列口初始化 while(1) { while(RI) { RI=0; P0=table[SBUF-0x30]; } while(P1!=255) { delay_ms(10); key(); } if(!P2_0){ P2_0 = 1; delay_ms(10); showString(); } } }View Code
微控制器非同步序列通訊
通過矩陣鍵盤,8位數碼管,8255,74ls373等器件,完成微控制器之間的串列埠通訊。將兩個微控制器的序列口連線,進行非同步序列通訊。兩個微控制器能夠通過按鍵,8位數碼管,設定輸出資料(10個數字和A-F字元組成的字串,最多輸入8個)和顯示接收到的資料(最多8個),通過設定傳送鍵(可使用外部中斷),傳送。 (100分)
/* Main.c file generated by New Project wizard * * Created: 週三 7月 1 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> extern void delay_ms(unsigned int n); extern void Scan_Key(void); void disp(void);//顯示收到的字元 void receive(void); unsigned char ptr,m; unsigned int tno=0,rno=0;//傳送和接收時的第幾個數碼管 sbit P3_2=P3^2;//傳送鍵 unsigned char table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };//共陰極字型碼 unsigned char sel[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位選 unsigned char data tdisbuf[8]={0}; unsigned char data rdisbuf[8]={0}; void delay_ms(unsigned int n) //延時 { unsigned int i,j; for(i=0;i<n;i++) { for(j=0;j<80;j++); } } void intrr0(void) interrupt 0 //判斷P3.2是否按下,如按下就傳送字串 { unsigned int i,j; //序列口傳送 for(i=0;i<8;i++){ SBUF=tdisbuf[i]; delay_ms(2); } tno=0;//重置,以便下次傳送從頭開始 for(j=0;j<8;j++){ tdisbuf[i]=0; } } void intrr4(void) interrupt 4 //判斷序列口是否傳送或接收完資料 { if(TI==1) //若傳送完資料 { TI=0; //傳送完資料,清TI } if(RI==1) //若接收到資料 { RI=0; //清RI receive(); } } void receive(void) //把接收到資料的資料送給rdisbuf陣列 { unsigned char i; rdisbuf[rno]=SBUF; rno=(rno+1)%8; } void disp(void) //把rdisbuf陣列內的字元顯示在數碼管上 { unsigned char i,j; P2=0XFF; //關閉所示數碼管顯示 for(i=0;i<8;i++) { j=rdisbuf[i]; P2=sel[i]; //得到位選 P0=table[j]; //送段碼 delay_ms(2); P2=0XFF; } } void csh() //初始化串列埠 { SM0=0; SM1=1; REN=1; TI=0; RI=0;//以上兩行可用SCON=0x50替換 PCON=0; //波特率不加倍 TH1=0xFD; TL1=0XFD;//波特率設定為9600 TMOD=0X20;//T1工作於方式2定時方式 EA=1; //開總中斷 ES=1; //開序列通訊中斷 TR1=1; //啟動T1 } unsigned char Check_Key() { unsigned char i; P1=0xF0; //送全0,向各行送低電平 i=P1; //取P1口值 i=i&0xF0; //遮蔽掉低四位,作為列值 if(i==0xF0) //判斷是否有鍵按下 return 0; else return 0xff; } void Scan_Key(void) // 鍵盤掃描程式 { char a1,i; bit FLAG0=0; a1=0xfe; //列掃描初值,送1個“0” ptr=0; //第ptr個按鈕,A-F時為10-16 if(Check_Key()==0) return; for(i=0;i<4;i++) //鍵盤4個掃描列 { P1=a1; delay_ms(10); m=P1; switch(m&0xf0) //取行的高4位,檢測哪一行有按鍵被按下 { case 0xe0: ptr=i*4; //第一行被按否? FLAG0=1; //表示有按鍵 break; case 0xd0: ptr=i*4+1; //第二行被按否? FLAG0=1; break; case 0xb0: ptr=i*4+2; //第三行被按否? FLAG0=1; break; case 0x70: ptr=i*4+3; //第四行被按否? FLAG0=1; break; default: break; } if( FLAG0 ) { if(tno<8) { tdisbuf[tno]=ptr; //第tno個數碼管 while((P1&0xf0)==0xe0); while((P1&0xf0)==0xd0); while((P1&0xf0)==0xb0); while((P1&0xf0)==0x70); tno=tno+1; return; } } a1=a1<<1|0x01; } } void main(void) { EX0=1;//開外部中斷0 csh(); while(1) { Scan_Key(); //掃描鍵盤 disp(); } }View Code
注:兩個微控制器程式一樣
unsigned char table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };//共陰極字型碼
unsigned char sel[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位選
為了上面這個綜合設計打過的草稿,參考了一堆程式,大部分來源於河南理工大學的mooc,微控制器原理與應用例項模擬
雙機通訊
//微控制器甲的程式 #include <reg51.h> void delay_ms(unsigned int x) { unsigned int t; while(x--) for(t=0;t<120;t++); } //初始化序列口 void csh() { SM0=0; SM1=1; REN=1; TI=0; RI=0; PCON=0; TH1=0xF3; TL1=0XF3; TMOD=0X20; EA=1; ET1=0; ES=1; TR1=1; } void main() { char c=0; csh(); while(1) { P0=c; SBUF=c; while(!TI); TI=0; delay_ms(600); c++; if (c>9) c=0; } } void intrr() interrupt 4 { char temp; temp=SBUF; P2=temp; RI=0; }View Code
注:這是微控制器甲的程式,乙的程式只在main函式的傳送9-0處不同
電子鐘
#include "reg51.h" #include "stdio.h" #define uint unsigned int #define uchar unsigned char uchar data second=0,minute=0,hour=0; uchar data disbuf[6]={0}; uchar bdata FLAG=0; sbit H_M=FLAG^1; //小時 分鐘切換標誌位 啟動後預設為分鐘設定狀態 sbit P1_0=P1^0; //增1鍵 sbit P3_2=P3^2; //小時,分鐘切換鍵 //定義共陰段碼 0-9 uchar code table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //計數變數 uchar data count=0; //定時器0的中斷服務程式 50ms void timer0(void) interrupt 1 using 1 {TH0=-50000/256; TL0=-50000%256; count++; if(count==20) {count=0; second++; if(second==60) {second=0; minute++; if(minute==60) {minute=0; hour++; if(hour==24) {hour=0;} } } } return; } //延時程式 void dlms(void) {uchar i; for(i=2000;i>0;i--){} } //外部中斷0的中斷服務程式 void int0(void) interrupt 0 using 2 { while(!P3_2) //等待按鍵彈起 { dlms(); } dlms( ); if(P3_2) //按鍵彈起 H_M=!H_M; } //顯示程式 void disp(void) {uchar i,j; uchar bdata sel; disbuf[0]=second%10; disbuf[1]=second/10; disbuf[2]=minute%10; disbuf[3]=minute/10; disbuf[4]=hour%10; disbuf[5]=hour/10; P2=0XFF; //關閉所示數碼管顯示 sel=0x01; for(i=0;i<6;i++) {j=disbuf[i]; P2=(sel^0xff); //得到位選 P0=table[j]; //送段碼 dlms(); P2=0XFF; sel=sel<<1; //位選左移1位 } } //加1處理程式 void increa(void) {if(H_M) //H_M為1 表示小時設定 {hour++; if(hour==24) {hour=0; disbuf[4]=0; disbuf[5]=0; } } else //H_M為0 表示分鐘設定 {minute++; if(minute==60) {minute=0; disbuf[2]=0; disbuf[3]=0; } } } int main( ) { TCON=0x01; TMOD=0x01; TH0=-50000/256; TL0=-50000%256; EA=1; ET0=1; EX0=1; TR0=1; while(1) {disp(); if(!P1_0) {while(!P1_0) dlms(); if(P1_0) increa(); } } }View Code
動態顯示數碼管(人眼的暫存效應)
#include <reg51.h> #define uchar unsigned char #define uint unsigned int uchar code ledD[6]={0x06,0x5b,0x4f,0x66,0x6d,0x7d};//段碼 uchar code ledW[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位選 //延時函式 void delay_ms(uint x) { uint t; while(x--) for(t=0;t<120;t++); } //主程式 void main( ) { uchar i; while(1) { for(i=0;i<6;i++) { P0=ledD[i]; P2=ledW[i]; delay_ms(2); //引數大於50時能清晰看到數碼管一個一個點亮 P2=0xff; } } }View Code
串列埠方式1
#include <reg52.h> //序列口初始化 void csh() //中斷方式序列口初始化 { SCON=0x50;//設定序列口工作方式,SM0=0,SM1=1,REN=1,TI=RI=0 PCON=0; //波特率不加倍 TH1=0xF4; //波特率設定為2400 TL1=0XF4; TMOD=0X20;//T1工作於方式2定時方式 ES=1; //開中斷 EA=1; TR1=1; //啟動T1 } void main() { csh(); //序列口初始化 P2=0Xff; //設P2為輸入埠 SBUF=P2; while(1); } void intrr() interrupt 4 //序列通訊中斷函式 { if(TI==1) //若傳送完資料 { TI=0; //傳送完資料,清TI SBUF=P2; //將開關的狀態讀入並從序列口傳送出去 } if(RI==1) //若接收到資料 { RI=0; //清RI P0=SBUF; //將接收到的資料顯示在LED上 } }View Code
微控制器7例子
老師發的優秀例子,僅供學習之用,不可轉載
#include<reg52.h> #include <stdio.h> #define uchar unsigned char #define uint unsigned int uchar table[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; uchar a; uchar str[7] = "Hello !"; void delay_ms(uint x) { uchar t; while(x --) for(t = 0; t < 120; t ++); } void csh() { SCON = 0x50; PCON = 0; TH1 = 0xFD; TL1 = 0xFD; TMOD = 0x20; ES = 1; EA = 1; TR1 = 1; } uint Key() { uint k; k = 0; if(P1 != 0xff) { delay_ms(10); switch(P1) { case 0xfe:k = 1; break; case 0xfd: k = 2; break; case 0xfb: k = 3; break; case 0xf7: k = 4; break; case 0xef: k = 5; break; case 0xdf: k = 6; break; case 0xbf: k = 7; break; case 0x7f: k = 8; break; } while(P1 != 0xff); } else if(P2 != 0xff) { delay_ms(10); if(P2 == 0xfe) k = 9; } return k; } void main() { uint i; csh(); P0 = 0x00; while(1) { if(TI == 0) { uint K = Key(); if(K >0 & K< 9 ) { SBUF = (K + 0x30); while(!TI); TI = 0; } else if(K ==9) for(i = 0; i < 7; i ++) { SBUF = str[i]; while(!TI); TI = 0; } } } } void intrr() interrupt 4 { if(RI == 1) { RI = 0; P0 = table[SBUF-0x30]; } }View Code
微控制器7例子3
老師發的優秀例子,僅供學習之用,不可轉載
#include <reg51.h> #include <stdio.h> #define uchar unsigned char #define uint unsigned int uchar buf; sbit BY0=P1^0; sbit BY1=P1^1; sbit BY2=P1^2; sbit BY3=P1^3; sbit BY4=P1^4; sbit BY5=P1^5; sbit BY6=P1^6; sbit BY7=P1^7; sbit BY8=P2^0;//這是控制向pc機發送一個字串 unsigned char string[]="hello world!"; //向pc機發送hello world! unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//數碼管0-9 unsigned int m,n; void delay10ms(void) //延時程式 { unsigned char i,j; for(i=20;i>0;i--) for(j=248;j>0;j--); } void csh() { SCON=0x50; PCON=0; TH1=0xFD; TL1=0xFD; TMOD=0x20; ES=1; EA=1; TR1=1; } void sendString() { for(m=0;m<12;m++) { SBUF=string[m]; while(!TI) ; TI=0; } } void key() //按鍵判斷程式 { if(P1 != 0xff) { delay10ms(); if(BY0==0) {SBUF=1+0x30;while(!TI) ;TI=0;while(!BY0) ;} if(BY1==0) {SBUF=2+0x30;while(!TI) ;TI=0;while(!BY1) ;} if(BY2==0) {SBUF=3+0x30;while(!TI) ;TI=0;while(!BY2) ;} if(BY3==0) {SBUF=4+0x30;while(!TI) ;TI=0;while(!BY3) ;} if(BY4==0) {SBUF=5+0x30;while(!TI) ;TI=0;while(!BY4) ;} if(BY5==0) {SBUF=6+0x30;while(!TI) ;TI=0;while(!BY5) ;} if(BY6==0) {SBUF=7+0x30;while(!TI) ;TI=0;while(!BY6) ;} if(BY7==0) {SBUF=8+0x30;while(!TI) ;TI=0;while(!BY7) ;} } if(BY8==0) { delay10ms(); if(BY8==0) {sendString(); while(!BY8) ;} } } void main(void) { csh(); while(1) key(); } void serial() interrupt 4 { if(RI==1){ RI=0; P0=tab[SBUF-0x30]; } }View Code
矩陣式鍵盤
#include <reg51.h> extern void Delay(unsigned int n); extern void Scan_Key(void); unsigned char ptr,m; unsigned char tab[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };//共陰極字型碼 void main(void) { P2=0x0; while(1) { Scan_Key(); //掃描鍵盤 } } void Delay(unsigned int n) //延時 { unsigned int i,j; for(i=0;i<n;i++) { for(j=0;j<80;j++); } } void Scan_Key(void) // 鍵盤掃描程式 { char a1,i; bit FLAG0=0; a1=0xfe; //列掃描初值 ptr=0; for(i=0;i<4;i++) //鍵盤4個掃描列 { P3=a1; Delay(10); m=P3; switch(m&0xf0) //取行的高4位,檢測哪一行有按鍵被按下 { case 0xe0: ptr=i*4; //第一行被按否? 如有則是tab[i*4]鍵 FLAG0=1; //表示有按鍵 break; case 0xd0: ptr=i*4+1; //第二行被按否? 如有則是tab[i*4+1]鍵 FLAG0=1; break; case 0xb0: ptr=i*4+2; //第三行被按否? 如有則是tab[i*4+2]鍵 FLAG0=1; break; case 0x70: ptr=i*4+3; //第四行被按否?如有則是tab[i*4+3]鍵 FLAG0=1; break; default: break; } if( FLAG0 ) { P2=tab[ptr]; //將鍵盤編碼轉換成顯示編碼 } a1=a1<<1|0x01 ; } } unsigned char Check_Key() { unsigned char i; P3=0xF0; //送全0,向各行送低電平 改了原來是0x00 i=P3; //取P3口值 i=i&0xF0; //遮蔽掉低四位,作為列值 if(i==0xF0) //判斷是否有鍵按下 return 0; else return 0xff; }View Code