/*
一个简单的整数计算器。
从4*4矩阵键盘接收 0~9 组成的数字,做加减乘除运算,
并将输入的键值和运算结果显示在LCD上。运算有效位好像只有6位。
*/
#include // 51系列单片机头文件
#include
#include "LCD.h" // 引入 自己编写的 LCD 文件
#define uchar unsigned char
#define uint unsigned int
#define KEY P1 // 键盘 接口
#define LED P0 // 7段数码管用于显示 按下键盘的键值
sbit BEEP = P3^7; // 蜂鸣
uchar code DSY_CODE[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x00}; // 0~f
uchar fuhao = '=', k = 0, KeyNO; // fuhao 用于 记录 最近 使用的 运算符
unsigned long num, a[12], temp1 = 0, temp2 = 0; // temp1 记录 当前输入的数值 temp2 记录 上次输入的数值
//===================================================================//
void delay_ms(uint x); // 微秒级延时函数
void Keys_Scan(); // 接收 从键盘输入的 键值
void Beep(); // 响铃函数
void fenjie (unsigned long n); // LCD数字显示函数
void LCD_Show();// LCD键值显示函数
//================== 调试主函数 ================================//
void main()
{
KEY = 0xf0;
LED = 0xff; // 数码管 灭
IE=0X81;
TCON=0X01; // TCON=0X00; 电平触发时,会接收两次 ??
Init();
W_CMD(0x80+16);
while(1); // 主程序 停留 等待中断
}
//============= 微秒级延时函数 =======================//
void delay_ms(uint x)
{
uchar t;
while(x--)
{
for(t=0;t<120;t++);
}
}
//================== 键值接收函数 ================================//
void Keys_Scan() // 接收 从键盘输入的 键值
{
KEY = 0xf0; // 列置0,求行
if(KEY!=0xf0) // 若 有键按下
{
delay_ms(10);
if(KEY!=0xf0) // 确认 是否键按下
{
switch(KEY) // 求出 所在行 KeyN0按下,松开时显示
{
case 0xe0: KeyNO = 0; break;
case 0xd0: KeyNO = 4; break;
case 0xb0: KeyNO = 8; break;
case 0x70: KeyNO = 12; break;
}
KEY = 0x0f; // 行置0,求列
switch(KEY)
{
case 0x0e: KeyNO = KeyNO + 0; break;
case 0x0d: KeyNO = KeyNO + 1; break;
case 0x0b: KeyNO = KeyNO + 2; break;
case 0x07: KeyNO = KeyNO + 3;break;
}
while(KEY!=0x0f) ;
}
}
}
//================== 响铃函数 ================================//
void Beep() // 响铃函数
{
uchar i;
for(i=0;i<100;i++)
{
delay_ms(1);;
BEEP = ~BEEP;
}
BEEP = 1;
}
//================== LCD数字显示函数 ================================//
void fenjie (unsigned long n) // 接收一个数,求出长度 k , 将其逐位分解,并存放在数组 a【】中 然后输出在 LCD上
{
unsigned long t = n;
uchar i = 1;
k = 0;
while(t >= 1) // 计算 n 的位数 k
{
t = t / 10;
k++;
}
for(i=0;i
{
a[i]=0;
while(n >= pow(10,k-i-1))
{
a[i]++;
n = n - pow(10,k-i-1);
}
}
a[i]=n;
for(i=0;i
{
num = 48 + a[i];
W_DATA(num);
}
}
//================== LCD键值显示函数 ================================//
void LCD_Show()
{
if(KeyNO < 10)
{
num = 48 + KeyNO;
W_DATA(num);
a[k++] = KeyNO;
if(k==1)
{
temp1 = a[0];
}
else
{
temp1 = temp1 * 10 + a[k-1]; // 记录 第一个 计算的数字
}
}
else if(KeyNO==10) // =
{
num = 61;
W_DATA(num);
if(fuhao == '=')
{
fenjie(temp1);
}
if(fuhao == '+')
{
temp1 = temp1 + temp2;
fenjie(temp1);
}
if(fuhao == '-')
{
temp1 = temp2 - temp1;
fenjie(temp1);
}
if(fuhao == '*')
{
temp1 = temp1 * temp2;
fenjie(temp1);
}
if(fuhao == '/')
{
temp1 = temp2 / temp1 ;
fenjie(temp1);
}
fuhao = '=';
}
else if(KeyNO==12) // +++++
{
fuhao = '+';
k = 0;
num = 43;
W_DATA(num);
temp2 = temp1;
}
else if(KeyNO==13) // -----
{
fuhao = '-';
k = 0;
num = 45;
W_DATA(num);
temp2 = temp1;
}
else if(KeyNO==14) // *****
{
fuhao = '*';
k = 0;
num = 42;
W_DATA(num);
temp2 = temp1;
}
else if(KeyNO==15) // ////
{
fuhao = '/';
k = 0;
num = 47;
W_DATA(num);
temp2 = temp1;
}
else if(KeyNO==11)
{
W_CMD(0x01); // 清屏
Init();
W_CMD(0x80+16);
temp1 = 0;
k = 0;
fuhao = '=';
}
}
//=================== 外部中断0 =============================//
void Int0 () interrupt 0// 外部中断0 负 跳沿触发
{
Keys_Scan();
LED = DSY_CODE[KeyNO];
Beep();
LCD_Show();
KEY = 0xf0;
}