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

[复制链接]
 楼主| gaoyang9992006 发表于 2025-8-8 20:35 | 显示全部楼层 |阅读模式
定时器初始化
  1. void TMR_init(void)
  2. {
  3.     TMR_TimeBase_T  timeBaseConfig;

  4.     /* Enable Clock */
  5.     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
  6.     RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR14);

  7.     /* Set clockDivision = 1 */
  8.     timeBaseConfig.clockDivision =  TMR_CKD_DIV1;
  9.     /* Up-counter */
  10.     timeBaseConfig.counterMode =  TMR_COUNTER_MODE_UP;
  11.     /* Set divider = 71.So TMR1 clock freq ~= 72/(71 + 1) = 1MHZ */
  12.     timeBaseConfig.div = 71 ;
  13.     /* Set counter = 0xffff */
  14.     timeBaseConfig.period = 0xFF;
  15.     /* Repetition counter = 0x0 */
  16.     timeBaseConfig.repetitionCounter =  0;

  17.     TMR_ConfigTimeBase(TMR14, &timeBaseConfig);

  18.     /* Enable update interrupt*/
  19.     TMR_EnableInterrupt(TMR14, TMR_INT_UPDATE);
  20.     NVIC_EnableIRQRequest(TMR14_IRQn, 2);

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

  4.                 uint8_t led_index =0;
  5.                 uint8_t lcd_index =0;
  6.         
  7.     GPIO_Config_T gpioConfig;

  8.     RCM_EnableAHBPeriphClock(LED2_GPIO_CLK | LED3_GPIO_CLK);
  9.     /* LED2 GPIO configuration */
  10.     gpioConfig.pin = LED2_PIN;
  11.     gpioConfig.mode = GPIO_MODE_OUT;
  12.     gpioConfig.outtype = GPIO_OUT_TYPE_PP;
  13.     gpioConfig.speed = GPIO_SPEED_50MHz;
  14.     gpioConfig.pupd = GPIO_PUPD_NO;
  15.     GPIO_Config(LED2_GPIO_PORT, &gpioConfig);

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

  19.     /* Turn LED2 on */
  20.     GPIO_ClearBit(LED2_GPIO_PORT, LED2_PIN);
  21.     /* Turn LED3 off */
  22.     GPIO_SetBit(LED3_GPIO_PORT, LED3_PIN);
  23.    
  24.                 TMR_init();
  25.           I2CInit();               
  26.                 OLED_Init();
  27.                
  28.                 OLED_ColorTurn(0);//0正常显示,1 反色显示
  29.                 OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
  30.                                  
  31.                 OLED_Interval_On();
  32.                 Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();

  33.     OLED_Clear();        
  34.                 OLED_Dot_All_On();
  35.                 Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();

  36.     OLED_Clear();               
  37.                 OLED_ShowPicture(0,0,128,64,BMP1,1);
  38.                 OLED_Refresh();
  39.                
  40.                 OLED_Clear();
  41.                
  42.                 for(i=0;i<5;i++)
  43.                 {
  44.                         OLED_ShowChinese(24+(16*i),0,i,16,1);//科学小火箭
  45.                 }
  46.                 OLED_ShowString(24,16,"KE XUE JIA",16,1);
  47.                 OLED_ShowString(24,32,"2025/08/08",16,1);
  48.                 OLED_ShowString(0,48,"ASCII:",16,1);        
  49.                 OLED_ShowString(63,48,"CODE:",16,1);               
  50.                
  51.                 OLED_Refresh();
  52.    
  53.                 lcd_index = 32;               
  54.     for (;;)
  55.     {
  56.                         if(led_tick>=1000)
  57.                         {
  58.                                 led_tick = 0;
  59.                                 /* LED Toggle*/
  60.                                 if(led_index++ == 0) APM_TINY_LEDToggle(LED2);
  61.                                 if(led_index++ == 1) APM_TINY_LEDToggle(LED3);
  62.                                 if(led_index>1) led_index = 0;
  63.                         }

  64.                         if(lcd_tick>=2000)
  65.                         {
  66.                                 lcd_tick = 0;
  67.                                 if(lcd_index<128)
  68.                                 {
  69.                       OLED_ShowChar(48,48,lcd_index,16,1);//显示ASCII字符
  70.                                         OLED_ShowNum(103,48,lcd_index,3,16,1);
  71.                             OLED_Refresh();
  72.                                         lcd_index++;
  73.                                 }
  74.                                 if(lcd_index>=128) lcd_index = 32;

  75.                         }

  76.     }
  77. }
42746895eee235419.jpg
程序运行后,根据计时器更新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 ...

你说的对,但这里并不是简单的延时,而是类似基于定时器的状态机,通过定时器来触发执行条件,程序执行不阻塞。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2045

主题

16350

帖子

222

粉丝
快速回复 在线客服 返回列表 返回顶部