最近学习开发STM8S003 MCU,,刚入手这颗MCU,对很多功能不太了解,只能一边开发学习,记录一下学习过程。

目前,需要实现KEY1按键长按3s进行关机,Linux下直接获取按键的开始时间戳和结束时间戳,可以直接确定按键的触发时间,目前MCU采用的是按键中断的方式,在中断触发后直接进入进入中断函数进行处理,根据定时器的特性,现在是采用方法如下:
将Tim1进行16分频,即频率为1Mhz,然后设置ARR(预装载计数器)为60000,即每次产生溢出时间为60ms, RCR(重复计数寄存器)为50,即 50 * 60 = 3000ms = 3s 后产生一个更新事件,而在按键中断函数中,在按键释放后,判断是否由此更新事件表示,如果有,则判断为按键触发大于3s,即可实现关机功能。

在实际测试过程中,通过打印的方式进行测试,发现并不是准确的3s产生一个更新事件,有时候2s多,有时候3s多,一直没有找到原因,难道是因为内部的时钟不准?感觉这个可能性比较小,现在还在查找原因,如果有了解原因的,麻烦告知一下^_^

代码如下:
按键配置


#define KEY1_PORT GPIOC

#define KEY1_PIN   GPIO_PIN_3 //KEY1 PC3

#define KEY1  GPIO_ReadInputPin(KEY1_PORT, KEY1_PIN)

GPIO_Init(KEY1_PORT, (GPIO_Pin_TypeDef)KEY1_PIN,GPIO_MODE_IN_PU_IT); //KEY1

TIM1配置

    TIM1_DeInit();
    TIM1_TimeBaseInit(15,TIM1_COUNTERMODE_UP,60000,30);
    TIM1_ARRPreloadConfig(ENABLE);//使能自动重装
    TIM1_Cmd(ENABLE);//开定时器

中断函数

INTERRUPT_HANDLER(EXTI_PORTC_IRQHandler, 5)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
    //key1
    if(RESET == KEY1)
    {
        Delay(50); //按键消抖
        if(RESET == KEY1)                        //确认按下
        {   
                //do something for key1

                key_start_detect();

                while(RESET == KEY1)  //释放检测
                {
                    if (key_stop_detect()) //MODE_SHUT
                    {
                        stop();                                        
                    }  
                }

        }
    }  
}

void key_start_detect()
{
    TIM1_Cmd(DISABLE);
    TIM1_ClearFlag(TIM1_FLAG_UPDATE);
    TIM1_SetCounter(0);  //开始检测,计数清零
    TIM1_Cmd(ENABLE);
}

uint8_t key_stop_detect()
{
    //判断是否有更新事件标志
    if (TIM1_GetFlagStatus(TIM1_FLAG_UPDATE) != RESET)
    {
        TIM1_ClearFlag(TIM1_FLAG_UPDATE);
        return 1;
    }

    return 0;
}


Logo

更多推荐