应届生求职网小程序
楼主: candygreen
打印 上一主题 下一主题

[面试] 周立功面试题----ZZ

[复制链接]

主题

好友

1万

积分

世界首富

跳转到指定楼层
1
发表于 2008-10-2 16:40 |显示全部楼层 |倒序浏览


题:用任意一单片机设计一个4X4的键盘并编出程序得到键值,要求有去抖,去抖时单片机可以做其它事情,按一下键盘蜂鸣器叫一下,蜂鸣器叫过程中也要单片机可以做其它事情。(提示:用定时器产生基本节拍)

题目是我做后记下来的,当时在做得时候写的很乱,被老师评为编程不怎么样。回来后想想其实很简单就一个中断函数搞定:

 

void time1_sv() interrupt 5 using 2{
 EA=0;
 TF2=0;    //清中断标志位
 if((spcnt--)==0){spcnt=0;SPEAK=0x00;}
 if(scankey()){count++;
    if(count>8){getkeyval();count=0;spcnt=30;SPEAK=0xff;}
    }
 else {count=0;}
 EA=1;
}

思路是:连续n次进入中断时都检测到有按键,那就去取按键值,并使蜂鸣器叫,蜂鸣器叫多长时间由spcnt的值决定。

试验源程序:

#include "mydef.h"
//定义外围器件地址
#define SPEAK   XBYTE[0xC000]
#define KEYIN  XBYTE[0xE000]
#define KEYOUT  XBYTE[0xF000]
#define PORTA  XBYTE[0xa000]
#define PORTB  XBYTE[0xb000]
#define LEDD   XBYTE[0x9000]
//3000个机器周期中断一次
#define TIME_H (65535-3000)/256
#define TIME_L (65535-3000)%256
//LED显示译码
uchar code table[]={0x0C0,0x0F9,0x0A4,0x0B0,0x99,0x92,0x82,0x0F8,0x80,0x90,0x88,0x83,0x0C6,0x0A1,0x86,0x8E,0x7F,0x89};
//全局变量
uchar key_value,count,spcnt;
//判断有无按键
uchar scankey()
{ KEYOUT=0x00;
  if(((~KEYIN)&0x0f)!=0) return(1);  //有键按下
  else return(0);
 }
//得到键值
void  getkeyval(void)
 {    
    KEYOUT=0x0e;
           switch(KEYIN&0x0f)
             { case 14:key_value=0;break;
              case 13:key_value=1;break;
              case 11:key_value=2;break;
              case 7:key_value=3;break;
              default:break;
             }
    KEYOUT=0x0d;
             switch(KEYIN&0x0f)
             { case 14:key_value=4;break;
              case 13:key_value=5;break;
              case 11:key_value=6;break;
              case 7:key_value=7;break;
              default:break;
             }
      KEYOUT=0x0b;
             switch(KEYIN&0x0f)
             { case 14:key_value=8;break;
              case 13:key_value=9;break;
              case 11:key_value=10;break;
              case 7:key_value=11;break;
              default:break;
             }
    KEYOUT=0x07;
             switch(KEYIN&0x0f)
             { case 14:key_value=12;break;
              case 13:key_value=13;break;
              case 11:key_value=14;break;
              case 7:key_value=15;break;
              default:break;
             }
 }
 //定时T2中断  89c52,w78e58之类的单片机都有定时器2
void time1_sv() interrupt 5 using 2{
 EA=0;
 TF2=0;    //清中断标志位
 if((spcnt--)==0){spcnt=0;SPEAK=0x00;}
 if(scankey()){count++;
    if(count>8){getkeyval();count=0;spcnt=30;SPEAK=0xff;}
    }
 else {count=0;}
 EA=1;
}
//粗劣延时mS级
void msec(uint x)
{
 unsigned int j;
 while((x--)!=0)
 {
  for(j=0;j<=123;j++)
   {;}
 }
}

//数码管显示
void dir(uchar leddat)
{
 ORTA=0x00;
 ORTB=0xff;
 LEDD=table[leddat];
 msec(2);
 ORTA=0xff;
 LEDD=table[leddat];
 ORTB=0x00;
 msec(2);
 ORTB=0xFF;
}

 

//主函数
main()
{
 
 C_T2=0;   //T2工作在定时器
 CP_RL2=0;  //自动装栽
 RCAP2H=TH2=TIME_H;
 RCAP2L=TL2=TIME_L;
 EA=1;
 ET2=1;
 TR2=1;
 while(1)
 { dir(key_value);
  }
 }

+10
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册 QQ登录

本版积分规则

关闭

站长推荐上一条 /1 下一条

应届生微信小程序|应届生求职网YingJieSheng.COM ( 沪ICP备12015550号-13 )

GMT+8, 2025-4-13 01:58

Powered by Discuz!

© 2001-2012 Comsenz Inc.

快速回复 返回顶部 返回列表