本案例采用芯片基本定时器采用16分频16MHZ的系统时钟,得到频率为1MHZ,自动重装值为200,每一次数数周期为0.2ms。
1、获取按键时间值执行函数
unsigned char get_key_press_time(void)
{
static u2 u2_key_scan_time=0; //按键值是轮询获取时间
static u1 u1_key_pin_value = 0; //获取按键链接的管脚信号值 (0/1)
static u2 u2_key_press_continu_time=0; //按键被连续按下时间
unsigned char u1_return_key_press_time = 0; // 所需按键返回时间
static u1 u1_key_press_state=KEY_STATE_RELEASE; //按键状态—(抬起、按下、抖动、短按、3s、5s...)
//1、3ms轮询查询一次,并获得按键管脚的信号值(0或1)
u2Clock_1msInc(&u2_key_scan_time); //1ms累加一次,按键扫描时间
if(u2_key_scan_time >= 3) //3ms扫描一次
{
u2_key_scan_time = 0; //按键扫描时间清0
u1_key_pin_value = ((GPIOA->DIN) & 0x0002); //获取PA1管脚输入寄存器的值(信号)——(SWI)管脚的按键值
}
u2Clock_1msInc(&u2_key_press_continu_time); //开始记录按键被按下时间
//3、判断按键状态,根据不同的按键状态返回按键时间
switch(u1_key_press_state) //根据按键值判断按键状态
{
//如果按键状态是被抬起
case KEY_STATE_RELEASE:
if(!u1_key_pin_value)
{
u2_key_press_continu_time = 0; //按键被按下保持时间清0
u1_key_press_state=KEY_STATE_RELEASE; //按键状态为被抬起
}
else
{
u1_key_press_state=KEY_STATE_PRESSDOWN; //按键状态为被按下
}
break;
//如果按键处于刚刚被按下状态
case KEY_STATE_PRESSDOWN: //如果是低电平0,说明按键被按下
//如果被抬起
if(!u1_key_pin_value) //从按键控制管脚输入数据寄存器中读到了值
{
u2_key_press_continu_time = 0; //按键被按下保持时间清0
u1_key_press_state =KEY_STATE_RELEASE;
}
//如果按键一直按着
else //如果没有从按键控制管脚中读到值
{
u2_key_press_continu_time = 0; //先清0,为20ms消抖做准备
u1_key_press_state = KEY_STATE_SHAKE; //按键状态为按下抖动状态
}
break;
//前20ms是属于抖动消抖阶段
case KEY_STATE_SHAKE: //按键消抖,消抖时间20ms
//如果按键在20ms前被抬起
if(!u1_key_pin_value) //如果从按键控制管脚输入数据寄存器中读到值
{
u1_key_press_state = KEY_STATE_RELEASE; //按键按下状态为抬起RELEASE
}
//如果是一直按着,时间经过20ms,到达短按阶段
else //如果没有从按键控制管脚输入数据寄存器中读到值
{ //按下消抖
if(u2_key_press_continu_time > 20) //1ms累加一次,记录按键被按下的时间长度
{
u1_key_press_state = KEY_STATE_SHORT; //按键状态为短按状态
}
}
break;
//如果按键按下时间进入短按阶段
case KEY_STATE_SHORT: //如果按键被按下状态是短按
if(!u1_key_pin_value) //如果现在被按着
{
u2_key_press_continu_time = 0; //按键被按下保持时间清0
u1_key_press_state = KEY_STATE_RELEASE; //按键被按下装下状态为按下
u1_return_key_press_time = KEY_VALUE_SHORT;
}
else //如果被抬起了
{
if(u2_key_press_continu_time >= 3000) //观察时间已经到了3s
{
u1_key_press_state = KEY_STATE_3S; //按键被按下状态为按下保持3s状态
u1_return_key_press_time = KEY_VALUE_3S; //返回3s按键值
}
}
break;
//如果按键进入按下保持3s阶段
case KEY_STATE_3S:
if(!u1_key_pin_value)
{
u2_key_press_continu_time = 0; //按键被按下保持时间清0
u1_key_press_state = KEY_STATE_RELEASE; //按键按下状态为按下
u1_return_key_press_time = KEY_VALUE_3S; //返回5s按键值
}
else
{
if(u2_key_press_continu_time >= 5000)
{
u1_key_press_state = KEY_STATE_5S; //按键状态是按下保持5s
u1_return_key_press_time = KEY_VALUE_5S; //返回5s按键值
}
}
break;
//如果按键进入按下保持5s阶段
case KEY_STATE_5S:
//如果是按键松开
if(!u1_key_pin_value)
{
u2_key_press_continu_time = 0; //按键被按下保持时间清0 //按键按下状态为按下 (这里按键到5s截至,如果按照5s赋值,就挑不出)
u1_key_press_state = KEY_STATE_RELEASE;
u1_return_key_press_time = KEY_STATE_5S; //返回5s按键值
}
else
{
if(u2_key_press_continu_time >= 8000)
{
u1_key_press_state = KEY_STATE_8S; //按键状态是按下保持8s
u1_return_key_press_time =KEY_STATE_8S; //返回8s按键值
}
}
break;
default:
u2_key_press_continu_time = 0; //按键被按下保持时间清0
u1_key_press_state= KEY_STATE_RELEASE; //按键按下状态为抬起
break;
}
return u1_return_key_press_time; //最终返回按键按下保持时间(短、3、5、8)
}
2、基本定时器
//基本定时器处理程序
void BSTIM_IRQHandler(void)
{
//这里基本定时器采用16分频16MHZ的系统时钟,得到频率为1MHZ,自动重装值为200,每一次数数周期为0.2ms
BSTIM32->ISR |= 0x1; //中断标志寄存器清零 (硬件置位,软件写 1 清零)
tm_200us++; //时间200微秒变量开始累加
tm_1ms++; //为了获得1毫秒基本定时器数数变量开始累加
if (tm_1ms == 5) //0.2ms*5=1ms
{
tm_1ms = 0; //把为了获得1毫秒数数变量清0
flag_1ms = 1; //时间成功过去1ms
}
if (tm_200us == 100) //0.2ms*100=20ms
{
tm_200us = 0; //把为了获得20毫秒数数变量清0
flag_20ms = 1; //时间成功过去20ms
}
if (0 == tm_1ms) //如果基本定时器没有开始数数
{
Time1ms_count++; //启动备用1ms计数累加
}
if (( 0 == ADCComplete)&&(Time1ms_count > 200)) //时间过去40ms且ADC转换没有完成
{
FL_ADC_EnableSWConversion(ADC); //使能ADC软件触发转换
Time1ms_count = 0; //备用1ms计数累加变量清0
}
// FL_ADC_EnableSWConversion(ADC); //使能ADC软件触发转换
}
3、时钟控制标志位
void clock_control(void)
{
flag_20msseed = 0; //过去20ms毫秒标识
flag_1secseed = 0; //过去1sec秒标识
flag_minseed = 0; //过去1min分钟标识
flag_1msseed = 0; //过去1ms毫秒标识
if (flag_1ms) //到达1毫秒
{
flag_1ms = 0; //1ms变量清0
flag_1msseed = 1; //时间成功过去1毫秒
}
if (flag_20ms) //到达20毫秒
{
flag_20ms = 0; //将到达20毫秒标识清零
flag_20msseed = 1; //成功到达20毫秒标识为1
tm_20ms++;
if (tm_20ms >= 50) //20*50=1000ms=1s
{
tm_20ms = 0; //20ms变量清0
flag_1secseed = 1; //成功过去1秒
}
}
if (flag_1secseed) //1秒
{
tm_1sec++;
if (tm_1sec >= 60) //1s*60=60s=1min
{
tm_1sec = 0; //1s变量清0
flag_minseed = 1; //成功过去1分钟
}
}
flag_successed_copy = flag_1secseed; //1分钟拷贝一次成功返回1
}
4、1ms定时器
//1ms累加一次
void u2Clock_1msInc(u2 *v)
{
if (flag_1msseed) //基本定时器时间过去1ms
{
if (*v < 0xffff) //累加到ffff
{
(*v)++;
}
}
}
5、1s定时器
//1s累加一次
void u2Clock_SecInc(u2 *v)
{
if (flag_1secseed) //如果时间过去1s
{
if (*v < 0xffff) //累加到ffff
{
(*v)++;
}
}
}
6、1min定时器
//1min累加一次
void u2Clock_MinInc(u2 *v)
{
if (flag_minseed) //基本定时器成功过去1分钟
{
if (*v < 0xffff) //累加到ffff
{
(*v)++;
}
}
}