51单片机 带修改错误功能的计算器

来源:互联网 发布:低频反射扬声器 知乎 编辑:程序博客网 时间:2024/06/07 07:50
utilities.h
#ifndef UTILITIES_H_INCLUDED#define UTILITIES_H_INCLUDEDtypedef unsigned char uchar, BYTE, uint8;typedef unsigned int uint, WORD, uint16;typedef unsigned long ulong, DWORD, uint32;typedef char int8;typedef int int16;typedef long int32;typedef unsigned char * uchar_p;typedef unsigned int * uint_p;typedef unsigned long * ulong_p;typedef char * char_p;typedef int * int_p;typedef long * long_p;#endif // UTILITIES_H_INCLUDED

keyBoard.c

#include <reg52.h>#include "utilities.h"sbit KEY_OUT_3 = P2^0;sbit KEY_OUT_2 = P2^1;sbit KEY_OUT_1 = P2^2;sbit KEY_OUT_0 = P2^3;sbit KEY_IN_0 = P2^4;sbit KEY_IN_1 = P2^5;sbit KEY_IN_2 = P2^6;sbit KEY_IN_3 = P2^7;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 pdata keyState[4][4] = {  //全部矩阵按键的当前状态    {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1}};extern void keyAction(uchar keyCode);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;}

digitalTube.c
#include <reg52.h>#include "utilities.h"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};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 LEDScan() {    static uchar i = 0;    P0 = 0xFF;    P1 = (P1 & 0xF8) | i;    P0 = LEDBuff[i];    if (i < 5)        i++;    else        i = 0;}

timer.c
#include <reg52.h>#include "utilities.h"#define TIMER0#define TIMER0_MOD1#if defined (TIMER0)uchar T0RH = 0;uchar T0RL = 0;#if defined (TIMER0_MOD1)void setTmr0(uint ms) {    ulong tmp;    tmp = 11059326 / 12;    tmp = tmp * ms / 1000;    tmp = 65536 - tmp;    tmp += 28;    T0RL = tmp;    T0RH = tmp>>8;}#endif // defined#endif // defined

calculator.c
/**********************************************************    加减乘除计算器,能实现连续的运算,并且提供修改功能:    对于算符来说,以最后输入的算符为准。    测试样例:    12 + 256 * 9 - 53 / 2    3 + - * 5    6 + - 2 / * 7***********************************************************/#include <reg52.h>#include "utilities.h"sbit ADDR0 = P1^0;sbit ADDR1 = P1^1;sbit ADDR2 = P1^2;sbit ADDR3 = P1^3;sbit ENLED = P1^4;extern uchar T0RH;extern uchar T0RL;extern uchar LEDBuff[6];extern uchar code LEDChar[];extern void showNumber(ulong num);extern void LEDScan();extern void keyScan();extern void keyDriver();extern void setTmr0(uint ms);void keyAction(uchar keyCode) {    static ulong result = 0Lu;    static ulong number = 0Lu;    static uchar opPre = 0x26;static bit preIsOp = 0;    if (keyCode >= 0x30 && keyCode <= 0x39) {           //数字键        number = number * 10 + keyCode - 0x30;        showNumber(number);        preIsOp = 0;    }    else if ((keyCode >= 0x25 && keyCode <= 0x28) || keyCode == 0x0D) {      //上下左右,加减乘除;回车键,相当于等于键        if (!preIsOp) {            switch (opPre) {                case 0x26: result += number; break;                case 0x28: result -= number; break;                case 0x25: result /= number; break;                case 0x27: result *= number; break;                case 0x0D: result = number; break;                default: break;            }            number = 0;            showNumber(result);        }        opPre = keyCode;        preIsOp = 1;    }    else if (keyCode == 0x1B) {     //ESC键        number = 0Lu;        result = 0Lu;        showNumber(0Lu);        preIsOp = 0;    }    else {        preIsOp = 0;    }}void interruptTmr0() interrupt 1 {    TH0 = T0RH;    TL0 = T0RL;LEDScan();keyScan();}void main() {    EA = 1;    ENLED = 0;    ADDR3 = 1;    TMOD = 0x01;    setTmr0(1);    TH0 = T0RH;    TL0 = T0RL;    ET0 = 1;    TR0 = 1;    LEDBuff[0] = LEDChar[0];    while (1) {        keyDriver();    }}


0 0
原创粉丝点击