1. 程式人生 > 實用技巧 >電子工藝課存檔 proteus和C語言

電子工藝課存檔 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毫秒),
    
//人眼就能感受到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); } } }
View Code

流水燈都往左,流水燈都往右,流水燈相對而行,流水燈相向而行

按鈕控制流水燈花樣

/* 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