51单片机按键连击

51单片机按键双击

关键字:51单片机  按键双击

//hnrain 改 //适用于CEPARK 51开发板

/******************************************************************************************

*********************** www.cepark.com            电子园 按键高阶攻略设计大赛

名称:        2*4矩阵键盘扫描 (状态机) 功能:        按键0单击时,点亮P0口的第1357个LED,按键1双击时,点亮P0口的2468个LED,按键2三

击时,点亮P0口的所有的LED             按键按下的时间间隔小于200ms。 其他键按下时,LED状态不变 作者:        alger2009 时间:        2009.12.30 星期三 版本:        V1.0 其他:        该开发板的LED不是单个的LED组成,而是LED逻辑卡; 看门狗程序防止程序跑飞             *******************************************************************************************

**********************/

#include "reg52.h" #include "intrins.h" #include "key2.h"

/******宏定义

*******************************************************************************************

********/ #define        No_key      255                        //无键按下返回值

/****** 定义全局变量

*******************************************************************************************

*/ unsigned char    keyread_flag = 0;                //矩阵键盘扫描标志位 unsigned char num = 0;                        //定时计数器计数变量 unsigned char    outdata = 0;                    //返回值

/******2*4矩阵键盘扫描程序

*******************************************************************************************

*** 返回值:key_return    key_return = 0 单击 key_return = 1 双击 key_return = 2 三击 key_return = 其他,按键无效 *******************************************************************************************

*****************************/ unsigned char read_keyboard(void) {        static unsigned char key_state = 0, key_value, key_line;            // 列读取变量,行扫

描码     static unsigned char key_times = 0;                                    //按键击打次数     static unsigned char Tcount = 0;                                    //按键连击计时变量     unsigned char key_return = No_key, i;                                //按键返回值     switch (key_state)     {         case 0:    //key you meiyou cunzai jiancha                                    //状

态0功能: 按键扫描 连击计时 和连击超时处理             key_line = 0x10;             if (key_times != 0)     Tcount++;        //如果不是第一次击打,计时变量加1

if (Tcount > 20)                        //若连击按键按下时间间隔大于200毫秒

{                 key_times = 0;                        // 按键击打次数归0                    Tcount = 0;                            // 计时变量归0             }             for (i = 0; i < 2; i++)                    // 扫描键盘             {                    P2 = ~key_line;                        // 输入行扫描码                 P2 = ~key_line;                        // 重复送一次              key_value = 0x0f & P2;                // 读列电平                 if (key_value == 0x0f)                     key_line <<= 1;                    // 没有按键,继续扫描                 else                 {                     key_state++;                    // 有按键,停止扫描                     break;                            // 跳出按键扫描                 }             }             break;                                            case 1:                                        //状态1功能:确认按键 读取按键值             if (key_value == (0x0f & P2))            // 再次读列电平,若非抖动             {                 switch (key_line | key_value)        //行扫描码和列电平,确认按键                 {                                    // 键盘编码,返回编码值                     case 0x1e:                        //单击按键0                         key_return = 1;                         break;                     case 0x1d:                         {                              if(key_times == 1 && Tcount < 20)                                 key_return = 2;        //双击按键1                             else                                 key_times++;        //第一次按下,计数加1                         }                         break;                      case 0x1b:                         {                             if(key_times == 2 && Tcount < 20)                                 key_return = 3;        //三击按键2                             else                                 key_times++;        //第一次或第二次按下,计数加1                         }                         break;                      case 0x17:                         key_return = 4;                         break;                      case 0x27:                         key_return = 5;                         break;                     case 0x2b:                         key_return = 6;                         break;                      case 0x2d:                         key_return = 7;                         break;                      case 0x2e:                         key_return = 8;                         break;                 }                 key_state++;                    // 转入等待按键释放状态             }             else                 key_state--;                    // 两次列电平不同返回状态0,(消抖处理)             break;                                case 2:                                    //状态2功能:按键释放判定             P2 = 0x0f;                            // 行线全部输出低电平             P2 = 0x0f;                            // 重复送一次             if ( (P2 & 0x0f) == 0x0f)                 key_state = 0;                    // 按键释放,返回状态0             break;     }     return key_return;                            //返回值 }

/******定时器1 定时1毫秒

******************************************************************************/ void timer1(void) interrupt 3 {     TH1 = (65536-1000)/256;     TL1 = (65536-1000)%256;     if(++num == 10)     {keyread_flag = 1;                    //按键扫描允许标志位      num = 0;        } }

/******定时器初始化

**********************************************************************************/ void timer1_initial(void) {     TH1 = (65536-1000)/256;     TL1 = (65536-1000)%256;             //装初始值     IE = 0x88;                         //开总中断和定时器1中断        TMOD = 0x10;                     //工作方式1     TR1 = 1;                         //启动定时器 }

/******看门狗子程序

*********************************************************************************/ void clr_wdt(void) {     WDTRST=0x1e;     WDTRST=0xe1; }

/******主程序

****************************************************************************************/ main(void) {     P0 = 0xff;                            //初始化LED端口     timer1_initial();                    //定时器1初始化     while(1)     {            if(keyread_flag == 1)            //矩阵扫描标志位允许         {             keyread_flag = 0;             clr_wdt();                    //调用看门狗 (每2的14次方个机器周期内必须调用一

次,使看门狗复位)             outdata = read_keyboard();    //读取矩阵键盘返回值         }

if(outdata == 1)                        P0 = 0xaa;                //单击按键0 点亮第1357个LED         else if(outdata == 2)                    P0 = 0x55;                //双击按键1 点亮第2468个LED         else if(outdata == 3)                    P0 = 0x00;                //三击按键2 点亮全部LED     } }

时间: 2024-10-17 04:50:29

51单片机按键连击的相关文章

[51单片机] nRF24L01 无线模块 测试 按键-灯-远程控制

哈哈,穷吊死一个,自己做的一个超简单的板还没有电源提供,只得借助我的大开发板啦.其实这2个模块是完全可以分开的,无线嘛,你懂得!进入正题,这个实验的功能就是一个发送模块(大的那个板)连接4个按键,通过按动这4个不同的按键来发送4种不同的命令,来控制接收端(小的板)点亮4个不同的灯. >_<!首先是发送模块: 1 void main() 2 { 3 uchar Tx_Buf1[]={1}; //发送的信息1 4 uchar Rx_Buf[32]; //接收到的数据暂存器,最多32字节数据 5 i

电子时钟万年历+51单片机+1602液晶屏+DS1302+DS18B20+按键

这次课程设计要完成的是制作一个基于51单片机的电子时钟的万年历(protues仿真),需要用到1602液晶屏+DS1302+DS18B20+按键等模块.各个的模块就不在一一介绍,直接讲解这个系统的功能,首先是四个按键,第一个按键是选中需要修改时间位置,在按一次选中下一个,依次类推,第二个按键是对数值进行加一,第三个按键对数值进行减一,第四个按键确认. 先放仿真图 然后是代码: main.c #include <REG52.H> #include <intrins.h> #defin

51单片机课程设计:基于DS18B20的温度报警器

51单片机课程设计:基于DS18B20的温度报警器 本程序用于读取DS18B20温度,同时具备报警功能,工程分为3个文件,main.c.temp.c.temp.h,经本人修改部分代码,适用于吉林农业大学51开发板,其他朋友亦可移植到其他型号开发板.工程文件在文章最下方. 1.main.c文件 /*********************************说明****************************************** 本程序用于读取温度检测模块DS18B20数值,并

51单片机课程设计:基于MQ-3的酒精浓度报警器

51单片机课程设计:基于MQ-3的酒精浓度报警器 本程序用于将MQ-3上读取到的模拟信号转换为对应的数字信号,经51单片机处理后,在数码管显示,同时具有报警功能,当检测值高于预警值,蜂鸣器报警.除了可以检测MQ-3酒精浓度模块的AD值,也适用于MQ系列的其他模块,原理基本都相同,都是将读取到的AD值转换为数字信号,程序修改后,如果接线方法正确,可以在吉林农业大学51开发板上完美运行,相关工程文件见最下方附件. /*************************************说明***

[51单片机] SPI nRF24L01无线 [可以放在2个单片机里实现通信]

main.c 1 #include<reg51.h> 2 #include"2401.h" 3 4 #define uint unsigned int 5 #define uchar unsigned char 6 7 sbit KEY8=P3^7; //发送按键 8 sbit beep=P2^3;//喇叭 9 sbit LED6=P1^6; ////接收到数据后的功能实现灯 10 11 void delay_ms(uint z) //延时函数 12 { 13 uint x

【转】看看什么叫51单片机最小系统

单片机最小系统,或者称为最小应用系统,是指用最少的元件组成的单片机可以工作的系统.对51系列单片机来说,最小系统一般应该包括:单片机.晶振电路.复位电路.下面给出一个51单片机的最小系统电路图. 说明 复位电路:由电容串联电阻构成,由图并结合"电容电压不能突变"的性质,可以知道,当系统一上电,RST脚将会出现高电平,并且,这个高电平持续的时间由电路的RC值来决定.典型的51单片机当RST脚的高电平持续两个机器周期以上就将复位,所以,适当组合RC的取值就可以保证可靠的复位.一般教科书推荐

基于51单片机的万年历(算法实现)

基于51单片机的万年历,用到了单片机独立键盘.数码管.LED灯模块实现. 想要简单还是DS1302好用. 1 /************************************************** 2 3 作者:纟彖氵戋 博客:http://www.cnblogs.com/yllinux/ 4 5 时间:2017年6月7日 6 7 目标:利用单片机独立键盘.数码管.LED灯模块实现万年历(算法实现) 8 9 ************************************

51单片机指令详解

                                                            数据传递类指令 以累加器为目的操作数的指令  MOV A,Rn MOV A,direct MOV A,@Ri  MOV A,#data  第一条指令中,Rn代表的是R0-R7.第二条指令中,direct就是指的直接地址,而第三条指令中,就是我们刚才讲过的.第四条指令是将立即数data送到A中. 下面我们通过一些例子加以说明: MOV A,R1 :将工作寄存器R1中的值送入A,R

51单片机控制的收音机(带串口,遥控,芯片89S52+LC72131+LA1845N)

本方案采用89S52做为主控芯片,LC72131+LA1845N做为收音模块,支持按键控制,红外线遥控控制,也可通过串口上位机控制,可以通过计算机并口更新单片机软件程序. 音量用两块DS1804控制,频率信息用一块1602液晶显示. 单面板,飞线很多,呵呵. 硬件方案.rar(Protel99) PC端控制软件.rar(VC++7.1,即Visual Stdio .Net 2003) 本方案的单片机软件使用C语言编写(Keil uVision3),LC72131芯片的驱动稍微麻烦,他使用SPI总