自写MSP430中断独立键盘,让大家也看看,有啥改进的
本帖最后由 lingergz 于 2015-4-2 08:32 编辑硬件上: 独立按键,按下,则I/O读到的电平为低电平
软件上:主要思想是,
配置I/0口为下降沿触发中断模式,下降沿 开启定时器计数,上升沿停止计数,
判断计数时间,高于500ms则为 短按,大于80小于500ms为 短按,其他为 键盘抖动,忽略掉
现在请大家看看有没有优化的空间,
同时请教下大家, 如果键盘变成 矩阵的,同样不用 延时消除抖动的方式,改怎么写代码?
/***********************************************************************************
* 函数名称:ConfigureClocks()
*
* 函数功能:时钟初始化函数,配置时钟为1 Mhz
*
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
void ConfigureClocks()
{
if (CALBC1_1MHZ==0xFF || CALDCO_1MHZ==0xFF)
{
while(1); // If calibration constants erased
// do not load, trap CPU!!
}
/* Configure Clocks */
BCSCTL1 = CALBC1_1MHZ; // Set DCO
DCOCTL = CALDCO_1MHZ; //
}
/***********************************************************************************
* 函数名称: configureTimer_A()
*
* 函数功能: 定时器A初始化函数,配置为向上计数模式,即从 0 开始到 TACCR0 的值重复计数
*
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
void configureTimer_A()
{
CCTL0 = CCIE; // CCR0 interrupt enabled
TACTL = TASSEL_2 + MC_1; // SMCLK, contmode
}
/***********************************************************************************
* 函数名称:ConfigureClocks()
*
* 函数功能:时钟初始化函数,配置时钟为1 Mhz
*
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
void SysInit()
{
ConfigureClocks();
configureTimer_A();
ConfigureSwitches(); //配置P1的几个管脚为中断模式
}
/***********************************************************************************
* 函数名称:void main(void)
*
* 函数功能:主函数,初始化系统,进入LPM4,等待中断唤醒后进入键盘处理函数
*
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
SysInit();
fall_eage=1;
LPM4;
while (1)
{
key_process();
}
}
/***********************************************************************************
* 函数名称:__interrupt void Timer_A (void)
*
* 函数功能:定时器 A中断函数,每10ms把对应的按键计数器加 1
*
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
switch (key_status)
{
case Zero_key:
{
if(key_0_Tcnt<0xff)
{
key_0_Tcnt++;
}
else
{
key_0_Tcnt=0;
}
break;
}
case One_key:
{
if(key_1_Tcnt<0xff)
{
key_1_Tcnt++;
}
else
{
key_1_Tcnt=0;
}
break;
}
case Two_key:
{
if(key_2_Tcnt<0xff)
{
key_2_Tcnt++;
}
else
{
key_2_Tcnt=0;
}
break;
}
default:
break;
}
}
/***********************************************************************************
* 函数名称:__interrupt void Port_1()
*
* 函数功能:P1端口中断函数,由于端口初始化为下降沿触发,因而在检测到 下降沿时
* 开启T0计数,每次间隔时间为10ms
*
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
#pragma vector=PORT1_VECTOR
__interrupt void Port_1()
{
if (P1IFG&Zero) //
{
key_status = Zero_key ;
P1IFG &= ~Zero;
P1IES ^=Zero ; // Toggle interrupt edge
if(fall_eage)
{
fall_eage=0;
CCR0 = 10000; //开启定时器
LPM4_EXIT;
}
else
{
fall_eage=1;
CCR0 = 0; //关闭定时器
}
}
if (P1IFG&One) //
{
key_status = One_key ;
P1IFG &= ~One;
P1IES ^=One ; //P1.3 Toggle interrupt edge
if(fall_eage)
{
fall_eage=0;
CCR0 = 10000;
LPM4_EXIT;
}
else
{
fall_eage=1;
CCR0 = 0;
}
}
}
/***********************************************************************************
* 函数名称:void key_process()
*
* 函数功能:独立按键处理函数,可以处理长按 和 短按
*
* 输入参数:none
*
* 返回数据:none
*
************************************************************************************/
void key_process()
{
if(fall_eage)
{
if(key_0_Tcnt>8) //0 key short press
{
;
LPM4;
******
}
else //抖动
{
key_0_Tcnt =0;
}
if(key_1_Tcnt>50) //* key long press
{
;
LPM4;
}
else if(key_1_Tcnt>8) //* key short press
{
;
LPM4;
}
else //抖动
{
key_1_Tcnt =0;
}
}
else
{
;
}
}
个人想法: 按键必须有延时去抖,如果只是单按键,又不担心定时器资源不够用,那可以用输入捕获方式来计算宽度(不过这只是理论,因为没法去抖); 矩阵定时器法觉得不行。 hwh1328 发表于 2015-6-27 19:11
个人想法: 按键必须有延时去抖,如果只是单按键,又不担心定时器资源不够用,那可以用输入捕获方式来计算 ...
矩阵按键 怎么做呢
页:
[1]