AT32F403A定时器计数&PWM&呼吸灯功能基础配置

定时器计数器功能

以AT32F403A雅特力芯片为基础:

        定时时间:T = 1/f  
         频率  f  :f = 系统频率/预分频/重装载值

#include "time.h"
void clkout_config(void)
{
  gpio_init_type gpio_init_struct;
                crm_clocks_freq_type crm_clocks_freq_struct = {0};
  /* enable gpio port clock */
  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);

  /* set default parameter */
  gpio_default_para_init(&gpio_init_struct);

  /* clkout gpio init */
  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_MUX;
  gpio_init_struct.gpio_pins = GPIO_PINS_8;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(GPIOA, &gpio_init_struct);  

  /* 获取系统时钟*/
  crm_clocks_freq_get(&crm_clocks_freq_struct);
  /* enable tmr1 clock */
  crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);

  /* systemclock/24000/10 = 1000hz = 1/1000 s = 1ms ,freq = sysfrq/((div+1)*(pr+1))*/
  //预分频就是 将此时的系统频率分频。分频后得到的频率就是 计一个数的频率对应的时间 = 频率的倒数
  //那么周期就是计多少个数产生中断溢出  分频后计一个数的时间 * 周期 = 定时时间----》周期值可以这样算:分频后的频率倒数 (单位s) / 定时的时间 = 等于填入的周期值                                                                                                                                                                                                                                                                                                                                                                                                               
  tmr_base_init(TMR1, 24-1, (crm_clocks_freq_struct.ahb_freq / 10000) - 1); 

//总线上240mhz  , 1ms进入 (crm_clocks_freq_struct.ahb_freq / 10000) - 1)是分频
// 24是重装载值 。。。所以计算是系统时钟频率(240mhz/分频系数)/ 重装载值 = 定时器频率                                                                                                                                                                                                                                                                                                                                                                                                              //定时时间 = 频率倒数单位s    
  tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);
  /* 溢出中断使能*/
  tmr_interrupt_enable(TMR1, TMR_OVF_INT, TRUE);
  /* 中断分组 */
  nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  nvic_irq_enable(TMR1_OVF_TMR10_IRQn, 0, 0);
  /* 开始计数 */
  tmr_counter_enable(TMR1, TRUE);
}

int timer_count = 0;
uint16_t temp_pro_count_0_1s = 0;
uint16_t temp_down_count_0_1s = 0;
void  TMR1_OVF_TMR10_IRQHandler(void)
{
  if(tmr_flag_get(TMR1, TMR_OVF_FLAG) != RESET)
  {
    timer_count++;
    temp_pro_count_0_1s++;
    temp_down_count_0_1s++;
    tmr_flag_clear(TMR1, TMR_OVF_FLAG);
  }
}

配置一个pwm 频率2.5k 占空比50%

void pwm_tmr8_config(void)
{
    gpio_init_type gpio_init_struct;
        tmr_output_config_type tmr_oc_init_structure;
 /* peripheral clocks configuration */
  crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_TMR8_PERIPH_CLOCK, TRUE);

  /* gpio configuration */
  gpio_default_para_init(&gpio_init_struct);
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_pins = GPIO_PINS_9;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(GPIOC, &gpio_init_struct);

  /* 初始化 TMR8 的基本时间基数,设置自动重装载寄存器(ARR)和预分频器(PSC) */
  tmr_base_init(TMR8, 1000-1, 96 - 1); //预分频为96,周期给个1000, 频率2.5k=240000000/(1000*96)
  tmr_output_enable(TMR8, TRUE);
  tmr_output_default_para_init(&tmr_oc_init_structure);
  tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;  // 设置为 PWM 模式 A
  tmr_oc_init_structure.oc_idle_state = FALSE;                    // PWM 模式下,空闲状态输出低电平
  tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;     // 输出极性为高电平有效
  tmr_oc_init_structure.oc_output_state = TRUE;                     // 输出状态使能
  // 配置 TMR8 的第四个通道,设置捕获比较寄存器(CCR)的值和输出比较模式
  tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_4, &tmr_oc_init_structure);
  tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_4, 500);
  
  /* tmr enable counter */// 启动 TMR8 计数器
  tmr_counter_enable(TMR8, FALSE);
}

呼吸灯例程

#include "Breath.h"
#define LED_PIN GPIO_PINS_13
#define LED_GPIO_PORT GPIOD
  uint16_t period = 1000; // 定时器周期
 uint8_t pwm_duty = 0; // PWM占空比
 uint8_t pwm_direction = 1; // 0表示减小,1表示增大

////// 定时器中断服务例程
void TMR3_GLOBAL_IRQHandler(void)
{
    // 检查更新中断标志
    if(tmr_flag_get(TMR3, TMR_OVF_FLAG) != RESET)
    {
        tmr_flag_clear(TMR3, TMR_OVF_FLAG); // 清除更新标志
        pwm_duty += pwm_direction; // 调整占空比
                                printf("pwm_duty=%d\r\n",pwm_duty);
        if(pwm_duty >=100) // 达到最大占空比
        {
            pwm_duty = 100;
            pwm_direction = -1; // 改变方向
        }
        else if(pwm_duty <= 0) // 达到最小占空比
        {
            pwm_duty = 0;
            pwm_direction = 1; // 改变方向
        }

        // 更新PWM占空比
        
        tmr_channel_value_set(TMR4, TMR_SELECT_CHANNEL_2,  (uint16_t)(period * pwm_duty / 100.0f));
    }
}

// 初始化呼吸灯 ///PD13是灯的,想pwm控制灯电平,需要找到对应的pwm通道 这个是 定时器4的通道2 在寄存器手册查找,同时不要忘记复用
void breathing_led_init(void)
{
    gpio_init_type gpio_init_struct;
    tmr_output_config_type tmr_oc_init_structure;
    TMR3INIT();
    // 启用GPIO和定时器时钟以及复用时钟
    crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR4_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
    // 配置LED引脚为复用功能
    gpio_default_para_init(&gpio_init_struct);
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pins = LED_PIN;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(LED_GPIO_PORT, &gpio_init_struct);
          /* GPIO PIN remap */                      //寄存器手册中PD13要复用才可以使用
     gpio_pin_remap_config(TMR4_MUX, TRUE); 
        
    // 配置定时器TMR4
    tmr_base_init(TMR4, 1000, 240); // 预分频为240,周期也就是重装在职1000。重装载计数值1000。频率240MHZ/(1000*240)
    tmr_cnt_dir_set(TMR4, TMR_COUNT_UP); // 向上计数
    tmr_clock_source_div_set(TMR4, TMR_CLOCK_DIV1);
    tmr_period_buffer_enable(TMR4, TRUE); 
    //tmr_output_enable(TMR4, TRUE);//高级定时器有的         
     /* configure primary mode settings */
  tmr_sub_sync_mode_set(TMR4, FALSE);
  tmr_primary_mode_select(TMR4, TMR_PRIMARY_SEL_RESET);

    // 配置PWM输出 channel 2 output settings      
    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A; // PWM模式A
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; // 高电平有效
    tmr_oc_init_structure.oc_output_state = TRUE; // 使能输出
    tmr_output_channel_config(TMR4, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR4, TMR_SELECT_CHANNEL_2,  50);     //设置初始值比较值CCR,CCR<重装载值输出高电平,相反输出低电平
    tmr_output_channel_buffer_enable(TMR4, TMR_SELECT_CHANNEL_2, TRUE);
    // 启用PWM输出和定时器
    
    tmr_counter_enable(TMR4, TRUE);

}

void TMR3INIT(void)
{
    crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE);
            //配置定时器TMR3
    tmr_base_init(TMR3, 1000, 2400); //  10ms,周期为1000
    tmr_cnt_dir_set(TMR3, TMR_COUNT_UP); // 向上计数
    tmr_clock_source_div_set(TMR3, TMR_CLOCK_DIV1);                                                     
    tmr_interrupt_enable(TMR3, TMR_OVF_INT, TRUE); // 启用更新中断
        
    tmr_counter_enable(TMR3, TRUE);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值