/*
程序说明: 快速调用显示及按键模块模板 软件环境: Keil uVision 4.10 硬件环境: CT107单片机综合实训平台(内部晶振11.0592HZ) STCF2K60F2K60S2单片机 日 期: 2018-5-21 备 注:输出结果为数码管显示01234567按下s4 led全部打开,按下s5 led全部关闭*/#include <stc15f2k60s2.h>typedef unsigned char u8;typedef unsigned int u16;#define key_state_0 0#define key_state_1 1#define key_state_2 2/************* 本地常量声明 **************/u8 code t_display[]={ //标准字库// 0 1 2 3 4 5 6 7 8 9 A B C D E F 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,//black - H J K L N o P U t G Q r M y 0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e, 0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码u8 key_scan();bit key_flag;/************* 定时器0初始化 **************/void Timer0Init(void) //1毫秒@11.0592MHz{ AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0xCD; //设置定时初值 TH0 = 0xD4; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0 = 1; //打开定时器中断 EA = 1; //打开总中断}/************* 中断服务程序 **************/void timer0() interrupt 1 using 1{ static char smg_count=0,key_count=0,i=0;//定义中断进入计时数 smg_count++;key_count++; //每进一次中断自增1 if(smg_count==3) //产生3ms定时 { smg_count=0; P2=0XE0;P0=~t_display[i];P2=0X00; //3ms刷新数码管段 P2=0XC0;P0=T_COM[i];P2=0X00; //3ms刷新数码管位 i++; if(i==8)i=0; //选通所有数码管 } if(key_count==10) //产生10ms定时 { key_count=0; key_flag=1; //按键检测标志位置1 }}/************* 主函数体 **************/void main(void){ u8 key_val; P2=0XA0;P0=0X00;P2=0X00; //关蜂鸣器 Timer0Init(); //初始化定时器0 while(1) { if(key_flag) //10ms进入按键扫描一次 { key_flag =0; //关闭标志位 key_val = key_scan(); //调用按键扫描 switch(key_val) //检测按下键值 { case 4:P2=0X80;P0=0X00;P2=0X00;break; //打开所有led case 5:P2=0X80;P0=0Xff;P2=0X00;break; //关闭所有led } } }}/************* 按键扫描程序 **************/u8 key_scan(){ static char key_state=key_state_0; //定义初始状态 u8 key1,key2,key_temp,key_value =0; //零时按键 P30=0;P31=0;P32=0;P33=0;P34=1;P35=1;P42=1;P44=1; //把按键相关io口置0置1 if(P44==0)key1=0x70; if(P42==0)key1=0xb0; if(P35==0)key1=0xd0; if(P34==0)key1=0xe0; if((P44==1)&&(P42==1)&&(P35==1)&&(P34==1))key1=0xf0; P30=1;P31=1;P32=1;P33=1;P34=0;P35=0;P42=0;P44=0; if(P33==0)key2=0x07; if(P32==0)key2=0x0b; if(P31==0)key2=0x0d; if(P30==0)key2=0x0e; if((P33==1)&&(P32==1)&&(P31==1)&&(P30==1))key2=0x0f; key_temp = key1|key2; //组成矩阵判断按键临时值 switch(key_state) //扫描按键状态 { case key_state_0: if(key_temp!=0xff)key_state=key_state_1; //有按键按下 break; case key_state_1: if(key_temp==0xff)key_state=key_state_0; //滤出抖动 else { switch(key_temp) { case 0x77:key_value=4;break; case 0x7b:key_value=5;break; case 0x7d:key_value=6;break; case 0x7e:key_value=7;break; case 0xb7:key_value=8;break; case 0xbb:key_value=9;break; case 0xbd:key_value=10;break; case 0xbe:key_value=11;break; case 0xd7:key_value=12;break; case 0xdb:key_value=13;break; case 0xdd:key_value=14;break; case 0xde:key_value=15;break; case 0xe7:key_value=16;break; case 0xeb:key_value=17;break; case 0xed:key_value=18;break; case 0xee:key_value=19;break; } key_state=key_state_2; } break; case key_state_2: if(key_temp==0xff)key_state=key_state_0; //检测按键是否松开 break; } return key_value;}