📄 key_display.c
字号:
/******************************************************************************************************
File Name:key_display.c
Version:
Discription:显示和按键及消息的处理
Author:
Date:
*******************************************************************************************************/
#include "key_display.h"
typedef unsigned char BYTE;
extern unsigned char lcd_byte;//LC75823E的显示缓冲区中的byte计数
extern unsigned char lcd_bit;//LC75823E的显示缓冲区中一个byte的bit计数
extern BYTE disp_buff[]; //LC75823E显示缓冲区定义,20个字节
extern bit vfd_flag ;//更新显示标志
bit key_detect_en = 1; //是否允许按键检测
bit updata_disp = 0;
unsigned char screen;
unsigned char disp_buf[4] = {0xff,0xff,0xff,0xff};
bit led_blank_flag;
unsigned char key_bak = 0 , yKeyTimeTemp = 0; //按键扫描时用的中间变量
code unsigned char code lcd_segment[] = { LED_0,LED_1,LED_2,LED_3,LED_4,LED_5,LED_6,LED_7,LED_8,LED_9,LED_V,LED__, LED_P,LED_E};//数字0-9,V,-,P,E
#define Clr_bit(b) &= ~(1<<(b))
#define MAX_MSG_POOL 15 //最大信息池深度
unsigned char xdata msg_buf[MAX_MSG_POOL];
unsigned char data msg_read_counter = 0;
unsigned char data msg_write_counter = 0;
/*******************************************************************************************************
* 函数名称: put_msg()
* 功 能:消息池管理,把信息压入消息池中,消息池深度为0~15
* 输入参数: msg
* 输出参数:所需要的信息msg
* 说 明:*消息池深度为15层(0~15)
*在消息池工作过程中,会禁止中断的发生
********************************************************************************************************/
#pragma NOAREGS
#pragma DISABLE
void put_msg(unsigned char msg)small //信息压入消息池
{
msg_buf[msg_write_counter] = msg;
msg_write_counter++;
if(msg_write_counter == MAX_MSG_POOL)
msg_write_counter = 0;
}
/*******************************************************************************************************
* 函数名称: get_msg()
* 功 能:把已经压入消息池中的信息读出来
* 输入参数: msg_temp
* 输出参数:所需要的信息msg
* 说 明:
*******************************************************************************************************/
#pragma DISABLE
unsigned char get_msg(void) small //从消息池中读出信息
{
unsigned char msg;
if(msg_read_counter == msg_write_counter)
{
return NO_MSG;
}
msg = msg_buf[msg_read_counter];
msg_read_counter++;
if(msg_read_counter == MAX_MSG_POOL)
msg_read_counter = 0;
return msg;
}
#pragma AREGS
/*******************************************************************************************************
* 函数名称: display()
* 功 能:LED(四位数码管、最高位为1)的显示管理(共阳)
* 输入参数: msg_temp
* 输出参数:
* 说 明:
*******************************************************************************************************/
void display()
{
if(led_blank_flag)
{
led_com1 = LED_HIGH;
led_com2 = LED_HIGH;
led_com3 = LED_HIGH;
led_com4 = LED_HIGH;
return;
}
if(screen == 0)
{
led_com1 = LED_HIGH;
led_com2 = LED_HIGH;
led_com3 = LED_HIGH;
led_com4 = LED_LOW;
led_seg = disp_buf[3]; // 最高位
}
else if(screen == 1)
{
led_com1 = LED_HIGH;
led_com2 = LED_HIGH;
led_com3 = LED_LOW;
led_com4 = LED_HIGH;
led_seg = disp_buf[2]; // 次高位
}
else if(screen == 2)
{
led_com1 = LED_HIGH;
led_com2 = LED_LOW;
led_com3 = LED_HIGH;
led_com4 = LED_HIGH;
led_seg = disp_buf[1]; // 次低位
}
else if(screen == 3)
{
led_com1 = LED_LOW;
led_com2 = LED_HIGH;
led_com3 = LED_HIGH;
led_com4 = LED_HIGH;
led_seg = disp_buf[0]; // 最低位
}
}
/********************************************************************************************************
* 函数名称:key_scan()
* 功 能:
* 输入参数:
* 输出参数:
* 说 明:
*********************************************************************************************************/
void key_scan(void)
{
unsigned char key_flag_start = 0,temp; //初始化为无按键按下
EA = 0;
CPUCFG |= 0x20; //选择EMI
temp = XBYTE[0x8000];//相当于读P6口的电压
CPUCFG = 0; //IRAM
EA = 1;
if ((temp & 0x01) == 0)key_flag_start = KEY_NEXT;//S0
else if ((temp & 0x02) == 0)key_flag_start = KEY_PREV;//S1
else if ((temp & 0x04) == 0)key_flag_start = KEY_P_P;//S2
if (key_flag_start)
{
if((key_bak != 0) && (key_bak != key_flag_start))
{
yKeyTimeTemp = 0;
}
key_bak = key_flag_start;
if (yKeyTimeTemp < 250)yKeyTimeTemp ++;
if(yKeyTimeTemp == 101) //长按
{
put_msg(key_bak | 0x10);
//put_msg(key_bak | 0x20);
}
else if((yKeyTimeTemp > 120)&&((key_bak==KEY_NEXT)||(key_bak==KEY_PREV))) //音量增加或减小
{
//flash_disp_mask = 1;
put_msg(key_bak | 0x10);
//put_msg(key_bak | 0x20);
yKeyTimeTemp -= 15; //2007-9-29 8:16 by juntham
//yKeyTimeTemp -= 30;
}
}
else
{
if((yKeyTimeTemp < 3)||(yKeyTimeTemp >100)) //长按或抖动
{
yKeyTimeTemp = 0;
}
else//((yKeyTimeTemp >= 3)&&(yKeyTimeTemp <= 200)) //短按
{
put_msg(key_bak);
yKeyTimeTemp = 0;
}
//flash_disp_mask = 0;
}
}
/********************************************************************************************************
* 函数名称: timer4_init()
* 功 能:Timer4的初始化程序,timer4 OSC(振荡器) input 12.288Mh,T4PR = 2.5 * 12288 / 128 = 240,
定时2.5ms;timer4的中断为低优先级.
* 输入参数: msg_temp
* 输出参数:
* 说 明:
********************************************************************************************************/
void timer4_init(void)
{
INTFG0 Clr_bit(F_T4);
T4CON = 0x87; // 选择timer模式,OSC 12.288M为计数源,128预分频,compare mode
T4CNT = 0X00;
T4PR = (unsigned long)CRYSTAL * 2.5 / 128000; //T4PR_set; 2.5 for 12.288M
IP1 &= 0xFB; //关timer4的优先级
IEN1 |= 0x04; //开timer4中断
T4CON |= 0x10; //使能timer4
}
/********************************************************************************************************
* 函数名称: Timer_4_Isr()
* 功 能:timer4中断服务程序,每2.5ms产生一次中断,主要处理了扫描按键,
即每3*2.5ms调用一次键盘扫描函数。
* 输入参数: msg_temp
* 输出参数:
* 说 明:
*********************************************************************************************************/
void Timer_4_Isr() INT_TMR4
{
static unsigned char key_scan_flag = 0;
INTFG0 Clr_bit(F_T4); // timer4 pending bit
_push_(DPS);
DPCON = 0x0; //DPTR0
BANKSEL = 0;
key_scan_flag++;
if(key_scan_flag == 3)
{
if(key_detect_en)
{
key_scan_flag = 0;
key_scan(); // 扫描得到键值 待处理
}
}
screen++;
if(screen > 3)
screen = 0;
display();
_pop_(DPS);
}
/********************************************************************************************************
* 函数名称:
* 功 能:
* 输入参数:定时50MS
* 输出参数:
* 说 明:
********************************************************************************************************/
void timer0_init(void)
{
TMOD = 0x01;//T0的工作模式,12分频,16位
TH0 = (65536-50000/3)/256;
TL0 = (65536-50000/3)%256;
IEN0 |= 0x02;//开t0中断
TCON |= 0x10;//使能t0
}
/********************************************************************************************************
* 函数名称:
* 功 能:中断服务程序,每50MS产生一次中断,定时0.25S
* 输入参数:
* 输出参数:
* 说 明:
********************************************************************************************************/
void t0(void) interrupt 1 using 0
{
unsigned char tcont;
tcont++;
if(tcont==5)
{
tcont=0;
disp_buff[lcd_byte] &= ~(1<<lcd_bit);//熄灭当前字段
vfd_flag = !vfd_flag;//更新显示标志取反,闪烁显示
}
TH0 = (65536-50000/3)/256;
TL0 = (65536-50000/3)%256;
}
/********************************************************************************************************
* 函数名称:
* 功 能:
* 输入参数:
* 输出参数:
* 说 明:
********************************************************************************************************/
void disp_number(unsigned char a,unsigned char b)
{
disp_buf[3] = lcd_segment[a%10];
disp_buf[2] = lcd_segment[b%10] LED_DOT;
disp_buf[1] = lcd_segment[((b%100)/10)];
if (b<100)disp_buf[0] = LED_BLANK;
else disp_buf[0] = LED_ALL_ON;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -