一、基础定时
        定时器功能我们常用的就是定时功能,这个也是我们在进行数据采集处理常用的功能,定时进行一些操作,这里我们选用非阻塞闪烁来测试定时器定时功能,熟悉基本配置和应用。
        非阻塞闪烁实际上就就是通过定时中断的方式实现LED的翻转,鉴于前面的额测试,我们选用LED3作为操作的LED,然后在定时中断中实现LED的翻转,相关的硬件已经介绍了,这里主要是软件配置。
       这里要注意下东软定时器中断Callback的明敏,咱们可以在启动文件中查看:
image.png

       其中AD16C4T是高级定时器,通用定时器为(GP16C4T),然后命名的GPTIMB,基本定时器(BS16T)为BSTIM0,希望可以统一一下。
       我们选取功能简单一点的BS16T作为基本定时功能,初始化:
  1. ald_timer_handle_t g_bstim_init;
  2. ald_timer_clock_config_t g_bstim_clock_config;

  3. static void BSTIM_init(void)
  4. {

  5.    
  6.     /* Initialize bstim */
  7.     memset(&g_bstim_init, 0x0, sizeof(g_bstim_init));  /* initialize the g_g_bstim_init_init */
  8.     g_bstim_init.perh = AD16C4T;
  9.     g_bstim_init.init.prescaler    = 72 - 1;             /* clk_count: 1MHz */
  10.     g_bstim_init.init.mode         = ALD_TIMER_CNT_MODE_UP;  /* count up */
  11.     g_bstim_init.init.period       = 1000 - 1;           /* period is 1000 count clock */
  12.     g_bstim_init.init.clk_div      = ALD_TIMER_CLOCK_DIV1;   /* working clock of dead time and filter */
  13.     g_bstim_init.init.re_cnt       = 0;             /* 10 repeat count */
  14.     g_bstim_init.period_elapse_cbk = ald_timer_period_elapsed_callback;  /* updata period callback function */
  15.     ald_timer_base_init(&g_bstim_init);

  16.     /* Initialize clock source */
  17.     g_bstim_clock_config.source = ALD_TIMER_SRC_INTER;   /**< internal clock sources */
  18.     ald_timer_config_clock_source(&g_bstim_init, &g_bstim_clock_config);

  19.     ald_mcu_irq_config(BSTIM0_IRQn, 4, ENABLE);/* Enable AD16C4T interrupt */
  20.     ald_timer_base_start_by_it(&g_bstim_init);       /* Start UPDATE interrupt by interrupt */
  21. }
      在初始化中我们定义了回调函数,这个需要我们进行重定义:
  1. void ald_timer_period_elapsed_callback(struct ald_timer_handle_s *arg)
  2. {
  3.     timerCnt++;
  4.     if(timerCnt > 1000)
  5.     {
  6.         ald_gpio_toggle_pin(TOGGLE_PORT, TOGGLE_PIN);      /* toggle io */
  7.         timerCnt = 0;
  8.     }
  9. }
      中断处理函数看着不用太多处理:
  1. void __attribute__((interrupt)) BSTIM0_Handler(void)
  2. {
  3.     /* Nested IRQ start : Save CSR and enable global interrupt. */
  4.     ALD_NEST_INT_START();

  5.     ald_timer_irq_handler(&g_bstim_init);

  6.     /* Nested IRQ end : Restore CSR and disable global interrupt. */
  7.     ALD_NEST_INT_END();

  8.     return;
  9. }
      中断处理函数其实只是一个入口,进入到回调函数中处理,效果如下:
image.png

二、PWM输出
       PWM输出属于定时器的高级功能之一,上面的基础定时器就无法实现,这里我们需要用到高级定时器或者通用定时器,PWM涉及到了输出引脚,我们为了实现PWM的展示,通过LED的呼吸灯效果进行展示。
       这里我们选择LED6作为呼吸灯的展示灯:
image.png

       对应的AD16C4T高级定时器是CH1。
       初始化,相对于普通定时器功能,还需要进行GPIO和PWM相关的初始化,引脚初始化:
  1. static void init_gpio(void)
  2. {
  3.     ald_gpio_init_t gpio_init;
  4.     memset(&gpio_init, 0x0, sizeof(gpio_init));
  5.     gpio_init.mode = ALD_GPIO_MODE_OUTPUT;
  6.     gpio_init.od   = ALD_GPIO_PUSH_PULL;
  7.     gpio_init.pupd = ALD_GPIO_FLOATING;

  8.     gpio_init.func = ALD_GPIO_FUNC_3;
  9.     ald_gpio_init(CH1_PORT, CH1_PIN, &gpio_init);

  10.     return;
  11. }
      定时器初始化:
  1. static void init_timer(void)
  2. {

  3.     /* Initialize AD16C4T */
  4.     memset(&g_ad16c4t_init, 0x0, sizeof(g_ad16c4t_init));
  5.     g_ad16c4t_init.perh = AD16C4T;
  6.     g_ad16c4t_init.init.prescaler    = 72 - 1;                 /* clk_count: 72 */
  7.     g_ad16c4t_init.init.mode         = ALD_TIMER_CNT_MODE_CENTER1; /* count mode is center1 */
  8.     g_ad16c4t_init.init.period       = 5000 - 1;              /* period is 5000 count clock */
  9.     g_ad16c4t_init.init.clk_div      = ALD_TIMER_CLOCK_DIV1;       /* working clock of dead time and filter */
  10.     g_ad16c4t_init.init.re_cnt       = 0;                      /* no repeat count */
  11.     g_ad16c4t_init.delay_elapse_cbk = ald_timer_compare_callback; /* compare elapsed callback */
  12.     ald_timer_oc_init(&g_ad16c4t_init);

  13.     /* Initialize clock source */
  14.     g_ad16c4t_clock_config.source = ALD_TIMER_SRC_INTER;   /* clock sources is internal */
  15.     ald_timer_config_clock_source(&g_ad16c4t_init, &g_ad16c4t_clock_config);

  16.     /* Compare output configuration for all channels */
  17.     memset(&oc_init, 0x0, sizeof(oc_init));
  18.     oc_init.oc_mode      = ALD_TIMER_OC_MODE_PWM2;      /* compare output mode is PWM2 */
  19.     oc_init.oc_polarity  = ALD_TIMER_OC_POLARITY_HIGH;  /* CHxO compare output polarity is high */
  20.     oc_init.ocn_polarity = ALD_TIMER_OCN_POLARITY_HIGH; /* CHxON compare output polarity is high */
  21.     oc_init.ocn_idle     = ALD_TIMER_OCN_IDLE_RESET;    /* CHxO idle is low */
  22.     oc_init.oc_idle      = ALD_TIMER_OC_IDLE_RESET;     /* CHxON idle is low */

  23.     /* Set the compare value for channel 1 */
  24.     oc_init.pulse = 1500 - 1;
  25.     ald_timer_oc_config_channel(&g_ad16c4t_init, &oc_init, ALD_TIMER_CHANNEL_1);


  26.     /* Start compare output from channel 1 */
  27.     ald_timer_oc_start_by_it(&g_ad16c4t_init, ALD_TIMER_CHANNEL_1);


  28.     /* Enable NVIC GP16C4T1 CC interrupt */
  29.     ald_mcu_irq_config(AD16C4T_UP_TRIG_COM_IRQn, 4, ENABLE);
  30. }
      接下来就是定时器对占空比的修改:
  1. if(timerCnt%10 == 0)
  2. {
  3.     oc_init.pulse = timerCnt;
  4.     ald_timer_oc_config_channel(&g_ad16c4t_init, &oc_init, ALD_TIMER_CHANNEL_1);
  5.     ald_timer_oc_start_by_it(&g_ad16c4t_init, ALD_TIMER_CHANNEL_1);

  6. }
       效果如下:
image.png