📄 led_key.c
字号:
/*************************************************/
/********************显示与键盘接口********/
/*************2002年12月13日*******************/
/************WROTE BY WANGSW********************/
#include "reg52x2.h"
#include <intrins.h>
#include "define.h"
#include "led_key.h"
#define KEY_SHORT_INTERVAL 2
#define KEY_LONG_INTERVAL 40
sbit SDA = P1^0; /*模拟串行转并行口,下降沿有效,输出为低电平可控点亮*/
sbit SCL = P1^1; /*模拟串并行转换的时钟信号线*/
sbit KEY = P1^2; /*键盘,低电平有效,检测位*/
sbit DISPLAY0 = P1^3; /*EBIT4, 低电平有效*/
sbit DISPLAY1 = P1^4; /*EBIT3*/
sbit DISPLAY2 = P1^5; /*EBIT2*/
sbit DISPLAY3 = P1^6; /*EBIT1*/
sbit LED = P1^7; /*EBIT0,低电平有效*/
bool LED_KEY_SIGN = FALSE;
byte data KeyCounter = 0;
byte data KeyIntervalSafeguard = 0; /*用于连续两个按键速度过快导致按键混乱*/
byte data g_KeyStore = 0x00;
static byte code KeyMap[8] = /*键盘转换*/
{
KEY1, KEY2, KEY3, KEY4, KEY5, KEY6, KEY7, KEY8
};
static byte code LedDisplayMap[2][16] =
{
{0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E},
{0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10, 0x08, 0x03, 0x46, 0x21, 0x06, 0x0E}
};
static void SendData(byte value);
static byte KeyCheck(void); /*键值检测*/
/******************************************************************************************
*函数名: SendData
*参数: value 需要进行串并转换的数据,是一字节8位数据
*返回值: 无
*描述: 把数据value按照从高位到低位串行发送到串并转换电路输
入端,主要可以用来协助完成底层LED显示
*编写: 王绍伟
*版本信息: V1.0 2003年8月15日
******************************************************************************************/
static void SendData(byte value)
{
byte data counter;
SCL = 1;
for(counter = 0; counter < 8; counter++)
{
if(value & 0x80) /*判断数据*/
{
SDA = 1;
}
else
{
SDA = 0;
}
SCL = 0; /*产生时钟动作*/
SCL = 1;
value = value << 1;
}
}
/******************************************************************************************
*函数名: KeyCheck
*参数: 无
*返回值: counter 返回键值
ERROR 返回出错信息
*描述: 通过扫描键盘返回按下的按键号
*编写: 王绍伟
*版本信息: V1.0 2003年8月15日
******************************************************************************************/
static byte KeyCheck(void)
{
byte counter;
SDA = 1; /*注意,原来数据为0,现在为1*/
for(counter = 0; counter < 8; counter++) /*r先将扫描线上都置为高电平*/
{
SCL = 0;
SCL = 1;
}
SDA = 0; /*r然后逐行置为低电平,侦测P1.2(KEY反馈线)*/
for(counter = 0; counter < 8; counter++) /*需要修改计数值*/
{
SCL = 0;
SCL = 1;
delay(1); /*必须的延迟,否则数据出错*/
if(!KEY)
{
return(counter); /*r扫描出按下键就返回按下的键值并退出函数*/
}
}
return(ERROR); /*r若没有扫描到按下键就返回ERROR*/
}
/******************************************************************************************
*函数名: led_key_led_control
*参数: LedIndex 点亮的LED发光管号,其取值从1~8有效
*返回值: 无
*描述: 根据LedIndex的值决定选择点亮哪一只LED管
*编写: 王绍伟
*版本信息: V1.0 2003年8月15日
******************************************************************************************/
extern void led_key_led_control(byte LedIndex)
{
P1 = 0xFF;
if(LedIndex)
{
LedIndex = 1 << (LedIndex - 1); /*r当1左移(LedIndex-1)位后,发送到串并行转换电路*/
SendData(~LedIndex);
LED = 0; /*r开启DP-51的Q1三极管,这样就可以开启LED管点亮*/
}
}
/******************************************************************************************
*函数名: led_key_led_display_control
*参数: value LED显示数码值
boDp 是否显示小数点
LedDisplayIndex 代表显示那一块LED
*返回值: 无
*描述: 对选择的LED模块让其显示一个数码的程序
*编写: 王绍伟
*版本信息: V1.0 2003年8月15日
******************************************************************************************/
extern void led_key_led_display_control(byte LedDisplayIndex, bool boDp, byte value)
{
byte i;
i = boDp;
P1 = 0xFF;
SendData(LedDisplayMap[i][value]); /*r发送LED显示数据到串并转换电路*/
P1 &= ~(0x04 << LedDisplayIndex);
}
/******************************************************************************************
*函数名: led_key_key_check
*参数: 无
*返回值: 无
*描述: 按键扫描判定程序
*编写: 王绍伟
*版本信息: V1.0 2003年8月15日
******************************************************************************************/
extern void led_key_key_check(void) /*5*5=25mS*/
{
byte i;
P1 = 0xFF; /*初始化原状态,以免引起错误*/
SDA = 0;
for(i = 0; i < 8; i++) /*r基于DP-51硬件构造,先向扫描线上发送低电平*/
{
SCL = 0;
SCL = 1;
}
if(KEY) /*r检测反馈线,若无键按下,则KEY(P1.2)则会保持高电平,此时判定无键按下,退出键扫程序*/
{
KeyCounter = 0;
return;
}
if(KeyIntervalSafeguard) /*设置这段程序是为了让判定两次按键之间的时间间隔大于等于0.1s,此段程序在初始化后第一次按键时并不执行*/
{
KeyIntervalSafeguard--;
return;
}
KeyCounter++; /*r每25ms执行一次本程序,也就使KeyCounter自加1*/
if(KeyCounter == KEY_SHORT_INTERVAL) /*r若非保持持续按键状态(超过75ms),系统每50ms检测一次按键,若没有按键,退出;若有,发出消息*/
{
i = KeyCheck();
if(i == ERROR)
{
return;
}
msg_queue_in(MSG_KEY, KeyMap[i]);
KeyIntervalSafeguard = 3; /*r确保系统在判定有按键按下后的0.1s内不会对按键的抖动作出多次按键判定*/
}
if(KeyCounter == KEY_LONG_INTERVAL) /*r连续按键判定,如果持续按键超过一秒钟,若不松键,则接下去每经过0.1s,系统就认定又按了一次键*/
{
i = KeyCheck();
if(i == ERROR)
{
return;
}
msg_queue_in(MSG_KEY, KeyMap[i]);
KeyCounter -= 4;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -