gaoyang9992006 发表于 2025-8-8 20:35

【APM32E030R Micro-EVB开发板评测】+ 使用定时器

定时器初始化
void TMR_init(void)
{
    TMR_TimeBase_TtimeBaseConfig;

    /* Enable Clock */
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR14);

    /* Set clockDivision = 1 */
    timeBaseConfig.clockDivision =TMR_CKD_DIV1;
    /* Up-counter */
    timeBaseConfig.counterMode =TMR_COUNTER_MODE_UP;
    /* Set divider = 71.So TMR1 clock freq ~= 72/(71 + 1) = 1MHZ */
    timeBaseConfig.div = 71 ;
    /* Set counter = 0xffff */
    timeBaseConfig.period = 0xFF;
    /* Repetition counter = 0x0 */
    timeBaseConfig.repetitionCounter =0;

    TMR_ConfigTimeBase(TMR14, &timeBaseConfig);

    /* Enable update interrupt*/
    TMR_EnableInterrupt(TMR14, TMR_INT_UPDATE);
    NVIC_EnableIRQRequest(TMR14_IRQn, 2);

    /*Enable TMR14*/
    TMR_Enable(TMR14);
}
定时器中断函数
void TMR14_IRQHandler(void)
{
    if (TMR_ReadIntFlag(TMR14, TMR_INT_FLAG_UPDATE) == SET)
    {
      /* The interrupt flag bit must be cleared first. */
      TMR_ClearIntFlag(TMR14, TMR_INT_FLAG_UPDATE);
      led_tick++;
      lcd_tick++;
      tick++;
    }
}
在定时器中断函数里定义几个计数变量,用于给不同的功能提供时间参考。
通过计数函数来调整执行内容,实现流畅的LED闪烁和LCD更新
int main(void)
{
          uint8_t i=0;

                uint8_t led_index =0;
                uint8_t lcd_index =0;
      
    GPIO_Config_T gpioConfig;

    RCM_EnableAHBPeriphClock(LED2_GPIO_CLK | LED3_GPIO_CLK);
    /* LED2 GPIO configuration */
    gpioConfig.pin = LED2_PIN;
    gpioConfig.mode = GPIO_MODE_OUT;
    gpioConfig.outtype = GPIO_OUT_TYPE_PP;
    gpioConfig.speed = GPIO_SPEED_50MHz;
    gpioConfig.pupd = GPIO_PUPD_NO;
    GPIO_Config(LED2_GPIO_PORT, &gpioConfig);

    /* LED3 GPIO configuration */
    gpioConfig.pin = LED3_PIN;
    GPIO_Config(LED3_GPIO_PORT, &gpioConfig);

    /* Turn LED2 on */
    GPIO_ClearBit(LED2_GPIO_PORT, LED2_PIN);
    /* Turn LED3 off */
    GPIO_SetBit(LED3_GPIO_PORT, LED3_PIN);
   
                TMR_init();
          I2CInit();               
                OLED_Init();
               
                OLED_ColorTurn(0);//0正常显示,1 反色显示
                OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
                                 
                OLED_Interval_On();
                Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();

    OLED_Clear();      
                OLED_Dot_All_On();
                Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();

    OLED_Clear();               
                OLED_ShowPicture(0,0,128,64,BMP1,1);
                OLED_Refresh();
               
                OLED_Clear();
               
                for(i=0;i<5;i++)
                {
                        OLED_ShowChinese(24+(16*i),0,i,16,1);//科学小火箭
                }
                OLED_ShowString(24,16,"KE XUE JIA",16,1);
                OLED_ShowString(24,32,"2025/08/08",16,1);
                OLED_ShowString(0,48,"ASCII:",16,1);      
                OLED_ShowString(63,48,"CODE:",16,1);               
               
                OLED_Refresh();
   
                lcd_index = 32;               
    for (;;)
    {
                        if(led_tick>=1000)
                        {
                              led_tick = 0;
                              /* LED Toggle*/
                              if(led_index++ == 0) APM_TINY_LEDToggle(LED2);
                              if(led_index++ == 1) APM_TINY_LEDToggle(LED3);
                              if(led_index>1) led_index = 0;
                        }

                        if(lcd_tick>=2000)
                        {
                              lcd_tick = 0;
                              if(lcd_index<128)
                              {
                      OLED_ShowChar(48,48,lcd_index,16,1);//显示ASCII字符
                                        OLED_ShowNum(103,48,lcd_index,3,16,1);
                            OLED_Refresh();
                                        lcd_index++;
                              }
                              if(lcd_index>=128) lcd_index = 32;

                        }

    }
}
程序运行后,根据计时器更新ASCII字符与对应编号,同时LED也正常闪烁,实现互不干扰的运行。

阳光爆裂 发表于 2025-8-11 17:00

我一直觉得把Timer作做延时计时有点浪费。
感觉一个systick可以替代不少的timer

心跳回响 发表于 2025-8-13 14:16

Timer的应用还是蛮高级的嘛

gaoyang9992006 发表于 2025-8-13 20:53

阳光爆裂 发表于 2025-8-11 17:00
我一直觉得把Timer作做延时计时有点浪费。
感觉一个systick可以替代不少的timer ...

你说的对,但这里并不是简单的延时,而是类似基于定时器的状态机,通过定时器来触发执行条件,程序执行不阻塞。

阳光爆裂 发表于 2025-8-31 19:04

我就是对事件触发一直都没有弄明白。
另外,项目上暂时也用不到——当然,也可能我的水平没有认识到。

DawnFervor 发表于 2025-9-4 20:45

Timer定时器的典型应用

时光贩卖机 发表于 2025-9-7 15:46

这个定时器的配置和中断服务程序写得不错,LED闪烁和LCD更新的逻辑也很清晰。

心跳回响 发表于 2025-9-7 23:07

Timer14的基本功能,溢出中断。
谢谢楼主的分享

彩虹捕手 发表于 2025-9-24 21:17

这个定时器的配置和中断处理对于初学者来说是个不错的示例,代码结构也很清晰。
页: [1]
查看完整版本: 【APM32E030R Micro-EVB开发板评测】+ 使用定时器