欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
簡易單片機計算器的proteus仿真實現
[打印本頁]
作者:
CRan
時間:
2018-11-15 20:17
標題:
簡易單片機計算器的proteus仿真實現
一個簡單的加減乘除計算器/*注意上面頭文件"bsp_GOG1.h"包含一個可選宏定義
若需使用擴展板請增加全局宏定義 _GOG1Plus
定義方式
菜單 Project->Options for Target->C51->Define
在此處填入 “_GOG1Plus”
在此代碼完全兼容,第三次課的矩陣按鍵程序,在此感謝魏同學的幫助 */
/*
計算器功能實現:4位數字的加,減,乘法,除法沒有做商的小數部分
1.對輸入運算數的有效性檢查,即超過9999時,顯示錯誤;
2,用LED--》D3來指示系統的正常運行狀態
3,運算的結果超過9999時,提示錯誤顯示;
4,當系統運行錯誤時,或者顯示亂碼時,按A鍵清除數碼管顯示;
5,除法運算時,的二個運算數為0時,提示錯誤顯示
6, 運算表達式不完整時,報錯:
(1)無數 * 第二個數 = 報錯
(2)第一個數 * 無數 = 報錯
(3)直接按等號,報錯
7,D3 LED燈實際是隔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, 下載次數: 93)
下載附件
2018-11-15 20:15 上傳
單片機源程序如下:
#include <REG52.H> //51單片機標準寄存器聲明頭文件
#include "bsp_GOG1.h" //這個頭文件用于映射GOG1學習板載硬件接口
/*計算器的運算狀態定義:*/
#define NoKey 0xaa //沒有按鍵按下的狀態
#define ErrKey 0xff //錯誤的按鍵狀態/干擾
#define DpyErr 0x0e //錯誤顯示狀態(碼表數組第14個元素:'E')
#define DpyCle 0x10 //清屏(碼表數組第16個元素:0xff 關閉數碼管)
#define InCount 0xf0 //有運算符輸入狀態
#define InErrEqu 0x0f //有等號輸入狀態
#define NoCountFlag 0xa5 //沒有運算符的狀態
/*矩陣按鍵 功能定義: */
#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
/*相關子函數的聲明:*/
void delayms(unsigned int ms); //延時函數
void SegDisplay(unsigned char casebit); //數碼管顯示函數
unsigned char ReadKeyPad(void); //讀取矩陣鍵盤函數
void Timer0Init(void); //定時器0初始化函數
unsigned char CheckInput(void); //計算器檢查輸入狀態函數
void DatUnpack(unsigned int dat); //計算器數據拆分函數
bit CheckNum(unsigned int dat); //計算器數據有效性檢查函數
void WarmDpy(unsigned char err); //計算器錯誤顯示函數
void ComputeState(unsigned char dat); //計算器計算過程函數
//數碼管段碼表 共陽 17個元素: 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; //運算結果
bit AnsFlag=0; //運算結果存在標志
bit InFlag1=0; //輸入有效數字1標志
bit InFlag2=0; //輸入有效數字2標志
unsigned char CountFlag; //運算符
unsigned int temp1=0,temp2=0;//輸入的2個運算的數字
unsigned char DisBuff[4]={DpyCle,DpyCle,DpyCle,DpyCle};//數碼管顯示緩存
/*******************************************************************************
* @brief mian (簡介)
* @param 無 (參數)
* @retval 無 (返回值)
******************************************************************************/
void main(void) //程序從這里開始
{
unsigned char in; //保存單個按鍵值的變量
CountFlag=NoCountFlag; //運算符初始狀態
Timer0Init(); //定時器0初始化
while(1)
{
in=CheckInput();
while(in == NoKey) in=CheckInput(); //沒有按鍵按下,在此等待
if(in !=ErrKey) //按鍵有效
{
ComputeState(in);
}
else WarmDpy(DpyErr); //按鍵無效,報錯 'E'
}
}
/*******************************************************************************
* @brief ComputeState: 計算過程程序
* @param unsigned char dat
* @retval 無
*******************************************************************************/
void ComputeState(unsigned char dat)
{
unsigned int num; //保存運算操作數的變量
if(AnsFlag == 1) //判斷上一次運算結果完成標志
{
WarmDpy(DpyCle); //清屏
AnsFlag=0; //清除有效運算完成標志
}
if((dat !=InCount)&(dat !=InErrEqu)&(dat <10)) //按下的鍵為數字
{
if(CountFlag == NoCountFlag) //沒有運算符存在,保存第一個數
{
num = temp1;
num *= 10; //輸入的數字依次進高位
num += dat;
if( CheckNum(num)==1 ) //判斷數據有效性
{ //有效在數字范圍
temp1 = num; //保存第一個數字
InFlag1 = 1; //輸入有效數字1標志
DatUnpack(temp1); //拆分數據,更新顯示緩存
}
else WarmDpy(DpyErr); //超出范圍報錯
}
else //運算符存在 ,保存第二個數
{
num = temp2;
num *= 10;
num += dat;
if(CheckNum(num)==1)
{
temp2 = num;
InFlag2 = 1; //輸入有效數字2標志
WarmDpy(DpyCle); //清除第一個數的顯示,消除'余暉'
DatUnpack(temp2);//更新顯示緩存
}
else WarmDpy(DpyErr);
}
}
else //按下的鍵為非數字(4則運算符被保存,這里考慮 清除鍵和 錯誤等號)
{
if(CLE == dat) //按下的為清除鍵
{
CountFlag = NoCountFlag; //清除運算符
InFlag1 =0; //清除輸入有效數字1標志
InFlag2 =0; //清除輸入有效數字2標志
AnsFlag=0; //清除運算結果存在標志
temp1=0,temp2=0; //清除輸入的2個運算數
WarmDpy(DpyCle); //清屏
Ans=0; //清除上一次運算結果
}
if(InErrEqu == dat) //運算表達式不完整時,按下等號的情況
WarmDpy(DpyErr); //報錯 'E'
}
}
/*******************************************************************************
* @brief ReadKeyPad 用于讀取矩陣鍵盤鍵值
* @param 無
* @retval 矩陣鍵盤鍵值
* @note 鍵盤鍵值設置請修改case分支臨時變量b的賦值
0xff 作為錯誤代碼,表示讀取出錯
******************************************************************************/
unsigned char ReadKeyPad(void)
{
unsigned char a,c,b=NoKey; //b 初始值為無按鍵的狀態
KeyPad = 0x0f; //初始狀態,行號(P3^0~P3^3)高電平,列號(P3^4~P3^7)低電平
if(KeyPad != 0x0f)
{
delayms(20); //按鍵消抖動(延時實現)
if(KeyPad != 0x0f) //按鍵被按下,初始狀態改變
{
a = KeyPad; //讀取矩陣鍵盤的行號
}
KeyPad = 0xf0; //初始狀態反轉
c = KeyPad; //讀取矩陣鍵盤的列號
a |= c; //按位'或',通過行號,列號唯一確定矩陣按鍵值
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 的匹配項
b = ErrKey; //錯誤的按鍵值
break;
}
KeyPad = 0xf0; //松手檢測
while (KeyPad != 0xf0); //當沒有松手,將在此一直等待
}
return (b); //返回讀取的按鍵值
}
/******************************************************************************
* @brief delayms 毫秒級延時函數
* @param ms 延時的毫秒數 允許值 unsigned int范圍
* @retval 無
* @attention 這個函數只是用于12T 8051內核的單片機運行于12Mhz
*****************************************************************************/
void delayms(unsigned int ms) //延時子程序(晶振12Mhz)
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}
/******************************************************************************
* @brief SegDisplay 數碼管顯示&定時器中斷程序組成動態顯示
* @param casebit 用于選擇數碼管的位 允許值 0~4
* @retval 無
* @attention 這個函數需配合定時器中斷服務程序
*****************************************************************************/
void SegDisplay(unsigned char casebit)
{
Seg7_Bits = 0xff; //關閉所有數碼管
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; //關閉所有數碼管
Seg7_Data = 0xff;
break;
}
}
/************************************************************************************
* @brief DatUnpack:數據拆分,同時把數據的千位,百位,十位,個位賦給顯示緩存數組DisBuff[]
* @param unsigned int dat
* @retval 無
***********************************************************************************/
void DatUnpack(unsigned int dat)
{
if((dat<10)) //1位數
DisBuff[0]=dat;
else if((dat<100)&&(dat>=10)) //2位數
{
DisBuff[1]=dat/10;
DisBuff[0]=dat%10;
}
else if((dat<1000)&&(dat>=100)) //3位數
{
DisBuff[2]=dat/100;
DisBuff[1]=dat%100/10;
DisBuff[0]=dat%100%10;
}
else if ((dat<10000)&&(dat>=1000))//4位數
{
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(): 檢查矩陣鍵盤輸入按鍵的類型(簡介)
* @param 無 (參數)
* @retval 數字,功能鍵(CLE,EQU,+,-,*,/),無按鍵的狀態 (返回值)
******************************************************************************/
unsigned char CheckInput(void)
{
unsigned char x;
x=ReadKeyPad(); //調用讀按鍵子程序
if(x != ErrKey) //是否為錯誤按鍵值
{
if((x<10)|(x == NoKey)| (x == CLE))//按下的為數字,或沒有按鍵按下,或清除鍵
{
return (x);
}
else //按下的為 運算符(四則運算 和 等號)
{
if(x == EQU) // 按下的為 等號"="
{
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,報錯
{
WarmDpy(DpyErr);
break;
}
else
{
Ans = temp1/temp2;//只計算除法商的整數,暫沒有考慮小數
break;
}
}
if( CheckNum(Ans)&&(InFlag1 ==1)&&(InFlag2 ==1))//檢測運算的有效性
{
DatUnpack(Ans); //運算結果拆分,更新顯示緩存
CountFlag = NoCountFlag; //清除運算符
temp1=0,temp2=0; //清除運算數字
AnsFlag = 1; //運算結果存在標志
InFlag1 =0; //清除有效數字輸入標志
InFlag2 =0;
Ans=0; //清除運算結果
return (NoKey); //此次運算完成,返回無按鍵狀態
}
else //WarmDpy(DpyErr) ;//運算表達式不完整或結果超出范圍,報錯
return (InErrEqu); //返回有等號輸入的狀態
}
else //按下的為 4則 運算符(+ ,-,*, /)
{
CountFlag = x; //保存運算符
return (InCount); //返回有運算符輸入的狀態
}
}
}
else return (ErrKey); //返回錯誤按鍵值狀態
}
/*******************************************************************************
* @brief CheckNum: 檢查計算器運算數的有效性
* @param dat
* @retval bit 有效: 1,無效: 0
******************************************************************************/
bit CheckNum(unsigned int dat)
{
if (dat < 10000)
return 1; //數據有效
else
return 0;
}
/*******************************************************************************
* @brief WarmDpy:數碼管錯誤顯示
* @param err 實則:'E'的碼段值元素的下標
* @retval 無
******************************************************************************/
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png
(8.53 KB, 下載次數: 79)
下載附件
2018-11-16 03:02 上傳
所有資料51hei提供下載:
counter程序(V2.0).zip
(122.64 KB, 下載次數: 165)
2018-11-15 20:14 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
1525138883
時間:
2019-4-22 07:53
下載試試
作者:
a957242744
時間:
2019-10-8 13:57
謝謝樓主,辛苦啦,先下載下來看看
作者:
亞卡西
時間:
2019-10-11 21:13
一共多少行啊. 看到后面舍不得花錢.
作者:
亞卡西
時間:
2019-10-11 21:13
細致得一
作者:
癡癡夢幻中心愛
時間:
2020-6-15 10:45
樓主在嗎?
作者:
癡癡夢幻中心愛
時間:
2020-6-15 10:45
能不能加個好友私聊 我想下載這個
作者:
sfdsl1
時間:
2020-6-26 18:26
把矩陣鍵盤每一個按鍵都標記了
作者:
zongziao
時間:
2020-11-13 10:20
這是編譯之后的源程序嗎?有沒有沒編譯的
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1