仿真圖proteus 7.8/proteus 8.6
程序編譯器:keil 4/keil 5
編程語言:C語言
編號S0001
資料下載網(wǎng)盤鏈接:
芯片可以替換為STC89C52/STC89C51/AT89C52/AT89C51等51單片機(jī)芯片。
講解視頻:
一、該簡易計算器設(shè)計硬件電路采用三部分電路模塊構(gòu)成:
1、鍵盤模塊電路, 采用 4*4 矩陣式鍵盤作為輸入電路;
2、LCD1602 液晶顯示模塊;
3、以 51 單片機(jī)作為控制核心。
二、軟件程序主要由三部分組成: 主程序、按鍵掃描程序和 LCD1602 顯示程序。
三、 性能指標(biāo)
(1) 用單片機(jī) stc89C51 設(shè)計一個簡易計算器, 并用 1602 液晶顯示相應(yīng)的數(shù)據(jù)。
(2) 可以進(jìn)行簡單的加減乘除運算。
(3) 最大可以 9999*9999, 。
(4) 可以通過 proteus 仿真。
PCB和原理圖
3.2 硬件設(shè)計
本系統(tǒng)以AT89S52單片機(jī)為核心,本系統(tǒng)選用12MHZ的晶振,使得單片機(jī)有合理的運行速度。起振電容30pF對振蕩器的頻率高低、振蕩器的穩(wěn)定性和起振的快速性影響較合適,復(fù)位電路為按鍵高電平復(fù)位。
3.2.1 鍵盤設(shè)計電路
本設(shè)計選用的是非編碼鍵盤。鍵盤是單片機(jī)系統(tǒng)中最常用的人機(jī)對話輸入設(shè)備,用戶通過鍵盤向單片機(jī)輸入數(shù)據(jù)或指令。鍵盤控制程序需完成的任務(wù)有:監(jiān)測是否有鍵按下,有鍵按下時,在無硬件去抖時,應(yīng)用軟件延時方法消除按鍵抖動影響;當(dāng)有多個鍵同 時按下時,只處理一個按鍵,不管一次按鍵持續(xù)多長時間,僅執(zhí)行一次按鍵功能程序。矩陣按鍵掃描程序是一種節(jié)省IO口的方法,按鍵數(shù)目越多節(jié)省IO口就越可觀,思路:先判斷某一列(行)是否有按鍵按下,再判斷該行(列)是那一只鍵按下。但是,在程序的寫法上,采用了最簡單的方法,使得程序效率最高。本程序中,如果檢測到某個鍵按下了,就不再檢測其它的按鍵,這完全能滿足絕大多數(shù)需要,又能節(jié)省大量的CPU時間。
本鍵盤掃描程序的優(yōu)點在于:不用專門的按鍵延時程序,提高了CPU效率,也不用中斷來掃描鍵盤,節(jié)省了硬件資源。另外,本鍵盤掃描程序,每次掃描占用CPU時最短,不論有鍵按下或者無鍵按下都可以在很短的時間完成一次掃描。鍵盤是單片機(jī)系統(tǒng)中最常用的人機(jī)對話輸入設(shè)備,用戶通過鍵盤向單片機(jī)輸入數(shù)據(jù)或指令。鍵盤控制程序需完成的任務(wù)有:監(jiān)測是否有鍵按下,有鍵按下時,在無硬件去抖時,應(yīng)用軟件延時方法消除按鍵抖動影響;當(dāng)有多個鍵同時按下時,只處理一個按鍵,不管一次按鍵持續(xù)多長時間,僅執(zhí)行一次按鍵功能程序。
矩陣按鍵掃描程序是一種節(jié)省IO口的方法,按鍵數(shù)目越多節(jié)省IO口就越可觀,思路:先判斷某一列(行)是否有按鍵按下,再判斷該行(列)是那一只鍵按下。但是,在程序的寫法上,采用了最簡單的方法,使得程序效率最高。本程序中,如果檢測到某個鍵按下了,就不再檢測其它的按鍵,這完全能滿足絕大多數(shù)需要,又能節(jié)省大量的CPU時間。本鍵盤掃描程序的優(yōu)點在于:不用專門的按鍵延時程序,提高了CPU效率,也不用中斷來掃描鍵盤,節(jié)省了硬件資源。另外,本鍵盤掃描程序,每次掃描占用CPU時最短,不論有鍵按下或者無鍵按下都可以在很短的時間完成一次掃描。
?程序代碼
LCD1602部分
#include <reg52.h>
#include <intrins.h>
sbit LCD_RS= P2^4;
sbit LCD_RW = P2^5;
sbit LCD_E = P2^6;
#define LCD_DATA P0
static void LCD_Delay(unsigned char ms) //延時函數(shù)
{
unsigned char i;
while(ms--)
{
for(i = 0; i< 250; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
bit LCD_Busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_E = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(LCD_DATA & 0x80);
LCD_E = 0;
return result;
}
void LCD_WriteCmd(unsigned char cmd) //LCD1602寫命令
{
while(LCD_Busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_E = 0;
_nop_();
_nop_();
LCD_DATA = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_E = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_E = 0;
}
void LCD_Pos(unsigned char row,unsigned char pos)
{
row &= 0x1;
pos &= 0xF;
if (row) pos |= 0x40;
LCD_WriteCmd(pos | 0x80);
}
void LCD_WriteDat(unsigned char dat) //寫數(shù)據(jù)
{
while(LCD_Busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_E = 0;
LCD_DATA = dat;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_E = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_E = 0;
}
void LCD_ShowStr(unsigned char x, unsigned char y, unsigned char *dat) //寫字符串
{
unsigned char i=0;
LCD_Pos(y,x);
while(dat[i] != '?')
{
LCD_WriteDat(dat[i]);
i++;
}
}
void LCD_Init(void) //LCD1602顯示
{
LCD_WriteCmd(0x38);
LCD_Delay(1);
LCD_WriteCmd(0x0c);
LCD_Delay(1);
LCD_WriteCmd(0x06);
LCD_Delay(1);
LCD_WriteCmd(0x01);
LCD_Delay(1);
}
主函數(shù):
#include "reg52.h"
#include "string.h"
#include "stdio.h"
#include "lcd1602.h"
#include "keyboard.h"
#define keydeng 14
#define keyzuoyi 12
code unsigned char KeyDisPlaybuf[16] =
{
'1', '2', '3', '+',
'4', '5', '6', '-',
'7', '8', '9', '*',
'<', '0', '=', '/'
};
long Count(char *ch, char len)//簡單計算器 僅支持加減乘除+-*/
{
unsigned char i = 0;
char Operation;
long Num1=0,Num2=0;
while(i<len && ch[i]!='+' && ch[i]!='-' && ch[i]!='*' && ch[i]!='/') //輸入的數(shù)據(jù) 數(shù)值1
{
Num1*=10;
Num1+=ch[i]-'0';
i++;
}
Operation=ch[i++];
while(i<len && ch[i]!='=') //輸入的數(shù)據(jù) 數(shù)值2
{
Num2*=10;
Num2+=ch[i]-'0';
i++;
}
switch(Operation) //計算
{
case'+':return Num1+Num2;//加法
case'-':return Num1-Num2;//減法
case'*':return Num1*Num2;//乘法
case'/':return Num1/Num2;//除法
}
return 0;
}
void EasyCounter(void)
{
unsigned char buff[30];
unsigned char text[30];
unsigned char key;
unsigned char i = 0;
do
{
key = keycan();//讀取鍵值
if(key!=0xff)//鍵值不等于0
{
text[i++]=KeyDisPlaybuf[key];//記錄鍵值對應(yīng)的字符
text[i]='?';
LCD_ShowStr(0,0," ");
LCD_ShowStr(16-strlen(text),0,text); //第一行顯示字符
}
if(key==keyzuoyi&&i>0)//按下"<"時刪除一位
i-=2;
}while(key!=keydeng);//按下'='時結(jié)束輸入
sprintf(buff, "%ld", Count(text, strlen(text)));
LCD_ShowStr(0,1," ");
LCD_ShowStr(16-strlen(buff),1,buff); //第二行顯示字符
}
void main(void) //主函數(shù)
{
LCD_Init();
LCD_ShowStr(0,0, " 0");
while(1)
{
EasyCounter(); //按鍵掃描+計算+顯示
}
}
設(shè)計報告
任務(wù)書如下
一. 設(shè)計要求
(一) 基本任務(wù)
該簡易計算器設(shè)計硬件電路采用三部分電路模塊構(gòu)成, 第一部分是鍵盤模塊
電路, 采用 4*4 矩陣式鍵盤作為輸入電路; 第二部分是 LCD1602 液晶顯示模塊;
第三部分是以 51 單片機(jī)作為控制核心。 軟件程序主要由三部分組成: 主程序、
按鍵掃描程序和 LCD1602 顯示程序。
(二) 性能指標(biāo)
(1) 用單片機(jī) stc89C51 設(shè)計一個簡易計算器, 并用 1602 液晶顯示相應(yīng)的
數(shù)據(jù)。
(2) 可以進(jìn)行簡單的加減乘除運算。
(3) 最大可以 9999*9999, 。
(4) 可以通過 proteus 仿真。
附: 可供選用的元件清單
1)1602 液晶
2)排針*16
3)16p 母座
4)STC89C51 單片機(jī)
5)40 腳 IC 座
6)10k 電阻*2
7)1.5k 電阻
8)103 排阻
9)10uf 電解電容
10)12M 晶振
11)30pf 電容*2
12)按鍵*17
13)自鎖開關(guān)等等