|
一個(gè)簡(jiǎn)單的加減乘除計(jì)算器/*注意上面頭文件"bsp_GOG1.h"包含一個(gè)可選宏定義
若需使用擴(kuò)展板請(qǐng)?jiān)黾尤趾甓x _GOG1Plus
定義方式
菜單 Project->Options for Target->C51->Define
在此處填入 “_GOG1Plus”
在此代碼完全兼容,第三次課的矩陣按鍵程序,在此感謝魏同學(xué)的幫助 */
/*
計(jì)算器功能實(shí)現(xiàn):4位數(shù)字的加,減,乘法,除法沒有做商的小數(shù)部分
1.對(duì)輸入運(yùn)算數(shù)的有效性檢查,即超過(guò)9999時(shí),顯示錯(cuò)誤;
2,用LED--》D3來(lái)指示系統(tǒng)的正常運(yùn)行狀態(tài)
3,運(yùn)算的結(jié)果超過(guò)9999時(shí),提示錯(cuò)誤顯示;
4,當(dāng)系統(tǒng)運(yùn)行錯(cuò)誤時(shí),或者顯示亂碼時(shí),按A鍵清除數(shù)碼管顯示;
5,除法運(yùn)算時(shí),的二個(gè)運(yùn)算數(shù)為0時(shí),提示錯(cuò)誤顯示
6, 運(yùn)算表達(dá)式不完整時(shí),報(bào)錯(cuò):
(1)無(wú)數(shù) * 第二個(gè)數(shù) = 報(bào)錯(cuò)
(2)第一個(gè)數(shù) * 無(wú)數(shù) = 報(bào)錯(cuò)
(3)直接按等號(hào),報(bào)錯(cuò)
7,D3 LED燈實(shí)際是隔1ms 閃爍一次,
*/
/*矩陣按鍵 功能定義:
#define ADD 15 //'#':加法 S15
#define SUB 12 //'C':減法 S12
#define MUL 14 //'*':乘法 S13
#define DIV 11 //'B':除法 S8
#define EQU 13 //'D':等于 S16
#define CLE 10 //'A':清除 S4
仿真圖:
仿真圖.png (44.65 KB, 下載次數(shù): 93)
下載附件
2018-11-15 20:15 上傳
單片機(jī)源程序如下:
- #include <REG52.H> //51單片機(jī)標(biāo)準(zhǔn)寄存器聲明頭文件
- #include "bsp_GOG1.h" //這個(gè)頭文件用于映射GOG1學(xué)習(xí)板載硬件接口
- /*計(jì)算器的運(yùn)算狀態(tài)定義:*/
- #define NoKey 0xaa //沒有按鍵按下的狀態(tài)
- #define ErrKey 0xff //錯(cuò)誤的按鍵狀態(tài)/干擾
- #define DpyErr 0x0e //錯(cuò)誤顯示狀態(tài)(碼表數(shù)組第14個(gè)元素:'E')
- #define DpyCle 0x10 //清屏(碼表數(shù)組第16個(gè)元素:0xff 關(guān)閉數(shù)碼管)
- #define InCount 0xf0 //有運(yùn)算符輸入狀態(tài)
- #define InErrEqu 0x0f //有等號(hào)輸入狀態(tài)
- #define NoCountFlag 0xa5 //沒有運(yùn)算符的狀態(tài)
- /*矩陣按鍵 功能定義: */
- #define ADD 15 //'#':加法 S15
- #define SUB 12 //'C':減法 S12
- #define MUL 14 //'*':乘法 S13
- #define DIV 11 //'B':除法 S8
- #define EQU 13 //'D':等于 S16
- #define CLE 10 //'A':清除 S4
- /*相關(guān)子函數(shù)的聲明:*/
- void delayms(unsigned int ms); //延時(shí)函數(shù)
- void SegDisplay(unsigned char casebit); //數(shù)碼管顯示函數(shù)
- unsigned char ReadKeyPad(void); //讀取矩陣鍵盤函數(shù)
- void Timer0Init(void); //定時(shí)器0初始化函數(shù)
- unsigned char CheckInput(void); //計(jì)算器檢查輸入狀態(tài)函數(shù)
- void DatUnpack(unsigned int dat); //計(jì)算器數(shù)據(jù)拆分函數(shù)
- bit CheckNum(unsigned int dat); //計(jì)算器數(shù)據(jù)有效性檢查函數(shù)
- void WarmDpy(unsigned char err); //計(jì)算器錯(cuò)誤顯示函數(shù)
- void ComputeState(unsigned char dat); //計(jì)算器計(jì)算過(guò)程函數(shù)
- //數(shù)碼管段碼表 共陽(yáng) 17個(gè)元素: 0~F & 0xff
- unsigned char code SegCode[17]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
- 0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
- unsigned int Ans; //運(yùn)算結(jié)果
- bit AnsFlag=0; //運(yùn)算結(jié)果存在標(biāo)志
- bit InFlag1=0; //輸入有效數(shù)字1標(biāo)志
- bit InFlag2=0; //輸入有效數(shù)字2標(biāo)志
- unsigned char CountFlag; //運(yùn)算符
- unsigned int temp1=0,temp2=0;//輸入的2個(gè)運(yùn)算的數(shù)字
- unsigned char DisBuff[4]={DpyCle,DpyCle,DpyCle,DpyCle};//數(shù)碼管顯示緩存
- /*******************************************************************************
- * @brief mian (簡(jiǎn)介)
- * @param 無(wú) (參數(shù))
- * @retval 無(wú) (返回值)
- ******************************************************************************/
- void main(void) //程序從這里開始
- {
- unsigned char in; //保存單個(gè)按鍵值的變量
-
- CountFlag=NoCountFlag; //運(yùn)算符初始狀態(tài)
- Timer0Init(); //定時(shí)器0初始化
- while(1)
- {
- in=CheckInput();
- while(in == NoKey) in=CheckInput(); //沒有按鍵按下,在此等待
- if(in !=ErrKey) //按鍵有效
- {
- ComputeState(in);
- }
- else WarmDpy(DpyErr); //按鍵無(wú)效,報(bào)錯(cuò) 'E'
- }
- }
- /*******************************************************************************
- * @brief ComputeState: 計(jì)算過(guò)程程序
- * @param unsigned char dat
- * @retval 無(wú)
- *******************************************************************************/
- void ComputeState(unsigned char dat)
- {
- unsigned int num; //保存運(yùn)算操作數(shù)的變量
- if(AnsFlag == 1) //判斷上一次運(yùn)算結(jié)果完成標(biāo)志
- {
- WarmDpy(DpyCle); //清屏
- AnsFlag=0; //清除有效運(yùn)算完成標(biāo)志
- }
- if((dat !=InCount)&(dat !=InErrEqu)&(dat <10)) //按下的鍵為數(shù)字
- {
- if(CountFlag == NoCountFlag) //沒有運(yùn)算符存在,保存第一個(gè)數(shù)
- {
- num = temp1;
- num *= 10; //輸入的數(shù)字依次進(jìn)高位
- num += dat;
- if( CheckNum(num)==1 ) //判斷數(shù)據(jù)有效性
- { //有效在數(shù)字范圍
- temp1 = num; //保存第一個(gè)數(shù)字
- InFlag1 = 1; //輸入有效數(shù)字1標(biāo)志
- DatUnpack(temp1); //拆分?jǐn)?shù)據(jù),更新顯示緩存
- }
- else WarmDpy(DpyErr); //超出范圍報(bào)錯(cuò)
- }
- else //運(yùn)算符存在 ,保存第二個(gè)數(shù)
- {
- num = temp2;
- num *= 10;
- num += dat;
- if(CheckNum(num)==1)
- {
- temp2 = num;
- InFlag2 = 1; //輸入有效數(shù)字2標(biāo)志
- WarmDpy(DpyCle); //清除第一個(gè)數(shù)的顯示,消除'余暉'
- DatUnpack(temp2);//更新顯示緩存
- }
- else WarmDpy(DpyErr);
- }
- }
- else //按下的鍵為非數(shù)字(4則運(yùn)算符被保存,這里考慮 清除鍵和 錯(cuò)誤等號(hào))
- {
- if(CLE == dat) //按下的為清除鍵
- {
- CountFlag = NoCountFlag; //清除運(yùn)算符
- InFlag1 =0; //清除輸入有效數(shù)字1標(biāo)志
- InFlag2 =0; //清除輸入有效數(shù)字2標(biāo)志
- AnsFlag=0; //清除運(yùn)算結(jié)果存在標(biāo)志
- temp1=0,temp2=0; //清除輸入的2個(gè)運(yùn)算數(shù)
- WarmDpy(DpyCle); //清屏
- Ans=0; //清除上一次運(yùn)算結(jié)果
- }
-
- if(InErrEqu == dat) //運(yùn)算表達(dá)式不完整時(shí),按下等號(hào)的情況
- WarmDpy(DpyErr); //報(bào)錯(cuò) 'E'
- }
- }
- /*******************************************************************************
- * @brief ReadKeyPad 用于讀取矩陣鍵盤鍵值
- * @param 無(wú)
- * @retval 矩陣鍵盤鍵值
- * @note 鍵盤鍵值設(shè)置請(qǐng)修改case分支臨時(shí)變量b的賦值
- 0xff 作為錯(cuò)誤代碼,表示讀取出錯(cuò)
- ******************************************************************************/
- unsigned char ReadKeyPad(void)
- {
- unsigned char a,c,b=NoKey; //b 初始值為無(wú)按鍵的狀態(tài)
- KeyPad = 0x0f; //初始狀態(tài),行號(hào)(P3^0~P3^3)高電平,列號(hào)(P3^4~P3^7)低電平
- if(KeyPad != 0x0f)
- {
- delayms(20); //按鍵消抖動(dòng)(延時(shí)實(shí)現(xiàn))
- if(KeyPad != 0x0f) //按鍵被按下,初始狀態(tài)改變
- {
- a = KeyPad; //讀取矩陣鍵盤的行號(hào)
- }
- KeyPad = 0xf0; //初始狀態(tài)反轉(zhuǎn)
- c = KeyPad; //讀取矩陣鍵盤的列號(hào)
- a |= c; //按位'或',通過(guò)行號(hào),列號(hào)唯一確定矩陣按鍵值
- switch (a) {
- case 0xee:
- b = 1; //S1
- break;
- case 0xed:
- b = 4; //S5
- break;
- case 0xeb:
- b = 7; //S9
- break;
- case 0xe7:
- b = MUL; //S13'MUL'
- break;
- case 0xde:
- b = 2; //S2
- break;
- case 0xdd:
- b = 5; //S6
- break;
- case 0xdb:
- b = 8; //S10
- break;
- case 0xd7:
- b = 0; //S14
- break;
- case 0xbe:
- b = 3; //S3
- break;
- case 0xbd:
- b = 6; //S7
- break;
- case 0xbb:
- b = 9; //S11
- break;
- case 0xb7:
- b = ADD; //S15 'ADD'
- break;
- case 0x7e:
- b = CLE; //S4 'CLE'
- break;
- case 0x7d:
- b = DIV; //S8 'DIV'
- break;
- case 0x7b:
- b = SUB; //S12 'SUB'
- break;
- case 0x77:
- b = EQU; //S16 '='
- break;
- default : //沒有和 a 的匹配項(xiàng)
- b = ErrKey; //錯(cuò)誤的按鍵值
- break;
- }
- KeyPad = 0xf0; //松手檢測(cè)
- while (KeyPad != 0xf0); //當(dāng)沒有松手,將在此一直等待
- }
- return (b); //返回讀取的按鍵值
- }
- /******************************************************************************
- * @brief delayms 毫秒級(jí)延時(shí)函數(shù)
- * @param ms 延時(shí)的毫秒數(shù) 允許值 unsigned int范圍
- * @retval 無(wú)
- * @attention 這個(gè)函數(shù)只是用于12T 8051內(nèi)核的單片機(jī)運(yùn)行于12Mhz
- *****************************************************************************/
- void delayms(unsigned int ms) //延時(shí)子程序(晶振12Mhz)
- {
- unsigned char i;
- while(ms--)
- {
- for(i = 0; i < 120; i++);
- }
- }
- /******************************************************************************
- * @brief SegDisplay 數(shù)碼管顯示&定時(shí)器中斷程序組成動(dòng)態(tài)顯示
- * @param casebit 用于選擇數(shù)碼管的位 允許值 0~4
- * @retval 無(wú)
- * @attention 這個(gè)函數(shù)需配合定時(shí)器中斷服務(wù)程序
- *****************************************************************************/
- void SegDisplay(unsigned char casebit)
- {
- Seg7_Bits = 0xff; //關(guān)閉所有數(shù)碼管
- Seg7_Data =SegCode[DisBuff[casebit]];//先把段碼值賦給P1(段選端口)
- switch(casebit)
- {
- case 0:
- Seg7_Bit1 = 0;
- break;
- case 1:
- Seg7_Bit2 = 0;
- break;
- case 2:
- Seg7_Bit3 = 0;
- break;
- case 3:
- Seg7_Bit4 = 0;
- break;
- default :
- Seg7_Bits = 0xff; //關(guān)閉所有數(shù)碼管
- Seg7_Data = 0xff;
- break;
- }
- }
- /************************************************************************************
- * @brief DatUnpack:數(shù)據(jù)拆分,同時(shí)把數(shù)據(jù)的千位,百位,十位,個(gè)位賦給顯示緩存數(shù)組DisBuff[]
- * @param unsigned int dat
- * @retval 無(wú)
- ***********************************************************************************/
- void DatUnpack(unsigned int dat)
- {
- if((dat<10)) //1位數(shù)
- DisBuff[0]=dat;
- else if((dat<100)&&(dat>=10)) //2位數(shù)
- {
- DisBuff[1]=dat/10;
- DisBuff[0]=dat%10;
- }
- else if((dat<1000)&&(dat>=100)) //3位數(shù)
- {
- DisBuff[2]=dat/100;
- DisBuff[1]=dat%100/10;
- DisBuff[0]=dat%100%10;
- }
- else if ((dat<10000)&&(dat>=1000))//4位數(shù)
- {
- DisBuff[3]=dat/1000;
- DisBuff[2]=dat%1000/100;
- DisBuff[1]=dat%1000%100/10;
- DisBuff[0]=dat%1000%100%10;
- }
- }
- /*******************************************************************************
- * @brief unsigned char CheckInput(): 檢查矩陣鍵盤輸入按鍵的類型(簡(jiǎn)介)
- * @param 無(wú) (參數(shù))
- * @retval 數(shù)字,功能鍵(CLE,EQU,+,-,*,/),無(wú)按鍵的狀態(tài) (返回值)
- ******************************************************************************/
- unsigned char CheckInput(void)
- {
- unsigned char x;
- x=ReadKeyPad(); //調(diào)用讀按鍵子程序
- if(x != ErrKey) //是否為錯(cuò)誤按鍵值
- {
- if((x<10)|(x == NoKey)| (x == CLE))//按下的為數(shù)字,或沒有按鍵按下,或清除鍵
- {
- return (x);
- }
- else //按下的為 運(yùn)算符(四則運(yùn)算 和 等號(hào))
- {
- if(x == EQU) // 按下的為 等號(hào)"="
- {
- switch (CountFlag)
- {
- case ADD: Ans = temp1+temp2; break;
- case SUB: Ans = temp1-temp2; break;
- case MUL: Ans = temp1*temp2; break;
- case DIV: if (temp2 == 0) //除法分母為0,報(bào)錯(cuò)
- {
- WarmDpy(DpyErr);
- break;
- }
- else
- {
- Ans = temp1/temp2;//只計(jì)算除法商的整數(shù),暫沒有考慮小數(shù)
- break;
- }
- }
- if( CheckNum(Ans)&&(InFlag1 ==1)&&(InFlag2 ==1))//檢測(cè)運(yùn)算的有效性
- {
- DatUnpack(Ans); //運(yùn)算結(jié)果拆分,更新顯示緩存
- CountFlag = NoCountFlag; //清除運(yùn)算符
- temp1=0,temp2=0; //清除運(yùn)算數(shù)字
- AnsFlag = 1; //運(yùn)算結(jié)果存在標(biāo)志
- InFlag1 =0; //清除有效數(shù)字輸入標(biāo)志
- InFlag2 =0;
- Ans=0; //清除運(yùn)算結(jié)果
- return (NoKey); //此次運(yùn)算完成,返回?zé)o按鍵狀態(tài)
- }
- else //WarmDpy(DpyErr) ;//運(yùn)算表達(dá)式不完整或結(jié)果超出范圍,報(bào)錯(cuò)
- return (InErrEqu); //返回有等號(hào)輸入的狀態(tài)
- }
- else //按下的為 4則 運(yùn)算符(+ ,-,*, /)
- {
- CountFlag = x; //保存運(yùn)算符
- return (InCount); //返回有運(yùn)算符輸入的狀態(tài)
- }
- }
- }
- else return (ErrKey); //返回錯(cuò)誤按鍵值狀態(tài)
- }
- /*******************************************************************************
- * @brief CheckNum: 檢查計(jì)算器運(yùn)算數(shù)的有效性
- * @param dat
- * @retval bit 有效: 1,無(wú)效: 0
- ******************************************************************************/
- bit CheckNum(unsigned int dat)
- {
- if (dat < 10000)
- return 1; //數(shù)據(jù)有效
- else
- return 0;
- }
- /*******************************************************************************
- * @brief WarmDpy:數(shù)碼管錯(cuò)誤顯示
- * @param err 實(shí)則:'E'的碼段值元素的下標(biāo)
- * @retval 無(wú)
- ******************************************************************************/
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
0.png (8.53 KB, 下載次數(shù): 79)
下載附件
2018-11-16 03:02 上傳
所有資料51hei提供下載:
counter程序(V2.0).zip
(122.64 KB, 下載次數(shù): 165)
2018-11-15 20:14 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
|