当前位置:网站首页>STC89C52 single chip microcomputer simple calculator design and code demonstration
STC89C52 single chip microcomputer simple calculator design and code demonstration
2022-06-30 01:06:00 【A piglet who likes fried chicken】
Catalog
First, select hardware and software according to the functions to be realized :
First, select hardware and software according to the functions to be realized :
First of all, the functions we want to realize are : Multi bit display , Decimal calculation , Continuous calculation , The symbol is modified by mistake ,,
hardware component
be used LCD1602 display , Matrix keyboard , Buzzer ( Yes or no )
The reason why there is no digital tube here is , The nixie tube needs to be scanned , And for addition, subtraction, multiplication and division, these symbols are not well displayed , Instead, it uses relatively simple LCD1602 To display
The matrix keyboard module is relatively simple : Schematic diagram is as follows :
Software part
Input part :
Obviously, it is necessary to input two or more numbers to be calculated . Input operation : Every time you enter a number , The previous numbers must be shifted forward . And for the fractional part , That is, every digit you enter , The numbers are displayed one after the other .( Some students may not be used to looking at the front when inputting numbers 0000,, You can count overflow variables , If there are several digits, it will show how many digits are used if sentence )
Count overflow variables : It is to count the number of digits of the input number so as to ensure that the total length of the input number will not exceed the screen , When the maximum length is reached, the display function is limited to achieve the effect
Calculation part :
Secondly, we should design the subroutines of addition, subtraction, multiplication and division , But our first design , Therefore, the number of digits calculated is relatively small , So the result of the interaction between variables is stored in the third variable , Then, just display it .
The input number may be an integer or a decimal , Taking multiplication as an example, the possible cases of calculation are :
Integers x Integers
decimal x Integers
Integers x decimal
decimal x decimal
For the sake of representation , What I designed here is to divide a decimal into integer part and decimal part to store ; That is to say, for example, a 2 Decimal place :number= Integral part +( The fractional part *0.01) If we just want to calculate integers , that ( The fractional part *0.01) by 0 It will not affect the following calculation
After entering the integer part of a number , After pressing the operation symbol, the next step is to input the second number . But if you press the decimal point , Then the input of operation symbols will be delayed , The next step is to input the number after the decimal point , Then press the operation symbol , Is the input of the second number . In the process of pressing each key , We can also combine the buzzer , Every click rings . Make sure we actually press this button
Continuous calculation :
There is also the calculation of multiple numbers , Our daily use of calculators may be more than just right 2 Between numbers , There may be an addition between these numbers , reduce , ride , Division and many other operations .
In general, I do this by 2 Based on the calculation between two numbers , The first input of 2 The calculated result of a number is stored in the first number , The second digit is cleared ( Count overflow variables should also be cleared , Otherwise, after the count overflow variable reaches the specified value, the second number cannot be entered ).
Here is the following :

Also mark the symbols to be calculated , If this flag is detected in the function that inputs the first number, it will jump out and directly enter the second number ( Since we have stored the result of the previous operation into the variable of the first number, we can only input the second number )
What do you say , The train of thought is relatively clear
Source code example :
The main function :
#include <REGX52.H>
#include "LCD1602.h"
#include "delay.h"
#include "jianpan.h"
#include "Buzzer.h"
/*
number1 Key entered for the first time
number2 Key entered for the second time
number3 Key entered for the third time
number4 Key entered for the fourth time
number For the calculation result
password1 and password3 constitute number1,password2 and password4 constitute number2
count1,count2,count3,count4 Count variables to avoid overflow of input numbers
The calculated figure may be :
Integers and integers
Integers and decimals
Decimals and integers
Decimals and decimals
Key description :
On the keyboard S1 To S9 Namely 1 To 9, then S10 yes 0
S11 It's the decimal point ,S12 It is the clear key when the first number is input , After the second number is entered, it is the equal key
S13 To S16 They are plus , reduce , ride , except .
*/
float number,password1,password2;
unsigned long number1,number2,number3,number4,password3,password4;
unsigned char symbol,count1,count2,count3,count4;
void main(){
while(1){
LCD_Init();
LCD_ShowString(1,1,"Calculator x4.0");
LCD_ShowString(2,1,"Wellcome");
password3=0;
count2=0;
while(1){
if(symbol==13||symbol==14||symbol==15||symbol==16)
{break;}
number1=jianpan();
if(number1){
Buzzer_Time(100);
if(number1==12){
LCD_ShowString(2,1," ");
count1=0;
password1=0;
LCD_ShowNum(2,1,password1,8);
}
if(number1<=10){
if(count1<8){// Input at most 8 position , Avoid spillovers
password1=10*password1;// Here two lines are the key , Shift the input single digits in sequence
password1=number1%10+password1;
if(count1>=0)
LCD_ShowNum(2,8,password1,1);
LCD_ShowString(2,1," ");
if(count1>=1)
LCD_ShowNum(2,7,(unsigned long)(password1/10)%10,1);
LCD_ShowString(2,1," ");
if(count1>=2)
LCD_ShowNum(2,6,(unsigned long)(password1/100)%10,1);
LCD_ShowString(2,1," ");
if(count1>=3)
LCD_ShowNum(2,5,(unsigned long)(password1/1000)%10,1);
LCD_ShowString(2,1," ");
if(count1>=4)
LCD_ShowNum(2,4,(unsigned long)(password1/10000)%10,1);
LCD_ShowString(2,1," ");
if(count1>=5)
LCD_ShowNum(2,3,(unsigned long)(password1/100000)%10,1);
LCD_ShowString(2,1," ");
if(count1>=6)
LCD_ShowNum(2,2,(unsigned long)(password1/1000000)%10,1);
LCD_ShowString(2,1," ");
if(count1>=7)
LCD_ShowNum(2,1,(unsigned long)(password1/10000000)%10,1);
}
count1++;
}
if(number1==11)// no need switch,case Can improve fault tolerance , Changing the choice of symbols many times
break;
if(number1==13){
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'+');
symbol=number1;
break;
}
if(number1==14){
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'-');
symbol=number1;
break;
}
if(number1==15){
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'*');
symbol=number1;
break;
}
if(number1==16){
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'/');
symbol=number1;
break;
}
}
}
while(1){
if(symbol==13){
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'+');
break;
}
if(symbol==14){
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'-');
break;
}
if(symbol==15){
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'*');
break;
}
if(symbol==16){
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'/');
break;
}
number2=jianpan();
if(number1==11){// If you last entered a decimal point , Then enter this cycle , Otherwise you won't get into ( When the first number is an integer )
LCD_ShowChar(2,9,'.');
if(number2){
Buzzer_Time(100);
if(number2<=10){
if(count2<3){// Input at most 3 position , Avoid spillovers
password3=10*password3;// Here two lines are the key , Shift the input single digits in sequence
password3=number2%10+password3;
if(count2>=0)
{
LCD_ShowNum(2,10,password3,1);
}
if(count2>=1)
{
LCD_ShowNum(2,10,(password3/10)%10,1);
LCD_ShowNum(2,11,password3,1);
}
if(count2>=2)
{
LCD_ShowNum(2,12,password3,1);
LCD_ShowNum(2,11,(password3/10)%10,1);
LCD_ShowNum(2,10,(password3/100)%10,1);
}
// LCD_ShowNum(2,10,password3,1);
// LCD_ShowNum(2,11,(password3/10)%10,1);
// LCD_ShowNum(2,12,(password3/100)%10,1);
}
count2++;
}
if(number2==13){// Symbol display
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'+');
symbol=number2;
break;
}
if(number2==14){
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'-');
symbol=number2;
break;
}
if(number2==15){
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'*');
symbol=number2;
break;
}
if(number2==16){
LCD_ShowString(2,1," ");
LCD_ShowChar(2,1,'/');
symbol=number2;
break;
}
}
}
else
break;
}
password2=0;//( One thing to note here is that when performing continuous operations , The second input number should be cleared , Otherwise, the third input will be based on the second input )
password4=0;
count3=0;//( One thing to note here is that when performing continuous operations , Count variables should be cleared , Otherwise, you may not be able to input numbers later **)
count4=0;
while(1){
number3=jianpan();
if(number3){
Buzzer_Time(100);
if(number3<=10){
if(count3<8){// Input at most 8 position , Avoid spillovers
password2=10*password2;// Here two lines are the key , Shift the input single digits in sequence
password2=number3%10+password2;
if(count3>=0)
LCD_ShowNum(2,8,password2,1);
LCD_ShowString(2,1," ");
if(count3>=1)
LCD_ShowNum(2,7,(unsigned long)(password2/10)%10,1);
LCD_ShowString(2,1," ");
if(count3>=2)
LCD_ShowNum(2,6,(unsigned long)(password2/100)%10,1);
LCD_ShowString(2,1," ");
if(count3>=3)
LCD_ShowNum(2,5,(unsigned long)(password2/1000)%10,1);
LCD_ShowString(2,1," ");
if(count3>=4)
LCD_ShowNum(2,4,(unsigned long)(password2/10000)%10,1);
LCD_ShowString(2,1," ");
if(count3>=5)
LCD_ShowNum(2,3,(unsigned long)(password2/100000)%10,1);
LCD_ShowString(2,1," ");
if(count3>=6)
LCD_ShowNum(2,2,(unsigned long)(password2/1000000)%10,1);
LCD_ShowString(2,1," ");
if(count3>=7)
LCD_ShowNum(2,1,(unsigned long)(password2/10000000)%10,1);
}
count3++;
}
if(number3==11){break;}
if(number3==12){
if(count2==1) password3=password3*100;// Using overflow variables , Implement a , Data with two decimal places and data with three decimal places are unified
if(count2==2) password3=password3*10;
switch (symbol){// Integers ( decimal )x decimal
case 13: number=(password1+password3*0.001)+(password2+password4*0.001); break;
case 14: number=(password1+password3*0.001)-(password2+password4*0.001); break;
case 15: number=(password1+password3*0.001)*(password2+password4*0.001); break;
case 16: number=(password1+password3*0.001)/(password2+password4*0.001); break;
}
LCD_ShowString(2,1,"result:");
LCD_ShowNum(2,8,number,1);
LCD_ShowNum(2,7,(unsigned long)(number/10)%10,1);
LCD_ShowNum(2,6,(unsigned long)(number/100)%10,1);
LCD_ShowNum(2,5,(unsigned long)(number/1000)%10,1);
LCD_ShowNum(2,4,(unsigned long)(number/10000)%10,1);
LCD_ShowNum(2,3,(unsigned long)(number/100000)%10,1);
LCD_ShowNum(2,2,(unsigned long)(number/1000000)%10,1);
LCD_ShowNum(2,1,(unsigned long)(number/10000000)%10,1);
LCD_ShowChar(2,9,'.');
LCD_ShowNum(2,10,(unsigned long)(number*1000)%1000,3);
}
if(number3==13||number3==14||number3==15||number3==16)
{
if(count2==1) password3=password3*100;// Using overflow variables in continuous operations , Implement a , Data with two decimal places and data with three decimal places are unified
if(count2==2) password3=password3*10;
switch (symbol){// Integers ( decimal )x decimal
case 13: number=(password1+password3*0.001)+(password2+password4*0.001); break;
case 14: number=(password1+password3*0.001)-(password2+password4*0.001); break;
case 15: number=(password1+password3*0.001)*(password2+password4*0.001); break;
case 16: number=(password1+password3*0.001)/(password2+password4*0.001); break;
}
password1=number;
symbol=number3;
number=0;
break;// End the small loop , Repeat the input operation in the first step
}
}
}
while(1)
{
if(number3==13||number3==14||number3==15||number3==16)
{break;}
number4=jianpan();
if(number3==11){
LCD_ShowChar(2,9,'.');
if(number4){
Buzzer_Time(100);
if(number4<=10){
if(count4<3){// Input at most 3 position , Avoid spillovers
password4=10*password4;// Here two lines are the key , Shift the input single digits in sequence
password4=number4%10+password4;
if(count4>=0)
{
LCD_ShowNum(2,10,password4,1);
}
if(count4>=1)
{
LCD_ShowNum(2,10,(password4/10)%10,1);
LCD_ShowNum(2,11,password4,1);
}
if(count4>=2)
{
LCD_ShowNum(2,12,password4,1);
LCD_ShowNum(2,11,(password4/10)%10,1);
LCD_ShowNum(2,10,(password4/100)%10,1);
}
}
count4++;
}
if(number4==12){
if(count2==1) password3=password3*100;// Using overflow variables , Implement a , Data with two decimal places and data with three decimal places are unified
if(count2==2) password3=password3*10;
if(count4==1) password4=password4*100;
if(count4==2) password4=password4*10;
switch (symbol){// Integers ( decimal )x decimal
case 13: number=(password1+password3*0.001)+(password2+password4*0.001); break;
case 14: number=(password1+password3*0.001)-(password2+password4*0.001); break;
case 15: number=(password1+password3*0.001)*(password2+password4*0.001); break;
case 16: number=(password1+password3*0.001)/(password2+password4*0.001); break;
}
LCD_ShowString(2,1,"result:");
LCD_ShowNum(2,8,number,1);
LCD_ShowNum(2,7,(unsigned long)(number/10)%10,1);
LCD_ShowNum(2,6,(unsigned long)(number/100)%10,1);
LCD_ShowNum(2,5,(unsigned long)(number/1000)%10,1);
LCD_ShowNum(2,4,(unsigned long)(number/10000)%10,1);
LCD_ShowNum(2,3,(unsigned long)(number/100000)%10,1);
LCD_ShowNum(2,2,(unsigned long)(number/1000000)%10,1);
LCD_ShowNum(2,1,(unsigned long)(number/10000000)%10,1);
LCD_ShowChar(2,9,'.');
LCD_ShowNum(2,10,(unsigned long)(number*1000)%1000,3);
}
if(number4==13||number4==14||number4==15||number4==16)
{
if(count2==1) password3=password3*100;// Using overflow variables in continuous operations , Implement a , Data with two decimal places and data with three decimal places are unified
if(count2==2) password3=password3*10;
if(count4==1) password4=password4*100;
if(count4==2) password4=password4*10;
switch (symbol){// Integers ( decimal )x decimal
case 13: number=(password1+password3*0.001)+(password2+password4*0.001); break;
case 14: number=(password1+password3*0.001)-(password2+password4*0.001); break;
case 15: number=(password1+password3*0.001)*(password2+password4*0.001); break;
case 16: number=(password1+password3*0.001)/(password2+password4*0.001); break;
}
password1=number;
symbol=number4;
number=0;
break;// End the small loop , Repeat the input operation in the first step
}
}
}
}
}
}Keyboard entry :
#include <REGX52.H>
#include "delay.h"
/**
* @brief Matrix keyboard
* @param nothing
* @retval Press the key to enter if() and while() in , The moment you release your hand , Return value generation , And return the original function
* When no key is pressed , Returns the initial value 0( Why should the main function add if? It is used to detect whether the key is pressed , Only press to enter the cycle )
*/
unsigned int jianpan(){
unsigned int number=0;
while(1){
P1=0xFF;// There should be... In front of each column , Otherwise, you will press a number repeatedly , There are other numbers in line with this number
P1_3=0;
if(P1_7==0){delay(20);while(P1_7==0);delay(20);number=1;}
if(P1_6==0){delay(20);while(P1_6==0);delay(20);number=5;}
if(P1_5==0){delay(20);while(P1_5==0);delay(20);number=9;}
if(P1_4==0){delay(20);while(P1_4==0);delay(20);number=13;}
P1=0xFF;
P1_2=0;
if(P1_7==0){delay(20);while(P1_7==0);delay(20);number=2;}
if(P1_6==0){delay(20);while(P1_6==0);delay(20);number=6;}
if(P1_5==0){delay(20);while(P1_5==0);delay(20);number=10;}
if(P1_4==0){delay(20);while(P1_4==0);delay(20);number=14;}
P1=0xFF;
P1_1=0;
if(P1_7==0){delay(20);while(P1_7==0);delay(20);number=3;}
if(P1_6==0){delay(20);while(P1_6==0);delay(20);number=7;}
if(P1_5==0){delay(20);while(P1_5==0);delay(20);number=11;}
if(P1_4==0){delay(20);while(P1_4==0);delay(20);number=15;}
P1=0xFF;
P1_0=0;
if(P1_7==0){delay(20);while(P1_7==0);delay(20);number=4;}
if(P1_6==0){delay(20);while(P1_6==0);delay(20);number=8;}
if(P1_5==0){delay(20);while(P1_5==0);delay(20);number=12;}
if(P1_4==0){delay(20);while(P1_4==0);delay(20);number=16;}
return number;
}
}LCD1602 Show :
#include <REGX52.H>
// Pin configuration :
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0
// Function definition :
/**
* @brief LCD1602 The time delay function ,12MHz Call can be delayed 1ms
* @param nothing
* @retval nothing
*/
void LCD_Delay()
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
/**
* @brief LCD1602 Write orders
* @param Command Command to write
* @retval nothing
*/
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602 Writing data
* @param Data The data to be written
* @retval nothing
*/
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602 Set cursor position
* @param Line Row position , Range :1~2
* @param Column Column position , Range :1~16
* @retval nothing
*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));
}
}
/**
* @brief LCD1602 Initialization function
* @param nothing
* @retval nothing
*/
void LCD_Init()
{
LCD_WriteCommand(0x38);// Eight bit data interface , Two lines show ,5*7 Lattice
LCD_WriteCommand(0x0c);// Show on , The cursor is off , Flashing off
LCD_WriteCommand(0x06);// After data reading and writing , The cursor automatically adds one , The picture doesn't move
LCD_WriteCommand(0x01);// Cursor reset , Clear the screen
}
/**
* @brief stay LCD1602 Display a character at the specified position
* @param Line Row position , Range :1~2
* @param Column Column position , Range :1~16
* @param Char Characters to display
* @retval nothing
*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
/**
* @brief stay LCD1602 Start displaying the given string at the specified position
* @param Line Start line position , Range :1~2
* @param Column Start column position , Range :1~16
* @param String String to display
* @retval nothing
*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
/**
* @brief Return value =X Of Y Power
*/
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
/**
* @brief stay LCD1602 Start displaying the given number at the specified position
* @param Line Start line position , Range :1~2
* @param Column Start column position , Range :1~16
* @param Number Number to display , Range :0~65535
* @param Length The length of the number to display , Range :1~5
* @retval nothing
*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
}
}
Buzzer :
#include <REGX52.H>
#include <INTRINS.H>
// Buzzer port :
sbit Buzzer=P2^5;
/**
* @brief Buzzer private delay function , Time delay 500us
* @param nothing
* @retval nothing
*/
void Buzzer_Delay500us() //@12.000MHz
{
unsigned char i;
_nop_();
i = 247;
while (--i);
}
/**
* @brief The buzzer makes a sound
* @param ms The duration of the sound , Range :0~32767
* @retval nothing
*/
void Buzzer_Time(unsigned int ms)
{
unsigned int i;
for(i=0;i<ms*2;i++)//2x500us=1ms
{
Buzzer=!Buzzer;
Buzzer_Delay500us();// Phonation frequency 1000Hz, One cycle time 0.5ms, so 29 Yes ms want *2
}//f=1/T, One cycle is 2x500us=1ms( A crest and a trough ),f=1/(1x10^-3)=1000Hz
}
The time delay function :
void delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms){
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
xms--;
}
}
边栏推荐
- 英伟达Jetson Nano的初步了解
- Quick Pow: 如何快速求幂
- Visual Studio 2017 无法打开包括文件: “QOpenGLFunctions_3_3_Core”: No such file or directory
- Crmeb SMS for program configuration of knowledge payment system
- Outsourcing work for three years, waste a step confused
- Simple pages
- 清洁、对话、带娃,扫地机摆脱“人工智障”标签
- Time flies that year
- 81. search rotation sort array II
- 赛芯电子冲刺科创板上市:拟募资6.23亿元,共有64项专利申请信息
猜你喜欢

如何在IDEA中创建Module、以及怎样在IDEA中删除Module?

81. search rotation sort array II

The SQL statement concat cannot find the result

干外包3年,真废了...

Preliminary understanding of NVIDIA Jetson nano

Outsourcing work for three years, waste a step confused

Common settings in idea

How to switch to root in xshell

太卷了~ 八股文,面试最强王者!

网易云音乐内测音乐社交 App“MUS”,通过音乐匹配同频朋友
随机推荐
c语言期末不挂科(上)
Video to image -cv2 Videocapture() usage
SFDP super form development platform v6.0.4 was officially released
作文总写不好怎么办?猿辅导:家长要注意这几点
How to refuse the useless final review? Ape tutoring: it is important to find a suitable review method
Analysis of IM instant messaging development technology on modern web
Kwai reached out to the "supply side" to find the "source" of live broadcast e-commerce?
我,33岁,字节跳动测试开发,揭开北京“测试岗”的真实收入
Nested call and chained access of functions in handwritten C language
干外包3年,真废了...
What are the top ten securities companies? In addition, is it safe to open a mobile account?
Arlo felt lost
阿四的情绪波动
Go 中的 UDP 服务器和客户端
如何拒绝期末复习无用功?猿辅导:找准适合自己的复习方法很重要
Too voluminous ~ eight part essay, the strongest king of interview!
Newton method (optimization of two variable functions)
A Yu's Rainbow Bridge
外包干了三年,废的一踏糊涂...
快手伸手“供给侧”,找到直播电商的“源头活水”?
