[AT32F403/403A] AT32学习记录——高级定时器

[复制链接]
 楼主| zexin 发表于 2024-9-9 19:40 | 显示全部楼层 |阅读模式
本帖最后由 zexin 于 2024-9-10 09:07 编辑

AT32F403A高级定时器
一、简介
高级定时器(TMR1TMR8)包含一个支持向上、向下、中央双向对齐计数的16位计数器、4个通道寄存器、4组独立通道,可实现嵌入死区输入捕获、可编程PWM输出等功能。
二、功能
1.死区插入
高级定时器的通道1至通道3具有互补输出功能,使用时可插入不同时长的死区。
插入死区后:
CxOUT(原通道)的上升沿延迟于CxORAW(参考信号)的上升沿
CxCOUT(互补通道)的上升沿延迟于CxORAW(参考信号)的下降沿
注:死区时间应小于有效电平的宽度。
2.重复计数器
TMRx_RPR(重复计数器周期寄存器)用于配置重复计数器的周期,当TMRx_RPR的RPR[0:7] ≠ 0(重复计数器的计数值不为0)时,重复计数模式开启


计数器每溢出1次,重复计数器的计数值减1,仅当重复计数器计数值减为0时,计数器才产生溢出事件
三、案例
1.带死区的互补输出
(1)功能
高级定时器输出3路带有死区时间互补信(通道1至3)。
(2)配置
介绍
TMR1---通道1及其互补通道---12kHz---50%;
TMR1---通道2及其互补通道---12kHz---25%;
TMR1---通道3及其互补通道---12kHz---12.5%;
步骤
①启用TMR1,选择“通道x和通道x互补输出”;
9435066df9b3753ac3.png
②根据所需频率(F)配置周期值,设置死区时间(DT)的个数(N);
(F = 240MHz / (19999 + 1) = 12kHz)
(DT = N × System_CLK = 12 × 1/240000000 = 50ns)
6806266df9b59ebbea.png

③根据占空比配置通道数据
(D1 = 10000 / (19999 + 1) = 50%)
(D2 = 5000 / (19999 + 1) = 25%)
(D3 = 2500 / (19999 + 1) = 12.5%)
1967966df9b6b77343.png

④生成代码。
(3)代码
main.c
  1. #include "at32f403a_407_wk_config.h"
  2. #include "wk_system.h"

  3. int main(void)
  4. {
  5.   wk_system_clock_config();
  6.   wk_periph_clock_config();
  7.   wk_nvic_config();
  8.   wk_timebase_init();
  9.   wk_tmr1_init();

  10.   while(1)
  11.   {

  12.   }
  13. }

at32f403a_407_wk_config.c

  1. #include "at32f403a_407_wk_config.h"
  2. void wk_system_clock_config(void)
  3. {
  4.   crm_reset();
  5.   crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);
  6.   while(crm_flag_get(CRM_LICK_STABLE_FLAG) != SET)
  7.   {
  8.   }
  9.   crm_clock_source_enable(CRM_CLOCK_SOURCE_HICK, TRUE);
  10.   while(crm_flag_get(CRM_HICK_STABLE_FLAG) != SET)
  11.   {
  12.   }
  13.   crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_60, CRM_PLL_OUTPUT_RANGE_GT72MHZ);
  14.   crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
  15.   while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
  16.   {
  17.   }
  18.   crm_ahb_div_set(CRM_AHB_DIV_1);
  19.   crm_apb2_div_set(CRM_APB2_DIV_2);
  20.   crm_apb1_div_set(CRM_APB1_DIV_2);
  21.   crm_auto_step_mode_enable(TRUE);
  22.   crm_sysclk_switch(CRM_SCLK_PLL);
  23.   while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
  24.   {
  25.   }
  26.   crm_auto_step_mode_enable(FALSE);
  27.   system_core_clock_update();
  28. }

  29. void wk_periph_clock_config(void)
  30. {
  31.   crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
  32.   crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  33.   crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
  34.   crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
  35. }
  36. void wk_nvic_config(void)
  37. {
  38.   nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  39.   NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
  40. }

  41. void wk_tmr1_init(void)
  42. {
  43.   gpio_init_type gpio_init_struct;
  44.   tmr_output_config_type tmr_output_struct;
  45.   tmr_brkdt_config_type tmr_brkdt_struct;

  46.   gpio_default_para_init(&gpio_init_struct);
  47.   gpio_init_struct.gpio_pins = GPIO_PINS_13;
  48.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  49.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  50.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  51.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  52.   gpio_init(GPIOB, &gpio_init_struct);

  53.   gpio_init_struct.gpio_pins = GPIO_PINS_14;
  54.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  55.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  56.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  57.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  58.   gpio_init(GPIOB, &gpio_init_struct);

  59.   gpio_init_struct.gpio_pins = GPIO_PINS_15;
  60.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  61.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  62.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  63.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  64.   gpio_init(GPIOB, &gpio_init_struct);

  65.   gpio_init_struct.gpio_pins = GPIO_PINS_8;
  66.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  67.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  68.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  69.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  70.   gpio_init(GPIOA, &gpio_init_struct);

  71.   gpio_init_struct.gpio_pins = GPIO_PINS_9;
  72.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  73.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  74.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  75.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  76.   gpio_init(GPIOA, &gpio_init_struct);

  77.   gpio_init_struct.gpio_pins = GPIO_PINS_10;
  78.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  79.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  80.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  81.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  82.   gpio_init(GPIOA, &gpio_init_struct);

  83.   tmr_base_init(TMR1, 19999, 0);
  84.   tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);
  85.   tmr_clock_source_div_set(TMR1, TMR_CLOCK_DIV1);
  86.   tmr_repetition_counter_set(TMR1, 0);
  87.   tmr_period_buffer_enable(TMR1, FALSE);

  88.   tmr_sub_sync_mode_set(TMR1, FALSE);
  89.   tmr_primary_mode_select(TMR1, TMR_PRIMARY_SEL_RESET);

  90.   tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
  91.   tmr_output_struct.oc_output_state = TRUE;
  92.   tmr_output_struct.occ_output_state = TRUE;
  93.   tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
  94.   tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_LOW;
  95.   tmr_output_struct.oc_idle_state = TRUE;
  96.   tmr_output_struct.occ_idle_state = FALSE;
  97.   tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_1, &tmr_output_struct);
  98.   tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, 10000);
  99.   tmr_output_channel_buffer_enable(TMR1, TMR_SELECT_CHANNEL_1, FALSE);

  100.   tmr_output_channel_immediately_set(TMR1, TMR_SELECT_CHANNEL_1, FALSE);
  101.   tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
  102.   tmr_output_struct.oc_output_state = TRUE;
  103.   tmr_output_struct.occ_output_state = TRUE;
  104.   tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
  105.   tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_LOW;
  106.   tmr_output_struct.oc_idle_state = TRUE;
  107.   tmr_output_struct.occ_idle_state = FALSE;
  108.   tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_2, &tmr_output_struct);
  109.   tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_2, 5000);
  110.   tmr_output_channel_buffer_enable(TMR1, TMR_SELECT_CHANNEL_2, FALSE);

  111.   tmr_output_channel_immediately_set(TMR1, TMR_SELECT_CHANNEL_2, FALSE);
  112.   tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
  113.   tmr_output_struct.oc_output_state = TRUE;
  114.   tmr_output_struct.occ_output_state = TRUE;
  115.   tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
  116.   tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_LOW;
  117.   tmr_output_struct.oc_idle_state = TRUE;
  118.   tmr_output_struct.occ_idle_state = FALSE;
  119.   tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_3, &tmr_output_struct);
  120.   tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_3, 2500);
  121.   tmr_output_channel_buffer_enable(TMR1, TMR_SELECT_CHANNEL_3, FALSE);

  122.   tmr_output_channel_immediately_set(TMR1, TMR_SELECT_CHANNEL_3, FALSE);
  123.   tmr_brkdt_struct.brk_enable = FALSE;
  124.   tmr_brkdt_struct.auto_output_enable = FALSE;
  125.   tmr_brkdt_struct.brk_polarity = TMR_BRK_INPUT_ACTIVE_LOW;
  126.   tmr_brkdt_struct.fcsoen_state = FALSE;
  127.   tmr_brkdt_struct.fcsodis_state = FALSE;
  128.   tmr_brkdt_struct.wp_level = TMR_WP_LEVEL_3;
  129.   tmr_brkdt_struct.deadtime = 12;
  130.   tmr_brkdt_config(TMR1, &tmr_brkdt_struct);
  131.   tmr_output_enable(TMR1, TRUE);

  132.   tmr_counter_enable(TMR1, TRUE);
  133. }
(4)现象
逻辑分析仪测量PA8、PA9、PA10和PB13、PB14、PB15输出互补波形
8145466df9b935848b.png
2.重复计数器+单周期模式
(1)功能
按键每按下1次,定时器输出10个脉冲。
(2)配置
介绍
单周期模式下,TMR1的通道2重复计数10次。
TMR_CH2---100Hz---50%
步骤
①启用TMR1,开启单周期模式
9594666df9ba39dbc4.png

②根据所需频率(F)和占空比(D)设置周期值通道数据,同时设置重复计数值
(F = 240MHz / (99 + 1) / (23999 + 1) = 100Hz)
(D = 12000 / (23999 + 1) = 50%)
268466df9baff20e0.png

③生成代码。
(3)代码
main.c
  1. #include "at32f403a_407_wk_config.h"
  2. #include "wk_system.h"

  3. #include "at32f403a_407_board.h"    //因为需要使用到按键功能,所以添加了bsp库文件

  4. int main(void)
  5. {
  6.   wk_system_clock_config();
  7.   wk_periph_clock_config();
  8.   wk_nvic_config();
  9.   wk_timebase_init();

  10.   wk_usart1_init();
  11.   wk_tmr1_init();

  12.   at32_board_init();    //包含了按键的初始化
  13.   while(1)
  14.   {
  15.         if(USER_BUTTON == at32_button_press())    //假如按键被按下
  16.         {
  17.                 tmr_counter_enable(TMR1, TRUE);    //使能定时器
  18.         }
  19.   }
  20. }
at32f403a_407_wk_config.c
  1. #include "at32f403a_407_wk_config.h"

  2. void wk_system_clock_config(void)
  3. {
  4.   crm_reset();
  5.   crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);
  6.   while(crm_flag_get(CRM_LICK_STABLE_FLAG) != SET)
  7.   {
  8.   }
  9.   crm_clock_source_enable(CRM_CLOCK_SOURCE_HICK, TRUE);
  10.   while(crm_flag_get(CRM_HICK_STABLE_FLAG) != SET)
  11.   {
  12.   }
  13.   crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_60, CRM_PLL_OUTPUT_RANGE_GT72MHZ);
  14.   crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
  15.   while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
  16.   {
  17.   }
  18.   crm_ahb_div_set(CRM_AHB_DIV_1);
  19.   crm_apb2_div_set(CRM_APB2_DIV_2);
  20.   crm_apb1_div_set(CRM_APB1_DIV_2);
  21.   crm_auto_step_mode_enable(TRUE);
  22.   crm_sysclk_switch(CRM_SCLK_PLL);
  23.   while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
  24.   {
  25.   }
  26.   crm_auto_step_mode_enable(FALSE);
  27.   system_core_clock_update();
  28. }

  29. void wk_periph_clock_config(void)
  30. {
  31.   crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
  32.   crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  33.   crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
  34.   crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
  35.   crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
  36. }

  37. void wk_nvic_config(void)
  38. {
  39.   nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  40.   NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
  41. }

  42. void wk_usart1_init(void)
  43. {
  44.   gpio_init_type gpio_init_struct;
  45.   gpio_default_para_init(&gpio_init_struct);
  46.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  47.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  48.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  49.   gpio_init_struct.gpio_pins = GPIO_PINS_6;
  50.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  51.   gpio_init(GPIOB, &gpio_init_struct);
  52.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  53.   gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
  54.   gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
  55.   gpio_init_struct.gpio_pins = GPIO_PINS_7;
  56.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  57.   gpio_init(GPIOB, &gpio_init_struct);

  58.   gpio_pin_remap_config(USART1_GMUX_0001, TRUE);
  59.   usart_init(USART1, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
  60.   usart_transmitter_enable(USART1, TRUE);
  61.   usart_receiver_enable(USART1, TRUE);
  62.   usart_parity_selection_config(USART1, USART_PARITY_NONE);
  63.   usart_hardware_flow_control_set(USART1, USART_HARDWARE_FLOW_NONE);
  64.   usart_enable(USART1, TRUE);
  65. }

  66. void wk_tmr1_init(void)
  67. {
  68.   gpio_init_type gpio_init_struct;
  69.   tmr_output_config_type tmr_output_struct;
  70.   tmr_brkdt_config_type tmr_brkdt_struct;

  71.   gpio_default_para_init(&gpio_init_struct);
  72.   gpio_init_struct.gpio_pins = GPIO_PINS_9;
  73.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  74.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  75.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  76.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  77.   gpio_init(GPIOA, &gpio_init_struct);
  78.   tmr_base_init(TMR1, 23999, 99);
  79.   tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);
  80.   tmr_clock_source_div_set(TMR1, TMR_CLOCK_DIV1);
  81.   tmr_repetition_counter_set(TMR1, 9);
  82.   tmr_period_buffer_enable(TMR1, FALSE);
  83.   tmr_sub_sync_mode_set(TMR1, FALSE);
  84.   tmr_primary_mode_select(TMR1, TMR_PRIMARY_SEL_RESET);

  85.   tmr_one_cycle_mode_enable(TMR1, TRUE);
  86.   tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
  87.   tmr_output_struct.oc_output_state = TRUE;
  88.   tmr_output_struct.occ_output_state = FALSE;
  89.   tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  90.   tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  91.   tmr_output_struct.oc_idle_state = FALSE;
  92.   tmr_output_struct.occ_idle_state = FALSE;
  93.   tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_2, &tmr_output_struct);
  94.   tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_2, 12000);
  95.   tmr_output_channel_buffer_enable(TMR1, TMR_SELECT_CHANNEL_2, FALSE);

  96.   tmr_output_channel_immediately_set(TMR1, TMR_SELECT_CHANNEL_2, FALSE);
  97.   tmr_brkdt_struct.brk_enable = FALSE;
  98.   tmr_brkdt_struct.auto_output_enable = FALSE;
  99.   tmr_brkdt_struct.brk_polarity = TMR_BRK_INPUT_ACTIVE_LOW;
  100.   tmr_brkdt_struct.fcsoen_state = FALSE;
  101.   tmr_brkdt_struct.fcsodis_state = FALSE;
  102.   tmr_brkdt_struct.wp_level = TMR_WP_OFF;
  103.   tmr_brkdt_struct.deadtime = 0;
  104.   tmr_brkdt_config(TMR1, &tmr_brkdt_struct);
  105.   tmr_output_enable(TMR1, TRUE);

  106. //  tmr_counter_enable(TMR1, TRUE);    //先不使能定时器,到主程序里等待按键按下时再使能定时器
  107. }
(4)现象
每按下一次按键,定时器输出10个脉冲。
6052466df9bc98778c.png
由于作者水平有限,文中如有错误之处,恳请读者批评指正。
参考资料:
《RM_AT32F403A_407_CH_V2.06》的14.4高级定时器(TMR1、TMR8)https://www.arterytek.com/file/download/1995
我喜欢打游戏 发表于 2024-9-10 15:28 | 显示全部楼层
质量很高,波形图和代码讲解的比较详细,感谢大佬分享
xionghaoyun 发表于 2024-9-11 08:39 | 显示全部楼层
很详细的教程
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

17

帖子

1

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