⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 计算器.c

📁 我给我们的开发板用C51编写的计算器的程序原代码
💻 C
字号:
/********************************************************************************/
/*     Project: 计算器(Calculator)                 版本号:V1。0                */
/*     Designed By: ma gong                        CPU:AT89S51 or C51           */
/*     键盘布局如下:         						        */
/*     K2(0)  K4(1)  K6(2)  K8(3)  K10(8)  K12(9)  K14(.)  K16(+)               */ 
/*     K3(4)  K5(5)  K7(6)  K9(7)  K11(-)  K13(*)  K15(/)  K17(=)               */
/*    功能描述:                						*/
/*        可以运算+,-,*,/等计算,运算的长度可以自行设定   		        */
/*        修改 Max_disp_buff 即可。           					*/                
/********************************************************************************/
#include <reg51.h>
#include <math.h>
#include <stdlib.h>
#define  Lcd_Data       P0          //定义数据端口#define  TH0_TL0        (65536-5000)//设定中断的间隔时长
#define  Max_disp_buff  10      //定义最大的显示位数
#define  Key_con        P1      //定义44键盘的连接口线
sbit  RS = P2 ^ 0;       //定义和LCM的连接端口
sbit  RW = P2 ^ 1;
sbit  E = P2 ^ 2;
sbit  Busy = P0 ^ 7;
unsigned char Key_value, Time_delay;
static float left_value = 0;
static float right_value = 0;//开机画面预定义
unsigned char code welcome[] = {"Welcome to :    "};
unsigned char code website[] = {"www.mculover.net"};
unsigned char code designed[]= {"Designed By:    "};
unsigned char code whoami[]  = {"          whoami"};//定义数组变量
unsigned char code keycodes[16]={'0','1','2','3','4','5','6','7','8','9','.','+','-','*','/','=',};
unsigned char number[Max_disp_buff + 1];//定义按键数字的缓冲大小//函数声明 
void Delay(unsigned char x);//延时处理
void Delay_1ms(unsigned char t);//延时子程序,延时 1MS*t S
unsigned char Read_key(void);//按键处理,返回按键的值
unsigned char Test_key(void);//按键检测函数
void Read_Busy(void);//读忙信号判断
void Write_Comm(unsigned char lcdcomm); //写指令函数
void Write_Data(unsigned char lcddata);//写数据函数void Init_LCD_Cal(void);//初始化LCDvoid Init_LCD_Logo(void);//初始化
LCDvoid Init_Timer0(void);//定时器0初始化
void Display (char *buf); //显示函数
void Display_Logo(unsigned char code *DData);//显示LOGO
void Digit_input_calcul(void);//字符输入
void Fun_calculator(unsigned int fuhao);//运算函数
void Calculator_output(float value);//输出计算结果函数
void Show_logo(void);//显示开机面
/******************************************************************************/
void Delay(unsigned char x)//延时处理
   { Time_delay = x; 
       while(Time_delay !=0);
   }
/******************************************************************************/
void Delay_1ms(unsigned char t)//延时子程序,延时 1MS*t S
{ unsigned char a; 
   while(--t != 0) 
        {  for(a = 0; a < 125; a++);          }
}
/******************************************************************************/
unsigned char Read_key(void)//按键处理,返回按键的值
{  unsigned char  j, k, s, key; 
Key_con = 0xf0;//   
if(Key_con != 0xf0)    
{     Delay_1ms(30);//延时消抖  
if(Key_con != 0xf0)  
{      Key_con=0xfe;   
k=0xfe;      
for(j=0;j<4;j++)     
 {           
s=Key_con & 0xf0;    
switch(s)   
{case 0xe0: key=4*j+0; break;          
case 0xd0: key=4*j+1; break;      
case 0xb0: key=4*j+2; break;      
case 0x70: key=4*j+3; break;      
default: break;    }    k = (k << 1) | 0x01;    
Key_con = k;          }//for       
Key_value = keycodes[key];  }    
}//if  else    
Key_value = 0x00;//如果为O, 则表示无键按下 
return Key_value;}
/******************************************************************************/void Timer0_int(void) interrupt 1 using 1//定时0中断处理{ // 调整出入栈的时间,在精度不高的场合可不要! TR0 = 0;    TL0 += (TH0_TL0 + 9) % 256;    TH0 += (TH0_TL0 + 9) / 256 + (char)CY;    TR0 = 1; if(Time_delay != 0)//延时函数用 {  Time_delay--;  } Read_key();//读取键盘的值}/******************************************************************************/
unsigned char Test_key(void)//按键检测函数
{ unsigned char mykey; 
while((mykey = Key_value) == 0x00);//等待  
return mykey;}
/******************************************************************************/
void Read_Busy(void)//读忙信号判断
{ do{  Lcd_Data = 0xff;  RS = 0;  RW = 1;  E = 0;  
Delay(2);//调用中断延时  
E = 1;   
}
while(Busy);}
/******************************************************************************/ 
void Write_Comm(unsigned char lcdcomm) //写指令函数
{  
Lcd_Data = lcdcomm; 
RS = 0; 
RW = 0;
 E = 0; 
Read_Busy(); 
E = 1;
}
/******************************************************************************/
void Write_Data(unsigned char lcddata)//写数据函数
{  
Lcd_Data = lcddata; 
RS = 1; 
RW = 0; 
E = 0; 
Read_Busy(); 
E = 1;
}
/******************************************************************************/
void Init_LCD_Cal(void)//初始化
LCD{ Delay_1ms(400);   //稍微延时,等待LCM进入工作状态 
Write_Comm(0x01);//清显示    
Write_Comm(0x38);    // 8位 2行.    
Write_Comm(0x0c);   //     
Write_Comm(0x07);   // 显示模式,从左至右增加    
Write_Comm(0x80+0x10);    // 定义首地址.
}
/******************************************************************************/
void Init_LCD_Logo(void)//初始化LCD
{ Delay_1ms(400);   //稍微延时,等待LCM进入工作状态 
Write_Comm(0x01);//清显示 
Write_Comm(0x38);//8位2行5*8 
Write_Comm(0x06);//文字不动,光标右移 
Write_Comm(0x0c);//显示开/关,光标开闪烁开}
/******************************************************************************/
void Init_Timer0(void)//定时器0初始化
{ 
TMOD=0x01; 
TH0=TH0_TL0 / 256; 
TL0=TH0_TL0 % 256;
 TR0=1; ET0=1; 
EA=1;
}
/******************************************************************************/
void Display(char *buf)//显示函数
{  unsigned char i;     
Write_Comm(0x01);//clearscreen,清屏命令
 Write_Comm(0x80+0x10);    
for (i=0 ; buf[i] != 0; i++)  
Write_Data(buf[i]);    
}
/******************************************************************************/
void Display_Logo(unsigned char code *DData)//显示LOGO
{ unsigned char  j;   
  for(j=0;j<16;j++)    
       { Write_Data(DData[j]); //显示单个字符  
         Delay(20); 
       }
}
/*******************************************************************************/
void Digit_input_calcul(void)//字符输入
{ static unsigned char pos; 
float tmp;    
unsigned int last_op = 0; 
Write_Data('0'); //上电显示" 0 " 
pos = 0;//位置为0 
while(1) 
{  Key_value = Test_key();//判断是数字还是运算符号,具有等待功能  
if((Key_value == '.') || ((Key_value >= '0') && (Key_value <= '9')))//如果是数字或小数点  
{   if (pos != Max_disp_buff )  //最大计算位           
{     number[pos++] = Key_value;            number[pos] = 0;             Display(number);           }  }  else //如果输入的是运算符号(+,-,*,/,=)  {   tmp = atof(number);//atof函数就是把字符转换成双精度的值   if((Key_value == '+') || (Key_value == '-') || (Key_value == '*') || (Key_value == '/'))   {    left_value = tmp;    last_op = Key_value;   }   else if (Key_value == '=')   {    right_value = tmp;       Fun_calculator(last_op);//计算   }      pos = 0;//从新归位,输入右值        }//else }//for
}
/**********************************************************************************/
void Fun_calculator(unsigned int fuhao)//运算函数
{ bit result = 1; 
  switch(fuhao) 
  {case '+': left_value += right_value;result = 1;break;  
   case '-': left_value -= right_value;result = 1;break;  
   case '*': left_value *= right_value;result = 1;break;  
   case '/': if(right_value != 0)   
               { left_value /= right_value;result = 1;   }   
             else  result = 0;break; //出错      
   default : break; } 
   if(result == 1)Calculator_output(left_value); 
   else Display("*ERROR*");
}
/******************************************************************************/
void Calculator_output(float value)//输出计算结果函数
{ unsigned char buff[Max_disp_buff + 1];//定义显示缓冲 
unsigned char p1=0, p=0; 
float divisor = 100000000;//除数 
float digit = 0; 
if(value >= 0)  buff[p++] = ' '; 
else {   buff[p++] = '-';  
value = -value; } 
if(value >= divisor )  buff[p++]='E'; 
else  while((p < Max_disp_buff ) && (divisor > 1 || value >= 0.00000001))  
{   divisor /= 10;   
digit = floor(value/divisor);//小于指定数的最小整数   
if (divisor < 1 && divisor > 0.01) buff[p++] = '.';          
if (digit != 0 || divisor < 10)           
{     buff[p++] = digit + '0';            
 p1 = 1;                   }          
else if (p1) buff[p++] = '0';         
value -= digit*divisor;  } 
buff[p] = 0;            
Display(buff);
}
/******************************************************************************/
void Show_logo(void)//显示开机画面
{ Write_Comm(0x80);//写入"welcome to"首地址(第一行) 
  Display_Logo(welcome); 
  Write_Comm(0xc0);//写入"website"首地址(第2行) 
  Display_Logo(website); 
  Delay(200);   Write_Comm(0x01);//清屏 
  Write_Comm(0x80);//写入"designed "首地址(第一行) 
  Display_Logo(designed);   Write_Comm(0xc0);//写入"whoami"首地址(第2行) 
  Display_Logo(whoami); 
  Delay(200); 
  Write_Data(0x01);//清屏
}
/******************************************************************************/
void main(void)//主函数
{ Init_Timer0();//初始化T0 
  Init_LCD_Logo(); //初始化 Logo 
  Show_logo();//开机画面显示  
  Init_LCD_Cal(); //初始化 LCM 
  Digit_input_calcul();//计算值输入函数
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -