51单片机学习3


概念

​ 键盘分为编码键盘和非编码键盘(是否有编码器);非编码键盘分为独立键盘和行列式(矩阵式)键盘。

独立键盘检测

​ 抖动现象(5~10ms),一般在检测按下时加入去抖延时,检测松手时不需。

cXXarj.jpg

目标:1、数码管前两位显示一个十进制数,变化范围00~59,开始时显示00,

​ 2、每按下S2键一次,数值加1;每按下S3键一次,数值减1;每按下S4键一次,数值归零;

​ 3、每按下S5键一次,利用定时器功能使数值开始自动每秒加1,再次按下S5键,数值暂停。

代码分析:(省略版)

#include "reg52.h"
#define uchar.....
sbit....
uchar code table[]={};

void display(uchar numdis){
shi=numdis/10;
ge=numdis%10;
}								//显示子函数
void delayms(uint xms){}		  //延时子函数
void init(){                      //初始化函数		
	//定时器初始化
	TMOD = 0x01;				//设置定时器0为工作方式1(M1M0为01)
	TH0 = (65536-45872)/256;	 //装初值11.0592M晶振定时50ms数为45872
	TL0 = (65536-45872)%256;
	EA = 1;				        //开总中断
	ET0 = 1;				    //开定时器0中断(通过 TR0 = 1;开启)
}	
void keyscan(){					//按键扫描子函数
	if(key1==0)
	{
		delayms(10);			//消抖
		if(key1==0)
		{
			num++;
			if(num==60)
				num=0;
			while(!key1);		//等待按键释放
		}
	}
	if(key2==0){}
	if(key3==0){}
	if(key4==0){	while(!key4); TR0=~TR0;}
}
void main()
{
	init();
	while(1)
	{
		keyscan();
		display(num);
	}
}
void T0_time()interrupt 1
{
	TH0 = (65536-45872)/256;	//重装初值
	TL0 = (65536-45872)%256;	
	numt0++;				
	if(numt0==20)				//1秒时间到
	{
		numt0=0;			    //时间清零重计
		num++;					//每秒加1
		if(num==60)
			num=0;
	}
}

矩阵键盘检测

cjpVPI.md.jpg

目标:TX-1C:上电,数码管不显示,顺序按下矩阵键盘后,数码管上依次显示0~F,6个数码管同时静态显示即可

代码分析:(省略版)

void main()
{
    P0=0;			//关闭所有数码管段选
    dula=1;
    dula=0;
    P0=0xc0;		//位选中所有数码管(以后直接送段选信号)
    wela=1;
    wela=0;
  while(1)
  {
      matrixkeyscan();		//不停调用键盘扫描程序
  }
}

void display(uchar num)
{
    P0=table[num];			//显示函数只送段选数据
    dula=1;
    dula=0;
}
void matrixkeyscan()
{
    uchar temp,key;
    P3=0xfe;				//1111 1110 第一行线置低电平,其余为高电平
    temp=P3;				//P3状态赋给临时变量,用于计算
    temp=temp&0xf0;			//1111 0000 若temp高四位有0,则结果不为0xf0;	若无,则一直为0xf0
    if(temp!=0xf0)			//说明有键按下
    {
        delayms(10);		//消抖
        	temp=P3;		//重读
        	temp=temp&0xf0;	//重&
         if(temp!=0xf0)			//说明确实有键按下
         {
             temp=P3;		//再读一下P3状态(行列交叉)
             switch(temp)
             {
                 case 0xee:		//1110 1110
                     key=0;
                     break;
                 case 0xde:		//1101 1110
                     key=1;
                     break;
                 case 0xbe:		//1011 1110
                     key=2;
                     break;
                 case 0x7e:		//0111 1110
                     key=3;
                     break;                
             }
             while(temp!=0xf0)		//等待按键释放
             {
                 temp=P3;			//不断读取
                 temp=temp&0xf0;	//不断相&,只要结果不为0xf0,就说明按键没有被释放
             }
             display(key);			//显示
         }
            
    }
     P3=0xfd;		//1111 1101第二行置低电平,其余为高电平
    。。。。。。。。。。。。。
     P3=0xfb;
    .......................
     P3=0xf7;
    .......................
        
}

switch(表达式)
{
        case 常量表达式1:
            语句1//可多条语句
            break;
        case 常量表达式2:
            语句2break;
        case 常量表达式n:
            语句n;
            break;
    default:				//可无
        语句n+1;
        break;
}

文章作者: 旧时南风
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 旧时南风 !
评论
  目录