Button计时器(解决倒计时闪烁)

4 篇文章 0 订阅

- (void)startWithTime:(NSInteger)timeLine title:(NSString *)title countDownTitle:(NSString *)subTitle {
    
    // 倒计时时间
    __block NSInteger timeOut = timeLine;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    
    // 每秒执行一次
    dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1.0 * NSEC_PER_SEC, 0);
    dispatch_source_set_event_handler(_timer, ^{
        
        // 倒计时结束,关闭
        if (timeOut <= 0) {
            dispatch_source_cancel(_timer);
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                [self setTitle:title forState:UIControlStateNormal];
                [self setTitleColor:[UIColor colorWithHexString:@"#FFFFFF"] forState:UIControlStateNormal];
                self.backgroundColor = [UIColor colorWithHexString:@"#4F2CE7"];
                self.userInteractionEnabled = YES;
            });
            
        } else {
            
            NSInteger seconds =  timeOut;
            NSString *timeStr = [NSString stringWithFormat:@"%0.2ld",(long)seconds];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                [self setTitleColor:[UIColor colorWithHexString:@"#FFFFFF"] forState:0];
                [self setTitle:[NSString stringWithFormat:@"%@%@",timeStr,subTitle] forState:UIControlStateNormal];
                self.userInteractionEnabled = NO;
            });
            
            timeOut--;
        }
    });
    
    dispatch_resume(_timer);
}

调用:

[sender startWithTime:60 title:@"获取验证码" countDownTitle:@"s"];

如果button在计时的时候一直闪烁可以将UIButtonType设置为UIButtonTypeCustom

 

 

抢答计时器是一种常见的应用场景,可以用于比赛、考试等需要计时的场合。在STM32F407ZGT6开发板上实现抢答计时器可以通过使用定时器和外部中断来实现。 以下是一个简单的示例代码,演示了如何在STM32F407ZGT6开发板上实现抢答计时器: ```c #include "stm32f4xx.h" // 定义计时器和中断的相关参数 #define TIMER TIM2 #define TIMER_IRQn TIM2_IRQn #define TIMER_IRQHandler TIM2_IRQHandler // 定义计时器的时钟频率和计时周期 #define TIMER_CLOCK_FREQ 84000000 #define TIMER_PERIOD 10000 // 10ms // 定义按键的GPIO和引脚 #define BUTTON_GPIO GPIOA #define BUTTON_PIN GPIO_PIN_0 // 定义LED的GPIO和引脚 #define LED_GPIO GPIOD #define LED_PIN GPIO_PIN_12 // 定义计时器计数变量和按键状态变量 volatile uint32_t timerCount = 0; volatile uint8_t buttonPressed = 0; // 初始化计时器 void Timer_Init(void) { // 使能定时器时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 配置定时器的参数 TIM_TimeBaseInitTypeDef timerInit; timerInit.TIM_Prescaler = (TIMER_CLOCK_FREQ / 1000000) - 1; // 设置预分频值,将定时器时钟分频为1MHz timerInit.TIM_CounterMode = TIM_CounterMode_Up; // 设置计数模式为向上计数 timerInit.TIM_Period = TIMER_PERIOD - 1; // 设置计时周期 timerInit.TIM_ClockDivision = TIM_CKD_DIV1; // 设置时钟分频因子 timerInit.TIM_RepetitionCounter = 0; // 设置重复计数值 TIM_TimeBaseInit(TIMER, &timerInit); // 使能定时器更新中断 TIM_ITConfig(TIMER, TIM_IT_Update, ENABLE); // 启动定时器 TIM_Cmd(TIMER, ENABLE); } // 初始化按键 void Button_Init(void) { // 使能按键GPIO时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // 配置按键GPIO为输入模式 GPIO_InitTypeDef gpioInit; gpioInit.GPIO_Pin = BUTTON_PIN; gpioInit.GPIO_Mode = GPIO_Mode_IN; gpioInit.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(BUTTON_GPIO, &gpioInit); } // 初始化LED void LED_Init(void) { // 使能LED GPIO时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); // 配置LED GPIO为输出模式 GPIO_InitTypeDef gpioInit; gpioInit.GPIO_Pin = LED_PIN; gpioInit.GPIO_Mode = GPIO_Mode_OUT; gpioInit.GPIO_OType = GPIO_OType_PP; gpioInit.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(LED_GPIO, &gpioInit); } // 定时器中断处理函数 void TIMER_IRQHandler(void) { if (TIM_GetITStatus(TIMER, TIM_IT_Update) != RESET) { // 清除定时器中断标志位 TIM_ClearITPendingBit(TIMER, TIM_IT_Update); // 计时器计数加1 timerCount++; } } // 外部中断处理函数 void EXTI0_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line0) != RESET) { // 清除外部中断标志位 EXTI_ClearITPendingBit(EXTI_Line0); // 按键按下,设置按键状态变量为1 buttonPressed = 1; } } int main(void) { // 初始化计时器 Timer_Init(); // 初始化按键 Button_Init(); // 初始化LED LED_Init(); // 配置外部中断 EXTI_InitTypeDef extiInit; extiInit.EXTI_Line = EXTI_Line0; extiInit.EXTI_Mode = EXTI_Mode_Interrupt; extiInit.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发 extiInit.EXTI_LineCmd = ENABLE; EXTI_Init(&extiInit); // 配置外部中断中断向量 NVIC_InitTypeDef nvicInit; nvicInit.NVIC_IRQChannel = EXTI0_IRQn; nvicInit.NVIC_IRQChannelPreemptionPriority = 0; nvicInit.NVIC_IRQChannelSubPriority = 0; nvicInit.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvicInit); while (1) { // 检测按键状态变量 if (buttonPressed) { // 按键按下,计时器计数清零 timerCount = 0; // 设置按键状态变量为0 buttonPressed = 0; } // 检测计时器计数值 if (timerCount >= 500) // 500 * 10ms = 5s { // 计时器计数达到5s,LED闪烁 GPIO_ToggleBits(LED_GPIO, LED_PIN); // 计时器计数清零 timerCount = 0; } } } ``` 这段代码使用了定时器TIM2和外部中断EXTI0来实现抢答计时器的功能。当按下按键时,计时器计数清零,并设置按键状态变量为1;当计时器计数达到5秒时,LED闪烁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值