標(biāo)題: 一個(gè)簡單的計(jì)算器 單片機(jī)程序(含原理圖,代碼注釋) [打印本頁]
作者: 張大仙123 時(shí)間: 2019-10-13 12:43
標(biāo)題: 一個(gè)簡單的計(jì)算器 單片機(jī)程序(含原理圖,代碼注釋)
0.png (24.28 KB, 下載次數(shù): 33)
下載附件
2019-10-13 18:37 上傳
用的是普中的開發(fā)板,下面是程序:#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit LcdEn_P = P2^5; // 1602液晶的EN管腳
sbit LcdRw_P = P2^6; // 1602液晶的RW管腳
sbit LcdRs_P = P2^7; // 1602液晶的RS管腳
ulong num1; // 運(yùn)算數(shù)1
ulong num2; // 運(yùn)算數(shù)2
ulong num3; // 計(jì)算結(jié)果
uchar cal; // 運(yùn)算符號(hào),1加,2減,3乘,4除
uchar num1_flag; // 運(yùn)算數(shù)1的輸入標(biāo)志
uchar num2_flag; // 運(yùn)算數(shù)2的輸入標(biāo)志
/*********************************************************/
// 毫秒級(jí)的延時(shí)函數(shù),time是要延時(shí)的毫秒數(shù)
/*********************************************************/
void DelayMs(uint time)
{
uint i,j;
for(i=0;i<time;i++)
for(j=0;j<112;j++);
}
/*********************************************************/
// 1602液晶寫命令函數(shù),cmd就是要寫入的命令
/*********************************************************/
void LcdWriteCmd(uchar cmd)
{
LcdRs_P = 0;
LcdRw_P = 0;
LcdEn_P = 0;
P0=cmd;
DelayMs(2);
LcdEn_P = 1;
DelayMs(2);
LcdEn_P = 0;
}
/*********************************************************/
// 1602液晶寫數(shù)據(jù)函數(shù),dat就是要寫入的數(shù)據(jù)
/*********************************************************/
void LcdWriteData(uchar dat)
{
LcdRs_P = 1;
LcdRw_P = 0;
LcdEn_P = 0;
P0=dat;
DelayMs(2);
LcdEn_P = 1;
DelayMs(2);
LcdEn_P = 0;
}
/*********************************************************/
// 1602液晶初始化函數(shù)
/*********************************************************/
void LcdInit()
{
LcdWriteCmd(0x38); // 16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)口
LcdWriteCmd(0x0C); // 開顯示,不顯示光標(biāo)
LcdWriteCmd(0x06); // 地址加1,當(dāng)寫入數(shù)據(jù)后光標(biāo)右移
LcdWriteCmd(0x01); // 清屏
}
/*********************************************************/
// 液晶光標(biāo)定位函數(shù)
/*********************************************************/
void LcdGotoXY(uchar line,uchar column)
{
// 第一行
if(line==0)
LcdWriteCmd(0x80+column);
// 第二行
if(line==1)
LcdWriteCmd(0x80+0x40+column);
}
/*********************************************************/
// 液晶輸出字符串函數(shù)
/*********************************************************/
void LcdPrintStr(uchar *str)
{
while(*str!='\0')
LcdWriteData(*str++);
}
/*********************************************************/
// 液晶輸出數(shù)字
/*********************************************************/
void LcdPrintNum(uchar num)
{
LcdWriteData(num+0x30);
}
/**********************************************************
矩陣鍵盤掃描程序.
如果掃描到有按鍵按下,則返回按鍵值,返回值情況如下所示:
-------------------------------------------------------------
| 第1列 第2列 第3列 第4列 |
|第1行 1 2 3 10 |
|第2行 4 5 6 11 |
|第3行 7 8 9 12 |
|第4行 13 0 14 15 |
------------------------------------------------------------
如果掃描不到有按鍵按下,則返回99
**********************************************************/
uchar KeyScanf()
{
uchar ret,temp1,temp2;
P1=0x0f;
if(P1!=0x0f)
{
DelayMs(15);
if(P1!=0x0f)
{
temp1=P1; // 判斷出是哪一行按鍵按下
P1=0xf0;
DelayMs(5);
temp2=P1; // 判斷出是哪一列按鍵被按下
ret=temp1|temp2; // 通過行和列的值,確定是哪個(gè)按鍵被按下
switch(ret)
{
case 0xe7: return 1;
case 0xd7: return 2;
case 0xb7: return 3;
case 0x77: return 10;
case 0xeb: return 4;
case 0xdb: return 5;
case 0xbb: return 6;
case 0x7b: return 11;
case 0xed: return 7;
case 0xdd: return 8;
case 0xbd: return 9;
case 0x7d: return 12;
case 0xee: return 13;
case 0xde: return 0;
case 0xbe: return 14;
case 0x7e: return 15;
}
return ret;
}
}
return 99;
}
/*********************************************************/
// 主函數(shù)
/*********************************************************/
void main()
{
uchar ret;
uchar i;
LcdInit();
while(1)
{
LcdWriteCmd(0x01); // 清除屏幕顯示
LcdWriteCmd(0x0f); // 開啟光標(biāo)閃爍
num1=0; // 運(yùn)算數(shù)1 清零
num2=0; // 運(yùn)算數(shù)2 清零
num3=0; // 計(jì)算結(jié)果 清零
cal=0; // 運(yùn)算符號(hào) 清零
i=0; // 臨時(shí)變量 清零
num1_flag=0; // 運(yùn)算數(shù)1輸入標(biāo)志 清零
num2_flag=0; // 運(yùn)算數(shù)2輸入標(biāo)志 清零
while(1)
{
ret=KeyScanf(); // 讀取矩陣鍵盤的掃描結(jié)果
if(ret!=99) // 返回值不等于99,說明有按鍵按下了
{
DelayMs(20);
ret=KeyScanf(); // 讀取矩陣鍵盤的掃描結(jié)果
if(ret!=99)
{
/*檢測(cè)到的是按下數(shù)字*/
if(ret<10)
{
if(cal==0) // 如果cal的值為0,說明現(xiàn)在在輸入運(yùn)算數(shù)1
{
if(num1<1000) // 限制運(yùn)算數(shù)1的大小小于10000
{
LcdPrintNum(ret); //將按下的數(shù)字鍵刷新顯示
num1=num1*10+ret; // 把運(yùn)算數(shù)1放大10倍
num1_flag=1; // 將運(yùn)算數(shù)1的標(biāo)志變量num1_flag置1,說明運(yùn)算數(shù)1已輸入
}
}
else // 如果cal的值不為0,說明現(xiàn)在在輸入運(yùn)算數(shù)2
{
if(num2<1000) // 限制運(yùn)算數(shù)2的大小小于10000
{
LcdPrintNum(ret); // 將按下的數(shù)字鍵顯示
num2=num2*10+ret; // 把運(yùn)算數(shù)2放大10倍
num2_flag=1; // 將運(yùn)算數(shù)2的標(biāo)志變量num2_flag置1,說明運(yùn)算數(shù)2已輸入
}
}
}
/*檢測(cè)到的是按下加號(hào)*/
if(ret==10)
{
if(cal==0) // 判斷是否是第一次輸入計(jì)算符號(hào)
{
if(num1_flag==0) // 判斷運(yùn)算數(shù)1是否還未輸入
{
LcdPrintNum(0); // 如果是的話,在液晶顯示數(shù)字0
num1=0; // 給運(yùn)算數(shù)1一個(gè)計(jì)算初值0
}
cal=1; // 將運(yùn)算符變量改為1,代表即將進(jìn)行加法運(yùn)算
LcdWriteData('+'); // 把加法運(yùn)算符號(hào)顯示到屏幕上
}
}
/*檢測(cè)到的是按下減號(hào)*/
if(ret==11)
{
if(cal==0) // 判斷是否是第一次輸入計(jì)算符號(hào)
{
if(num1_flag==0) // 判斷運(yùn)算數(shù)1是否還未輸入
{
LcdPrintNum(0); // 如果是的話,在液晶上面顯示0
num1=0; // 給運(yùn)算數(shù)1一個(gè)計(jì)算初值0
}
cal=2; // 將運(yùn)算符變量改為2,代表即將進(jìn)行減法運(yùn)算
LcdWriteData('-'); // 把減法運(yùn)算符號(hào)顯示到屏幕上
}
}
/*檢測(cè)到的是按下乘號(hào)*/
if(ret==12)
{
if(cal==0) // 判斷是否是第一次輸入計(jì)算符號(hào)
{
if(num1_flag==0) // 判斷運(yùn)算數(shù)1是否還未輸入
{
LcdPrintNum(0); // 如果是的話,在液晶上面顯示0
num1=0; // 給運(yùn)算數(shù)1一個(gè)計(jì)算初值0
}
cal=3; // 將運(yùn)算符變量改為3,代表即將進(jìn)行乘法運(yùn)算
LcdWriteData('*'); // 把乘法運(yùn)算符號(hào)顯示到屏幕上
}
}
/*檢測(cè)到的是按下除號(hào)*/
if(ret==15)
{
if(cal==0) // 判斷是否是第一次輸入計(jì)算符號(hào)
{
if(num1_flag==0) // 判斷運(yùn)算數(shù)1是否還未輸入
{
LcdPrintNum(0); // 如果是的話,在液晶上面顯示0
num1=0; // 給運(yùn)算數(shù)1一個(gè)計(jì)算初值0
}
cal=4; // 將運(yùn)算符變量改為4,代表即將進(jìn)行除法運(yùn)算
LcdWriteData('/'); // 把除法運(yùn)算符號(hào)顯示到屏幕上
}
}
/*檢測(cè)到的是按下清除鍵*/
if(ret==13)
{
break; // 退出當(dāng)前的while循環(huán)
}
/*檢測(cè)到的是按下等于號(hào)*/
if(ret==14)
{
if(num2_flag==0) // 判斷運(yùn)算數(shù)2是否還未輸入
{
LcdPrintNum(0); // 如果是的話,在液晶上面顯示0
num2=0; // 給運(yùn)算數(shù)2一個(gè)計(jì)算初值0
}
switch(cal) // 根據(jù)cal這個(gè)變量的不同值,采取不同的四則運(yùn)算
{
/*加法運(yùn)算*/
case 1:
LcdGotoXY(1,15); // 定位到液晶的第2行最后一列
LcdWriteCmd(0x04); // 光標(biāo)左移
num3=num1+num2; // 計(jì)算結(jié)果
if(num3==0) // 如果計(jì)算結(jié)果為0
{
LcdPrintNum(0); // 在屏幕上顯示0
}
while(num3!=0) // 顯示計(jì)算結(jié)果
{
LcdPrintNum(num3%10);
num3=num3/10;
}
LcdWriteData('='); // 顯示等于號(hào)
LcdWriteCmd(0x06); // 光標(biāo)右移
break;
/*減法運(yùn)算*/
case 2:
LcdGotoXY(1,15); // 定位到液晶的第2行最后一列
LcdWriteCmd(0x04); // 光標(biāo)左移
if(num1>num2)
{
num3=num1-num2; // 計(jì)算結(jié)果
while(num3!=0) // 顯示計(jì)算結(jié)果
{
LcdPrintNum(num3%10);
num3=num3/10;
}
}
else if(num1<num2)
{
num3=num2-num1; // 計(jì)算結(jié)果
while(num3!=0) // 顯示計(jì)算結(jié)果
{
LcdPrintNum(num3%10);
num3=num3/10;
}
LcdWriteData('-'); // 顯示負(fù)號(hào)
}
else
{
LcdPrintNum(0); // 顯示數(shù)字0
}
LcdWriteData('='); // 顯示等于號(hào)
LcdWriteCmd(0x06); // 光標(biāo)右移
break;
/*乘法運(yùn)算*/
case 3:
LcdGotoXY(1,15); // 定位到液晶的第2行最后一列
LcdWriteCmd(0x04); // 光標(biāo)左移
num3=num1*num2; // 計(jì)算結(jié)果
if(num3==0) // 如果計(jì)算結(jié)果為0
{
LcdPrintNum(0); // 在屏幕上顯示0
}
while(num3!=0) // 顯示計(jì)算結(jié)果
{
LcdPrintNum(num3%10);
num3=num3/10;
}
LcdWriteData('='); // 顯示等于號(hào)
LcdWriteCmd(0x06); // 光標(biāo)右移
break;
/*除法運(yùn)算*/
case 4:
if(num2!=0)
{
LcdGotoXY(1,15); // 定位到液晶的第2行最后一列
LcdWriteCmd(0x04); // 光標(biāo)左移
num3=(ulong)(((float)num1/num2)*1000); // 計(jì)算結(jié)果(放大了1000倍)
if(num1<num2) // 如果是小數(shù)除以大數(shù)
{
num3=num3+1000;// 先給計(jì)算結(jié)果加1000
}
while(num3!=0) // 顯示計(jì)算結(jié)果
{
LcdPrintNum(num3%10);
num3=num3/10;
i++;
if(i==3) // 顯示小數(shù)點(diǎn)
{
LcdWriteData('.');
}
}
if(num1<num2) // 如果是小數(shù)除以大數(shù)
{
LcdGotoXY(1,11); // 把之前加的1000給清除
LcdPrintNum(0);
}
LcdWriteData('='); // 顯示等于號(hào)
LcdWriteCmd(0x06); // 光標(biāo)右移
break;
}
else // 如果除數(shù)位0,顯示“ERROR!”
{
LcdGotoXY(1,10);
LcdPrintStr("ERROR!");
}
}
LcdWriteCmd(0x0C); // 光標(biāo)不閃爍
while(KeyScanf()!=13); // 計(jì)算后,只能通過按下清除鍵,才能進(jìn)入新一輪的計(jì)算
break;
}
DelayMs(10); // 去除按鍵按下的抖動(dòng)
while(KeyScanf()!=99); // 等待按鍵釋放
DelayMs(10); // 去除按鍵松開的抖動(dòng)
}
}
}
}
}
-
-
計(jì)算器程序 原理圖.rar
2019-10-13 12:38 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
89.25 KB, 下載次數(shù): 25, 下載積分: 黑幣 -5
作者: zzzzz.c 時(shí)間: 2019-10-15 11:04
真全,,謝謝了
| 歡迎光臨 (http://www.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |