仿真圖proteus 7.8/proteus 8.6
程序編譯器:keil 4/keil 5
編程語言:C語言
編號(hào)S0001
資料下載網(wǎng)盤鏈接:
芯片可以替換為STC89C52/STC89C51/AT89C52/AT89C51等51單片機(jī)芯片。
講解視頻:
51單片機(jī)的簡(jiǎn)易計(jì)算器仿真設(shè)計(jì)(仿真+程序+原理圖+PCB+設(shè)計(jì)報(bào)告+講解視頻)
一、該簡(jiǎn)易計(jì)算器設(shè)計(jì)硬件電路采用三部分電路模塊構(gòu)成:
1、鍵盤模塊電路, 采用 4*4 矩陣式鍵盤作為輸入電路;
2、LCD1602 液晶顯示模塊;
3、以 51 單片機(jī)作為控制核心。
二、軟件程序主要由三部分組成: 主程序、按鍵掃描程序和 LCD1602 顯示程序。
三、 性能指標(biāo)
(1) 用單片機(jī) stc89C51 設(shè)計(jì)一個(gè)簡(jiǎn)易計(jì)算器, 并用 1602 液晶顯示相應(yīng)的數(shù)據(jù)。
(2) 可以進(jìn)行簡(jiǎn)單的加減乘除運(yùn)算。
(3) 最大可以 9999*9999, 。
(4) 可以通過 proteus 仿真。
PCB和原理圖
3.2 硬件設(shè)計(jì)
本系統(tǒng)以AT89S52單片機(jī)為核心,本系統(tǒng)選用12MHZ的晶振,使得單片機(jī)有合理的運(yùn)行速度。起振電容30pF對(duì)振蕩器的頻率高低、振蕩器的穩(wěn)定性和起振的快速性影響較合適,復(fù)位電路為按鍵高電平復(fù)位。
3.2.1 鍵盤設(shè)計(jì)電路
本設(shè)計(jì)選用的是非編碼鍵盤。鍵盤是單片機(jī)系統(tǒng)中最常用的人機(jī)對(duì)話輸入設(shè)備,用戶通過鍵盤向單片機(jī)輸入數(shù)據(jù)或指令。鍵盤控制程序需完成的任務(wù)有:監(jiān)測(cè)是否有鍵按下,有鍵按下時(shí),在無硬件去抖時(shí),應(yīng)用軟件延時(shí)方法消除按鍵抖動(dòng)影響;當(dāng)有多個(gè)鍵同 時(shí)按下時(shí),只處理一個(gè)按鍵,不管一次按鍵持續(xù)多長(zhǎng)時(shí)間,僅執(zhí)行一次按鍵功能程序。矩陣按鍵掃描程序是一種節(jié)省IO口的方法,按鍵數(shù)目越多節(jié)省IO口就越可觀,思路:先判斷某一列(行)是否有按鍵按下,再判斷該行(列)是那一只鍵按下。但是,在程序的寫法上,采用了最簡(jiǎn)單的方法,使得程序效率最高。本程序中,如果檢測(cè)到某個(gè)鍵按下了,就不再檢測(cè)其它的按鍵,這完全能滿足絕大多數(shù)需要,又能節(jié)省大量的CPU時(shí)間。
本鍵盤掃描程序的優(yōu)點(diǎn)在于:不用專門的按鍵延時(shí)程序,提高了CPU效率,也不用中斷來掃描鍵盤,節(jié)省了硬件資源。另外,本鍵盤掃描程序,每次掃描占用CPU時(shí)最短,不論有鍵按下或者無鍵按下都可以在很短的時(shí)間完成一次掃描。鍵盤是單片機(jī)系統(tǒng)中最常用的人機(jī)對(duì)話輸入設(shè)備,用戶通過鍵盤向單片機(jī)輸入數(shù)據(jù)或指令。鍵盤控制程序需完成的任務(wù)有:監(jiān)測(cè)是否有鍵按下,有鍵按下時(shí),在無硬件去抖時(shí),應(yīng)用軟件延時(shí)方法消除按鍵抖動(dòng)影響;當(dāng)有多個(gè)鍵同時(shí)按下時(shí),只處理一個(gè)按鍵,不管一次按鍵持續(xù)多長(zhǎng)時(shí)間,僅執(zhí)行一次按鍵功能程序。
矩陣按鍵掃描程序是一種節(jié)省IO口的方法,按鍵數(shù)目越多節(jié)省IO口就越可觀,思路:先判斷某一列(行)是否有按鍵按下,再判斷該行(列)是那一只鍵按下。但是,在程序的寫法上,采用了最簡(jiǎn)單的方法,使得程序效率最高。本程序中,如果檢測(cè)到某個(gè)鍵按下了,就不再檢測(cè)其它的按鍵,這完全能滿足絕大多數(shù)需要,又能節(jié)省大量的CPU時(shí)間。本鍵盤掃描程序的優(yōu)點(diǎn)在于:不用專門的按鍵延時(shí)程序,提高了CPU效率,也不用中斷來掃描鍵盤,節(jié)省了硬件資源。另外,本鍵盤掃描程序,每次掃描占用CPU時(shí)最短,不論有鍵按下或者無鍵按下都可以在很短的時(shí)間完成一次掃描。
?程序代碼
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í)函數(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)//簡(jiǎn)單計(jì)算器 僅支持加減乘除+-*/
{
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) //計(jì)算
{
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];//記錄鍵值對(duì)應(yīng)的字符
text[i]='?';
LCD_ShowStr(0,0," ");
LCD_ShowStr(16-strlen(text),0,text); //第一行顯示字符
}
if(key==keyzuoyi&&i>0)//按下"<"時(shí)刪除一位
i-=2;
}while(key!=keydeng);//按下'='時(shí)結(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(); //按鍵掃描+計(jì)算+顯示
}
}
設(shè)計(jì)報(bào)告
任務(wù)書如下
一. 設(shè)計(jì)要求
(一) 基本任務(wù)
該簡(jiǎn)易計(jì)算器設(shè)計(jì)硬件電路采用三部分電路模塊構(gòu)成, 第一部分是鍵盤模塊
電路, 采用 4*4 矩陣式鍵盤作為輸入電路; 第二部分是 LCD1602 液晶顯示模塊;
第三部分是以 51 單片機(jī)作為控制核心。 軟件程序主要由三部分組成: 主程序、
按鍵掃描程序和 LCD1602 顯示程序。
(二) 性能指標(biāo)
(1) 用單片機(jī) stc89C51 設(shè)計(jì)一個(gè)簡(jiǎn)易計(jì)算器, 并用 1602 液晶顯示相應(yīng)的
數(shù)據(jù)。
(2) 可以進(jìn)行簡(jiǎn)單的加減乘除運(yù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)等等