蜂鸣数字计算器Word文件下载.docx
《蜂鸣数字计算器Word文件下载.docx》由会员分享,可在线阅读,更多相关《蜂鸣数字计算器Word文件下载.docx(17页珍藏版)》请在冰豆网上搜索。
voidInterruptTimer0()interrupt1
TH0=0xFC;
//重新加载初值
TL0=0x67;
LedScan();
//调用数码管显示扫描函数
KeyScan();
//调用按键扫描函数
ShowPhoto(tx);
//调用点阵显示函数
/*T1中断服务函数,用于蜂鸣器*/
voidInterruptTimer1()interrupt3
TH1=T1RH;
//重新加载重载值
TL1=T1RL;
BUZZ=~BUZZ;
//反转蜂鸣器控制电平
2、宏定义头文件sys.c
#ifndef__sys_h__
#define__sys_h__
#include"
sys.h"
#defineuintunsignedint
#defineucharunsignedchar
sbitADDR0=P1^0;
sbitADDR1=P1^1;
sbitADDR2=P1^2;
sbitADDR3=P1^3;
sbitENLED=P1^4;
sbitKEY_IN_1=P2^4;
sbitKEY_IN_2=P2^5;
sbitKEY_IN_3=P2^6;
sbitKEY_IN_4=P2^7;
sbitKEY_OUT_1=P2^3;
sbitKEY_OUT_2=P2^2;
sbitKEY_OUT_3=P2^1;
sbitKEY_OUT_4=P2^0;
sbitBUZZ=P1^6;
//蜂鸣器控制引脚
unsignedcharT1RH=0;
//T0重载值的高字节
unsignedcharT1RL=0;
//T0重载值的低字节
unsignedchartx=0;
//矩阵led显示
unsignedcharcodeLedChar[]={//数码管显示字符转换表
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
};
unsignedcharLedBuff[6]={//数码管显示缓冲区
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
unsignedcharcodeKeyCodeMap[4][4]={//矩阵按键编号到标准键盘键码的映射表
{0x31,0x32,0x33,0x26},//数字键1、数字键2、数字键3、加键
{0x34,0x35,0x36,0x25},//数字键4、数字键5、数字键6、乘键
{0x37,0x38,0x39,0x28},//数字键7、数字键8、数字键9、减键
{0x30,0x1B,0x0D,0x27}//数字键0、ESC键、等号键、除键
unsignedcharKeySta[4][4]={//全部矩阵按键的当前状态
{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
unsignedcharcodeimage[6][8]={//符号的字模表
{0xFF,0xBD,0x5A,0xFF,0xFF,0xBD,0xDB,0xE7},//笑脸
{0xE7,0xE7,0xE7,0x00,0x00,0xE7,0xE7,0xE7},//加号
{0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF},//减号
{0x3C,0x18,0x81,0xC3,0xC3,0x81,0x18,0x3C},//乘号
{0xE7,0xE7,0xFF,0x00,0x00,0xFF,0xE7,0xE7},//除号
{0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF}//等号
voidInit();
voidShowNumber(unsignedlongnum);
voidKeyAction(unsignedcharkeycode);
voidKeyDriver();
voidKeyScan();
voidLedScan();
voidOpenBuzz(unsignedintfrequ);
voidStopBuzz();
voidDelay();
voidBuzz(unsignedintfrequ);
voidShowPhoto(unsignedinta);
#endif
3、函数头文件fun.c
#ifndef__fun_h__
#define__fun_h__
fun.h"
voidInit()
EA=1;
//使能总中断
TMOD=0x11;
//设置T0为模式1
//为T0赋初值0xFC67,定时1ms
ET0=1;
//使能T0中断
TR0=1;
//启动T0
/*将一个无符号长整型的数字显示到数码管上,num-待显示数字*/
voidShowNumber(unsignedlongnum)
signedchari;
unsignedcharbuf[6];
for(i=0;
i<
6;
i++)//把长整型数转换为6位十进制的数组
{
buf[i]=num%10;
num=num/10;
for(i=5;
i>
=1;
i--)//从最高位起,遇到0转换为空格,遇到非0则退出循环
if(buf[i]==0)
LedBuff[i]=0xFF;
else
break;
for(;
=0;
i--)//剩余低位都如实转换为数码管显示字符
LedBuff[i]=LedChar[buf[i]];
/*按键动作函数,根据键码执行相应的操作,keycode-按键键码*/
voidKeyAction(unsignedcharkeycode)
staticunsignedlongresult=0;
//用于保存运算结果
staticunsignedlongadd[2]=0;
//用于保存输入的数字
staticunsignedintsign[2]=0;
//用作统计前一次和当前运算符号,0~3依次代表加减乘除
staticunsignedintflag=0;
//用于统计次数
switch(keycode){//不同按键蜂鸣器发出不同频率声音
case0x30:
Buzz(1000);
break;
case0x31:
Buzz(1500);
case0x32:
Buzz(2000);
case0x33:
Buzz(2500);
case0x34:
Buzz(3000);
case0x35:
Buzz(3500);
case0x36:
Buzz(4000);
case0x37:
Buzz(4500);
case0x38:
Buzz(5000);
case0x39:
Buzz(5500);
case0x26:
Buzz(6000);
case0x28:
Buzz(6500);
case0x25:
Buzz(7500);
case0x27:
Buzz(8000);
case0x0D:
Buzz(8500);
case0x1B:
Buzz(9000);
default:
if((keycode>
=0x30)&
&
(keycode<
=0x39))//输入0-9的数字
{if(flag==0){
add[0]=(add[0]*10)+(keycode-0x30);
//整体十进制左移,新数字进入个位
ShowNumber(add[0]);
//运算结果显示到数码管
}else{
add[1]=(add[1]*10)+(keycode-0x30);
ShowNumber(add[1]);
}
elseif(keycode==0x26)//向上键用作加号,执行加法或连加运算
sign[0]=sign[1];
//保存前一次的运算符号
sign[1]=0;
//保存当前运算符号
flag=1;
tx=1;
switch(sign[0]){//用于连加
case0:
add[0]=add[0]+add[1];
case1:
add[0]=add[0]-add[1];
case2:
add[0]=add[0]*add[1];
case3:
add[0]=add[0]/add[1];
default:
add[1]=0;
//清零add[1];
elseif(keycode==0x28)//向下键用作减号,执行减法
{sign[0]=sign[1];
sign[1]=1;
tx=2;
switch(sign[0]){
ShowNumber(add[0]);
elseif(keycode==0x25)//向下键用作乘号,执行乘法
sign[1]=2;
tx=3;
elseif(keycode==0x27)//向下键用作除号,执行除法
sign[1]=3;
tx=4;
elseif(keycode==0x0D)//等号键,执行运算
switch(sign[1]){
{result=add[0]+add[1];
//进行加法运算
ShowNumber(result);
break;
{result=add[0]-add[1];
//进行减法运算
{result=add[0]*add[1];
//进行乘法运算
{result=add[0]/add[1];
//进行除法运算
tx=5;
flag=0;
add[0]=0;
add[1]=0;
sign[0]=0;
sign[1]=0;
elseif(keycode==0x1B)//Esc键,清零结果
{add[0]=0;
result=0;
tx=0;
//清零后的加数显示到数码管
/*按键驱动函数,检测按键动作,调度相应动作函数,需在主循环中调用*/
voidKeyDriver()
unsignedchari,j;
staticunsignedcharbackup[4][4]={//按键值备份,保存前一次的值
};
4;
i++)//循环检测4*4的矩阵按键
for(j=0;
j<
j++)
if(backup[i][j]!
=KeySta[i][j])//检测按键动作
=0)//按键按下时执行动作
KeyAction(KeyCodeMap[i][j]);
//调用按键动作函数
backup[i][j]=KeySta[i][j];
//刷新前一次的备份值
/*按键扫描函数,需在定时中断中调用,调用间隔1ms*/
voidKeyScan()
unsignedchari;
staticunsignedcharkeyout=0;
//矩阵按键扫描输出索引
staticunsignedcharkeybuf[4][4]={//矩阵按键扫描缓冲区
{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},
{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}
//将一行的4个按键值移入缓冲区
keybuf[keyout][0]=(keybuf[keyout][0]<
<
1)|KEY_IN_1;
keybuf[keyout][1]=(keybuf[keyout][1]<
1)|KEY_IN_2;
keybuf[keyout][2]=(keybuf[keyout][2]<
1)|KEY_IN_3;
keybuf[keyout][3]=(keybuf[keyout][3]<
1)|KEY_IN_4;
//消抖后更新按键状态
i++)//每行4个按键,所以循环4次
if((keybuf[keyout][i]&
0x0F)==0x00)
{//连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下
KeySta[keyout][i]=0;
elseif((keybuf[keyout][i]&
0x0F)==0x0F)
{//连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起
KeySta[keyout][i]=1;
//执行下一次的扫描输出
keyout++;
//输出索引递增
keyout=keyout&
0x03;
//索引值加到4即归零
switch(keyout)//根据索引,释放当前输出引脚,拉低下次的输出引脚
case0:
KEY_OUT_4=1;
KEY_OUT_1=0;
case1:
KEY_OUT_1=1;
KEY_OUT_2=0;
case2:
KEY_OUT_2=1;
KEY_OUT_3=0;
case3:
KEY_OUT_3=1;
KEY_OUT_4=0;
default:
/*数码管动态扫描刷新函数,需在定时中断中调用*/
voidLedScan()
staticunsignedchari=0;
//动态扫描的索引
ENLED=0;
//选择数码管进行显示
ADDR3=1;
P0=0xFF;
//显示消隐
switch(i)
ADDR2=0;
ADDR1=0;
ADDR0=0;
i++;
P0=LedBuff[0];
ADDR0=1;
P0=LedBuff[1];
ADDR1=1;
P0=LedBuff[2];
P0=LedBuff[3];
case4:
ADDR2=1;
P0=LedBuff[4];
case5:
i=0;
P0=LedBuff[5];
/*蜂鸣器启动函数,frequ-工作频率*/
voidOpenBuzz(unsignedintfrequ)
unsignedintreload;
//计算所需的定时器重载值
reload=65536-(11059200/12)/(frequ*2);
//由给定频率计算定时器重载值
T1RH=(unsignedchar)(reload>
>
8);
//16位重载值分解为高低两个字节
T1RL=(unsignedchar)reload;
TH1=0xFF;
//设定一个接近溢出的初值,以使定时器马上投入工作
TL1=0xFE;
ET1=1;
TR1=1;
//启动T0
/*蜂鸣器停止函数*/
voidStopBuzz()
ET1=0;
//禁用T0中断
TR1=0;
//停