键盘初始化判断是否有键按下YESNO等待按键触发进入外部中断函数开启定时器逐行扫描键盘确定按下通过定时器消抖返回键盘值抖动继续扫描等待
图3.3.1 键盘扫描流程图
程序代码如下: {
EX0=0;
TMOD&=0XF1;//设置定时器0为模式1方式, TH0=0X2E; //设置初值,为12毫秒 TL0=0X00;
ET0=1; //开启定时器中断0
void key_scan() interrupt 0 //外部中断 0
TR0=1; //启动定时器计数 }
void timer0_isr(void) interrupt 1 //定时器0的中断函数 {
TR0=0; //中断后我们停止计数
ReadKey(); //定时器计数12毫秒后产生中断,调用此函数,读取键值
}
void ReadKey(void) //读键盘值 {
unsigned char i,j,key; j=0xfe;
key=0xff; //设定初值 for (i=0;i<4;i++){
P0=j; //P0口低4位循环输出0,扫描键盘 if ((P0&0xf0)!=0xf0){ //如果有键按下,P0口高4位不会为1,
key=P0; //读取P0口,退出循环,否则循环下次
break; }
j=_crol_(j,1); //此函数功能为左循环移位 }
if (key==0xff){ //如果读取不到P0口的值,比如是干扰,我们不做键值处理,返回
l_keyold=0xff;
P0=0xf0; //恢复P0口,等待按键按下 EX0=1; //返回之前,开启外中断 return; }
if(l_keyold==key){ //检测按键放开否,如果一样表明没放开,
TH0=0X2E; //继续启动定时器,检测按键松开否 TL0=0;
TR0=1; return; }
TH0=0X2E; TL0=0;
TR0=1; //继续启动定时器,检测按键松开否
l_keyold=key; //获取键码做为放开的凭证
for(i=0;i<17;i++){ //查表获得相应的16进制值存放l key变量中 if (key==key_tab) {
l_key=i; break; } } }
3.4 数码管显示程序设计
数码管的程序流程图如图3.4.1所示:
显示端口初始化查表得要显示的段码循环显示 图3.4.1 数码管显示流程图
程序如下:
void display(unsigned char *lp,unsigned char lc)//显示 {
unsigned char i; //定义变量 P2=0; //端口2为输出 P1=P1&0xF8; for(i=0;i P2=table[lp]; //查表法得到要显示数字的数码段 delay(); //延时5个空指令 if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据 break; P2=0; //清0端口,准备显示下位 P1++; //下一位数码管 } } 程序中将P1口的前3位(即低3位)输出0,对应138译门输入脚,全0为第一位数码管,然后再检测是否8位数码管已完全显示,若没有,P1口右移一位,显示下一位数码管。 3.5 键盘显示转换程序 在程序的设计中,我们需要将输入的按键转换为相应的数值在数码管上显示,这里就需要设计一段转换程序,具体代码如下所示: void diszf()//处理转换给数码管显示字符 { bit nums=1; unsigned long tmp; l_tmpdate[0]=freq/10000000; tmp=freq/10000000; if(tmp==0 && nums)l_tmpdate[0]=12; else { nums=0; } tmp=freq000000; l_tmpdate[1]=tmp/1000000; if(l_tmpdate[1]==0 && nums)l_tmpdate[1]=12; else { nums=0; } tmp=tmp00000; l_tmpdate[2]=tmp/100000; if(l_tmpdate[2]==0 && nums)l_tmpdate[2]=12; else { nums=0; } tmp=tmp0000; l_tmpdate[3]=tmp/10000; if(l_tmpdate[3]==0 && nums)l_tmpdate[3]=12; else { nums=0; } tmp=tmp000; l_tmpdate[4]=tmp/1000; if(l_tmpdate[4]==0 && nums)l_tmpdate[4]=12; else { nums=0; } tmp=tmp00; l_tmpdate[5]=tmp/100; if(l_tmpdate[5]==0 && nums)l_tmpdate[5]=12; else { nums=0; } tmp=tmp0; l_tmpdate[6]=tmp/10; if(l_tmpdate[6]==0 && nums)l_tmpdate[6]=12; else { nums=0; } tmp=tmp; l_tmpdate[7]=tmp; } 3.6 扫频程序 在运行扫频程序时,由于之前的按键已经全部被占用,故我们这里将两个记忆键中的一个改为扫频开始按键。只有按下此键后,我们才开始对起始频率,终止频率,步长的设置。