AT32F403A通用定时器02

上期:AT32F403A通用定时器01icon-default.png?t=N7T8https://blog.csdn.net/weixin_64557865/article/details/140821669?spm=1001.2014.3001.5501

目录

一、输入部分

1.输入捕获

2.多输入异或

3.PWM输入 

二、案例

1.多输入异或

(1)功能

(2)配置

介绍

步骤

(3)代码

(4)现象

2.PWM输入

(1)功能

(2)配置

介绍

步骤

(3)代码

(4)现象


一、输入部分

通道1输入部分

1.输入捕获

触发信号被检测到时,通道x的数据寄存器(TMRx_CxDT)会记录当前计数器的计数值,并将捕获中断标志(CxIF)置1。如果有使能中断或者DMA请求,则还会进入到相应的中断或DMA。

注:如果在发生捕获后又立即检测到触发信号,此时计数器的计数值会覆盖之前的计数值,同时通道再捕获标志(CxRF)置1。

2.多输入异或

多输入异或

通道1的输入端可以通过TMRx_CH1TMRx_CH2TMRx_CH3经过异或逻辑后输入,可用于连接霍尔传感器,进而计算出电机的转速。

3.PWM输入 

PWM输入

使用PWM输入模式时需要将C1INC2IN同时映射到同一个TMRx_CHx,同时通道1(或通道2)配置成次定时器的复位模式

PWM输入

如图,通道1(CH1)输入信号的上升沿会触发捕获,并将捕获值(0xA)储存到通道1的数据寄存器(C1DT),同时复位定时器,使之从0开始计数

接着,通道1(CH1)输入信号的下降沿会触发捕获,并将捕获值(0x4)储存到通道2的数据寄存器(C2DT);

则输入信号的周期:T = C1DT ÷ TMR_CLK

输入信号的占空比:D = C2DT ÷ C1DT

二、案例

1.多输入异或

(1)功能

对三路霍尔输入信号进行异或输出。

(2)配置

介绍

使用PA3PA6PA7产生三路霍尔信号,将其输入到PA0、PA1、PA2进行异或,PA8根据异或结果输出方波

步骤

①启用定时器(以TMR2为例),选择“异或/HALL模式”;

②选择触发极性(以上升沿为例);

③开启中断;

 ④设置PA3、PA6、PA7、PA8为输出模式;

⑤生成代码。 

(3)代码

main.c

#include "at32f403a_407_wk_config.h"
#include "wk_system.h"

int main(void)
{
  wk_system_clock_config();
  wk_periph_clock_config();
  wk_nvic_config();
  wk_timebase_init();
  wk_tmr2_init();
  wk_gpio_config();
  tmr_counter_enable(TRM2, TRUE);

  while(1)
  {
    /* 产生三路霍尔信号 */
    gpio_bits_set(GPIOA, GPIO_PINS_3);
    delay_us(10)
    gpio_bits_set(GPIOA, GPIO_PINS_6);
    delay_us(10)
    gpio_bits_set(GPIOA, GPIO_PINS_7);
    delay_us(10)
    gpio_bits_reset(GPIOA, GPIO_PINS_3);
    delay_us(10)
    gpio_bits_reset(GPIOA, GPIO_PINS_6);
    delay_us(10)
    gpio_bits_reset(GPIOA, GPIO_PINS_7);
    delay_us(10)
  }
}

at32f403a_407_wk_config.c


#include "at32f403a_407_wk_config.h"

void wk_system_clock_config(void)
{
  crm_reset();
  crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);
  while(crm_flag_get(CRM_LICK_STABLE_FLAG) != SET)
  {
  }

  crm_clock_source_enable(CRM_CLOCK_SOURCE_HICK, TRUE);

  while(crm_flag_get(CRM_HICK_STABLE_FLAG) != SET)
  {
  }

  crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_60, CRM_PLL_OUTPUT_RANGE_GT72MHZ);

  crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);

  while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
  {
  }

  crm_ahb_div_set(CRM_AHB_DIV_1);

  crm_apb2_div_set(CRM_APB2_DIV_2);

  crm_apb1_div_set(CRM_APB1_DIV_2);

  crm_auto_step_mode_enable(TRUE);

  crm_sysclk_switch(CRM_SCLK_PLL);

  while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
  {
  }

  crm_auto_step_mode_enable(FALSE);

  system_core_clock_update();
}

void wk_periph_clock_config(void)
{
  crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);

  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);

  crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);

  crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);
}

void wk_nvic_config(void)
{
  nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);

  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
  nvic_irq_enable(TMR2_GLOBAL_IRQn, 0, 0);
}

void wk_gpio_config(void)
{

  gpio_init_type gpio_init_struct;
  gpio_default_para_init(&gpio_init_struct);


  gpio_bits_set(GPIOA, GPIO_PINS_3 | GPIO_PINS_6 | GPIO_PINS_7 | GPIO_PINS_8);

  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
  gpio_init_struct.gpio_pins = GPIO_PINS_3 | GPIO_PINS_6 | GPIO_PINS_7 | GPIO_PINS_8;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(GPIOA, &gpio_init_struct);

}


void wk_tmr2_init(void)
{
  gpio_init_type gpio_init_struct;
  tmr_input_config_type  tmr_input_struct;
  tmr_output_config_type tmr_output_struct;

  gpio_default_para_init(&gpio_init_struct);

  gpio_init_struct.gpio_pins = GPIO_PINS_0;
  gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init(GPIOA, &gpio_init_struct);

  gpio_init_struct.gpio_pins = GPIO_PINS_1;
  gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init(GPIOA, &gpio_init_struct);

  gpio_init_struct.gpio_pins = GPIO_PINS_2;
  gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init(GPIOA, &gpio_init_struct);

  tmr_base_init(TMR2, 65535, 0);
  tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);
  tmr_clock_source_div_set(TMR2, TMR_CLOCK_DIV1);
  tmr_period_buffer_enable(TMR2, FALSE);

  tmr_sub_sync_mode_set(TMR2, FALSE);
  tmr_primary_mode_select(TMR2, TMR_PRIMARY_SEL_RESET);

  tmr_input_struct.input_channel_select = TMR_SELECT_CHANNEL_1;
  tmr_input_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_STI;
  tmr_input_struct.input_polarity_select  = TMR_INPUT_RISING_EDGE;
  tmr_input_struct.input_filter_value = 0;
  tmr_input_channel_init(TMR2, &tmr_input_struct, TMR_CHANNEL_INPUT_DIV_1);

  tmr_channel1_input_select(TMR2, TMR_CHANEL1_2_3_CONNECTED_C1IRAW_XOR);

  tmr_trigger_input_select(TMR2, TMR_SUB_INPUT_SEL_C1INC);

  tmr_sub_mode_select(TMR2, TMR_SUB_RESET_MODE);

  tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
  tmr_output_struct.oc_output_state = TRUE;
  tmr_output_struct.occ_output_state = FALSE;
  tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.oc_idle_state = FALSE;
  tmr_output_struct.occ_idle_state = FALSE;
  tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_2, &tmr_output_struct);

  tmr_output_channel_immediately_set(TMR2, TMR_SELECT_CHANNEL_4, FALSE);
  tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_2, 0);
  tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_2, FALSE);

  tmr_primary_mode_select(TMR2, TMR_PRIMARY_SEL_RESET);

//tmr_counter_enable(TMR2, TRUE);

  /* 使能定时器中断 */ 
  tmr_interrupt_enable(TMR2, TMR_TRIGGER_INT, TRUE);
}

 at32f403a_407_int.c

#include "at32f403a_407_int.h"
#include "wk_system.h"

void SysTick_Handler(void)
{
  wk_timebase_handler();
}

void TMR2_GLOBAL_IRQHandler(void)
{
  if(tmr_interrupt_flag_get(TMR2, TMR_TRIGGER_FLAG) != RESET)
  {
     tmr_flag_clear(TMR2, TMR_TRIGGER_FLAG);
     GPIOA->odt ^= GPIO_PINS_8;       //PA8根据异或结果翻转电平
  }
}

(4)现象

连接PA0和PA3、PA1和P6、PA2和PA7,逻辑分析仪测量PA0(霍尔1)、PA1(霍尔2)、PA2(霍尔3)和PA8(异或结果)的波形。

当霍尔信号 = “001”时,异或结果为“1”; 

当霍尔信号 = “011”时,异或结果为“0”;

当霍尔信号 = “111”时,异或结果为“1”;

……

即只有当霍尔信号中“1”的个数为奇数时,异或结果才为“1”,其余情况都为“0”。

2.PWM输入

(1)功能

使用32位计数器测量输入PWM的频率占空比。(以测量频率20Hz以上的信号为例)

(2)配置

介绍

PA6产生PWM方波(有条件的可以使用信号发生器),输入到PA0进行测量,在Debug模式下查看所测频率与占空比与逻辑分析所测结果是否一致。

步骤

①TMR2选择“通道1PWM输入”模式,开启“增强模式”(32bit);

② 可通过所测信号的频率范围来设置周期值(以最小20Hz为例),配置通道1极性为上升沿,并且次定时器模式为复位模式,配置通道2极性为下降沿

 ③开启中断;

④配置PA6为输出模式用于产生PWM;

⑤ 生成代码。

(3)代码

main.c

#include "at32f403a_407_wk_config.h"
#include "wk_system.h"

uint16_t duty_cycle = 0;  //占空比
uint32_t frequency = 0;   //频率

int main(void)
{
  wk_system_clock_config();
  wk_periph_clock_config();
  wk_nvic_config();
  wk_timebase_init();
  wk_tmr2_init();
  wk_gpio_config();

  while(1)
  {
    /* 产生PWM波 */
    gpio_bits_set(GPIOA, GPIO_PINS_6);
    delay_us(30);
    gpio_bits_reset(GPIOA, GPIO_PINS_6);
    delay_us(10);
  }
}

 at32f403a_407_wk_config.c

#include "at32f403a_407_wk_config.h"

void wk_system_clock_config(void)
{
  crm_reset();
  crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);
  while(crm_flag_get(CRM_LICK_STABLE_FLAG) != SET)
  {
  }

  crm_clock_source_enable(CRM_CLOCK_SOURCE_HICK, TRUE);

  while(crm_flag_get(CRM_HICK_STABLE_FLAG) != SET)
  {
  }
  crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_60, CRM_PLL_OUTPUT_RANGE_GT72MHZ);
  crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
  while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
  {
  }

  crm_ahb_div_set(CRM_AHB_DIV_1);
  crm_apb2_div_set(CRM_APB2_DIV_2);
  crm_apb1_div_set(CRM_APB1_DIV_2);
  crm_auto_step_mode_enable(TRUE);
  crm_sysclk_switch(CRM_SCLK_PLL);
  while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
  {
  }
  crm_auto_step_mode_enable(FALSE);
  system_core_clock_update();
}

void wk_periph_clock_config(void)
{
  crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);
}

void wk_nvic_config(void)
{
  nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
  nvic_irq_enable(TMR2_GLOBAL_IRQn, 0, 0);
}

void wk_gpio_config(void)
{
  gpio_init_type gpio_init_struct;
  gpio_default_para_init(&gpio_init_struct);
  gpio_bits_set(GPIOA, GPIO_PINS_6);

  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
  gpio_init_struct.gpio_pins = GPIO_PINS_6;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(GPIOA, &gpio_init_struct);
}

void wk_tmr2_init(void)
{
  gpio_init_type gpio_init_struct;
  tmr_input_config_type tmr_ic_init_struct;

  gpio_default_para_init(&gpio_init_struct);

  gpio_init_struct.gpio_pins = GPIO_PINS_0;
  gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init(GPIOA, &gpio_init_struct);

  /* 使能32位计数器 */
  tmr_32_bit_function_enable(TMR2, TRUE);

  tmr_base_init(TMR2, 11999999, 0);
  tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);
  tmr_clock_source_div_set(TMR2, TMR_CLOCK_DIV1);
  tmr_period_buffer_enable(TMR2, FALSE);

  tmr_sub_sync_mode_set(TMR2, FALSE);
  tmr_primary_mode_select(TMR2, TMR_PRIMARY_SEL_RESET);

  tmr_ic_init_struct.input_filter_value = 0;
  tmr_ic_init_struct.input_channel_select = TMR_SELECT_CHANNEL_1;
  tmr_ic_init_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
  tmr_ic_init_struct.input_polarity_select = TMR_INPUT_RISING_EDGE;
  tmr_pwm_input_config(TMR2, &tmr_ic_init_struct, TMR_CHANNEL_INPUT_DIV_1);

  tmr_trigger_input_select(TMR2, TMR_SUB_INPUT_SEL_C1DF1);
  tmr_sub_mode_select(TMR2, TMR_SUB_RESET_MODE);

  tmr_counter_enable(TMR2, TRUE);

  /* 开启中断 */
  tmr_counter_enable(TRM2, TMR_C1_INT, TRUE)
}

at32f403a_407_int.c

#include "at32f403a_407_int.h"
#include "wk_system.h"

extern uint16_t duty_cycle;
extern uint32_t frequency;
uint32_t ic1value = 0;

void SysTick_Handler(void)
{
  wk_timebase_handler();
}

void TMR2_GLOBAL_IRQHandler(void)
{
  if(tmr_interrupt_flag_get(TMR2, TMR_C1_FLAG) != RESET)
  {
     tmr_flag_clear(TMR2, TMR_C1_FLAG);
     ic1value = tmr_channel_value_get(TMR2, TMR_SELECT_CHANNEL_1);//获取上升沿时的计数值
     if(ic1value != 0)
     {
        /* 计算占空比(上升沿时的计数值/下降沿时的计数值) */
        duty_cycle = (tmr_channel_value_get(TMR2, TMR_SELECT_CHANNEL_2) * 100) / ic1value;
        /* 计算频率(定时器时钟/上升沿时的计数值) */
        frequency = system_cor_clock / ic1value;
     }
     else
     {
        duty_cycle = 0;
        frequency = 0;
     }
  }
}

(4)现象

先用逻辑分析仪测量PA6所产生的PWM的频率和占空比;

再连接PA6与PA0,进入Debug(调试模式),对比Watch 1中变量duty_cycle和frequency的值与逻辑分析仪的结果基本一致。

下期:AT32F403A通用定时器03icon-default.png?t=N7T8https://blog.csdn.net/weixin_64557865/article/details/141779922?spm=1001.2014.3001.5501

由于作者水平有限,文中如有错误之处,恳请读者批评指正。 

参考资料: 

《RM_AT32F403A_407_CH_V2.06》的14.2通用定时器(TMR2到TMR5)https://www.arterytek.com/file/download/1995

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值