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

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

  • static void BSTIM_init(void)
  • {

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

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

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

  •     ald_timer_irq_handler(&g_bstim_init);

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

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

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

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

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

  •     return;
  • }
  • 复制代码
          定时器初始化:
    static void init_timer(void)
  • {

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

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

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

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


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


  •     /* Enable NVIC GP16C4T1 CC interrupt */
  •     ald_mcu_irq_config(AD16C4T_UP_TRIG_COM_IRQn, 4, ENABLE);
  • }
  • 复制代码
          接下来就是定时器对占空比的修改:
    if(timerCnt%10 == 0)
  • {
  •     oc_init.pulse = timerCnt;
  •     ald_timer_oc_config_channel(&g_ad16c4t_init, &oc_init, ALD_TIMER_CHANNEL_1);
  •     ald_timer_oc_start_by_it(&g_ad16c4t_init, ALD_TIMER_CHANNEL_1);

  • }
  • 复制代码
           效果如下:
    image.png