51單片機 簡易加法計算器

#include <reg52.h>

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
sbit KEY_IN_0 = P2^4;
sbit KEY_IN_1 = P2^5;
sbit KEY_IN_2 = P2^6;
sbit KEY_IN_3 = P2^7;
sbit KEY_OUT_0 = P2^3;
sbit KEY_OUT_1 = P2^2;
sbit KEY_OUT_2 = P2^1;
sbit KEY_OUT_3 = P2^0;

uchar code LEDChar[] = {  //數碼管顯示字符轉換表
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
uchar LEDBuff[6] = {  //數碼管顯示緩衝區
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
uchar code keyCodeMap[4][4] = { //矩陣按鍵編號到標準鍵盤鍵碼的映射表
    {0x31, 0x32, 0x33, 0x26}, //數字鍵1、數字鍵2、數字鍵3、向上鍵
    {0x34, 0x35, 0x36, 0x25}, //數字鍵4、數字鍵5、數字鍵6、向左鍵
    {0x37, 0x38, 0x39, 0x28}, //數字鍵7、數字鍵8、數字鍵9、向下鍵
    {0x30, 0x1B, 0x0D, 0x27}  //數字鍵0、ESC鍵、  回車鍵、 向右鍵
};
uchar keyState[4][4] = {  //全部矩陣按鍵的當前狀態
    {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1}
};
uchar T0RH = 0;
uchar T0RL = 0;

void ShowNumber(ulong num)
{
    char i;
	uchar buf[6];
    for (i=0; i<6; i++)
    {
        buf[i] = num % 10;
        num /= 10;
    }
    for (i=5; i>=0; i--)
    {
        if (buf[i] == 0)
            LEDBuff[i] = 0xFF;
        else
            break;
    }
	for (; i>=0; i--)
	    LEDBuff[i] = LEDChar[buf[i]];
}

void KeyAction(uchar keyCode)
{
    static ulong result = 0;
    static ulong number = 0;
    if (keyCode >= 0x30 && keyCode <= 0x39)
    {
        number = number * 10 + keyCode - 0x30;
        ShowNumber(number);
    }
    else if (keyCode == 0x26 || keyCode == 0x0D)
    {
        result += number;
        number = 0;
        ShowNumber(result);
    }
    else if (keyCode == 0x1B)
    {
        number = 0;
        result = 0;
        ShowNumber(number);
    }
}

void KeyDriver()
{
    uchar i, j;
    static uchar backup[4][4] = {
        {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
    };
    for (i=0; i<4; i++)
        for (j=0; j<4; j++)
            if (keyState[i][j] != backup[i][j])
            {
                if (keyState[i][j] == 0)
                    KeyAction(keyCodeMap[i][j]);
                backup[i][j] = keyState[i][j];
            }
}

void KeyScan()
{
    static uchar i = 0;
    static uchar keyBuf[4][4] = {
        {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},
        {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}
    };
    uchar j;
    keyBuf[i][0] = (keyBuf[i][0] << 1) | KEY_IN_0;
    keyBuf[i][1] = (keyBuf[i][1] << 1) | KEY_IN_1;
    keyBuf[i][2] = (keyBuf[i][2] << 1) | KEY_IN_2;
    keyBuf[i][3] = (keyBuf[i][3] << 1) | KEY_IN_3;
    for (j=0; j<4; j++)
    {
        if (keyBuf[i][j] == 0x00)
            keyState[i][j] = 0;
        else if (keyBuf[i][j] == 0xFF)
            keyState[i][j] = 1;
    }
    switch (i)
    {
        case 0: KEY_OUT_0 = 1; KEY_OUT_1 = 0; break;
        case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
        case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
        case 3: KEY_OUT_3 = 1; KEY_OUT_0 = 0; break;
        default : break;
    }
    i = ++i & 0x03;
}

void LEDScan()
{
    static uchar i = 0;
    P0 = 0xFF;
    P1 = (P1 & 0xF8) | i;
    P0 = LEDBuff[i];
    if (i < 5)
        i++;
    else
        i = 0;
}

void SetTimer0(uint ms)
{
    ulong tmp;
    tmp = 11059326 / 12;
    tmp = tmp * ms / 1000;
    tmp = 65536 - tmp;
    tmp += 28;
    T0RL = tmp;
    T0RH = tmp>>8;
}

void InterruptTimer0() interrupt 1
{
    TH0 = T0RH;
    TL0 = T0RL;
	LEDScan();
	KeyScan();
}

void main()
{
    EA = 1;
    ENLED = 0;
    ADDR3 = 1;
    TMOD = 0x01;
    SetTimer0(1);
    TH0 = T0RH;
    TL0 = T0RL;
    ET0 = 1;
    TR0 = 1;
    LEDBuff[0] = LEDChar[0];
    while (1)
    {
        KeyDriver();
    }
}



我想加一個效果,在按加號的時候同時顯示數字和加號,我使用了第二個定時器定時,可是實驗結果是中斷服務函數執行得太慢了,掃描很慢,看不到連續的畫面,效果不好,而且影響下一個按鍵的判斷。。

#include <reg52.h>

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
sbit KEY_IN_0 = P2^4;
sbit KEY_IN_1 = P2^5;
sbit KEY_IN_2 = P2^6;
sbit KEY_IN_3 = P2^7;
sbit KEY_OUT_0 = P2^3;
sbit KEY_OUT_1 = P2^2;
sbit KEY_OUT_2 = P2^1;
sbit KEY_OUT_3 = P2^0;

uchar code LedChar[] = {  //數碼管顯示字符轉換表
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
uchar LedBuff[6] = {  //數碼管顯示緩衝區
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
uchar code KeyCodeMap[4][4] = { //矩陣按鍵編號到標準鍵盤鍵碼的映射表
    { 0x31, 0x32, 0x33, 0x26 }, //數字鍵1、數字鍵2、數字鍵3、向上鍵
    { 0x34, 0x35, 0x36, 0x25 }, //數字鍵4、數字鍵5、數字鍵6、向左鍵
    { 0x37, 0x38, 0x39, 0x28 }, //數字鍵7、數字鍵8、數字鍵9、向下鍵
    { 0x30, 0x1B, 0x0D, 0x27 }  //數字鍵0、ESC鍵、  回車鍵、 向右鍵
};
uchar keyState[4][4] = {  //全部矩陣按鍵的當前狀態
    {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1}
};
uchar code image[] = {
    0xFF,0xE7,0xE7,0x81,0x81,0xE7,0xE7,0xFF
};

uchar T0RH = 0;
uchar T0RL = 0;

void showNumber(ulong num){
    char i;
	uchar buf[6];
    for(i=0; i<6; i++){
        buf[i] = num % 10;
        num /= 10;
    }
    for(i=5; i>=0; i--){
        if(buf[i] == 0) LedBuff[i] = 0xFF;
        else break;
    }
	for(; i>=0; i--){
	    LedBuff[i] = LedChar[buf[i]];
	}
}

void showPicture(){
    TR0 = 0;
    ET0 = 0;
    ADDR3 = 0;
    TMOD &= 0x0F;
    TMOD |= 0x10;
    TH1 = 0xFF;
    TL1 = 0xFE;
    ET1 = 1;
    TR1 = 1;
}

void closePicture(){
    TR1 = 0;
    ET1 = 0;
    ADDR3 = 1;
    ET0 = 1;
    TR0 = 1;
}

void keyAction(uchar keyCode){
    static ulong result = 0;
    static ulong number = 0;
    static bit flag = 0;
    if(keyCode >= 0x30 && keyCode <= 0x39){
        if(flag == 1){
            closePicture();
            flag = 0;
        }
        number = number * 10 + keyCode - 0x30;
        showNumber(number);
    }
    else if(keyCode == 0x26 || keyCode == 0x0D){
        result += number;
        number = 0;
        showNumber(result);
        showPicture();
        flag = 1;
    }
    else if(keyCode == 0x1B){
        if(flag == 1){
            closePicture();
            flag = 0;
        }
        number = 0;
        result = 0;
        showNumber(number);
    }
}

void keyDriver(){
    uchar i, j;
    static uchar backup[4][4] = {
        {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
    };
    for(i=0; i<4; i++){
        for(j=0; j<4; j++){
            if(keyState[i][j] != backup[i][j]){
                if(keyState[i][j] == 0){
                    keyAction(KeyCodeMap[i][j]);
                }
                backup[i][j] = keyState[i][j];
            }
        }
    }
}

void keyScan(){
    static uchar i = 0;
    static uchar keyBuf[4][4] = {
        {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},
        {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}
    };
    uchar j;
    keyBuf[i][0] = (keyBuf[i][0] << 1) | KEY_IN_0;
    keyBuf[i][1] = (keyBuf[i][1] << 1) | KEY_IN_1;
    keyBuf[i][2] = (keyBuf[i][2] << 1) | KEY_IN_2;
    keyBuf[i][3] = (keyBuf[i][3] << 1) | KEY_IN_3;
    for(j=0; j<4; j++) {
        if(keyBuf[i][j] == 0x00){
            keyState[i][j] = 0;
        }
        else if(keyBuf[i][j] == 0xFF){
            keyState[i][j] = 1;
        }
    }
    switch(i){
        case 0: KEY_OUT_0 = 1; KEY_OUT_1 = 0; break;
        case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
        case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
        case 3: KEY_OUT_3 = 1; KEY_OUT_0 = 0; break;
        default: break;
    }
    i = ++i & 0x03;
}

void LEDScan(){
    static uchar i = 0;
    P0 = 0xFF;
    P1 = (P1 & 0xF8) | i;
    P0 = LedBuff[i];
    if(i < 5) i++;
    else i = 0;
}

void setTimer0(uint ms){
    ulong tmp;
    tmp = 11059326 / 12;
    tmp = tmp * ms / 1000;
    tmp = 65536 - tmp;
    tmp += 28;
    T0RL = tmp;
    T0RH = tmp>>8;
}

void interruptTimer0() interrupt 1{
    TH0 = T0RH;
    TL0 = T0RL;
	LEDScan();
	keyScan();
}

void interruptTimer1() interrupt 3{
    static uchar i = 0, j = 0;
	static bit flag = 1;
	if(flag){
        ADDR3 = 0;
	    P0 = 0xFF;
        P1 = (P1 & 0xF8) | i;
        P0 = image[i];
        if(i < 7) i++;
        else{
            i = 0;
            flag = 0;
        }
	}
	else{
	    ADDR3 = 1;
        P0 = 0xFF;
        P1 = (P1 & 0xF8) | j;
        P0 = LedBuff[j];
        if(j < 5) j++;
        else{
            j = 0;
            flag = 1;
        }
	}
	keyScan();
}

void main(){
    EA = 1;
    ENLED = 0;
    ADDR3 = 1;
    TMOD = 0x01;
    setTimer0(1);
    TH0 = T0RH;
    TL0 = T0RL;
    ET0 = 1;
    TR0 = 1;
    LedBuff[0] = LedChar[0];
    while(1){
        keyDriver();
    }
}


發佈了151 篇原創文章 · 獲贊 19 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章