第十八章 AT32F403A基于V2库 定时器输出移相pwm
目录
概述
硬件
TMR互联同步
软件
初始化
初始化代码
测试
概述
本文主要是使用AT32F403A开发板,基于V2库使用tmr的同步功能来实现定时器输出移相pwm的功能。
串口工具使用的Atlink-ez自带的串口功能。
工程建立、调试工具配置在前面章节有详细介绍。
硬件
硬件方面使用的是参考官方AT32F437 SURF板子而设计的一个AT32F403A开发板,板子上的芯片是AT32F403AVGT7的型号,开发板上面还板载了一个atlink-ez的仿真器,atlink-ez除了可以在线仿真和下载之外还有一个串口的功能,硬件上是通过跳线帽接到了MCU的串口1,pa9/10上面。
如下图是开发板pcb图,以及硬件资源。(左边上角的就是atlink-ez,用usb线接到pc即可):

如下是实物图:

本章是移相pwm输出的功能,TMR2-CH1(PA0), TMR3-CH1(PA6),示波器直接接到对应的排针上即可。
TMR互联同步
定时器之间支持互联同步,因此一个定时器的 TMR_CLK 可由另一个定时器输出信号 TRGOUT 提供。配 置 STIS[2:0]选择内部触发信号驱动计数器计数。

上图是主次定时器的内部触发连接图,可以根据需求使用对应的主次定时器,比如TMR2作为主定时器,TMR3作为次定时器,那么就需要选择IS1。
下图是主定时器可以输出到次定时器的信号:
其中CxORAM是通道x的中间信号。

下图是次定时器的工作模式:

所以在使用同步模式的时候可以根据需求去使用不同的搭配。
软件
初始化
本功能的主要思路就是使用主定时器输出两路pwm,并且pwm为PWM B模式、低极性输出,其中一路用来作为次定时器的触发源,用来触发的pwm对输出极性和输出不太注重,因为使用的是这个通道的中间信号作为触发,输不输出不影响;次定时器输出一路pwm,频率、占空比、PWM模式、输出极性都设置和主定时器的一样,次定时器的工作模式为触发模式,当有上升沿的时候,就开始工作,所以用来作为触发的pwm的占空比就是移相的大小。
软件上使用TMR2为主定时器,TMR2-CH1/CH2作为pwm输出,并且把CH2做为次定时器的输入信号;TMR3作为次定时器,TMR3-CH1作为输出pwm,这样TMR2-CH1和TMR3-CH1就是移相的两个pwm波。
TMR2-CH1(PA0), TMR3-CH1(PA6),先初始化这两个IO为复用推挽输出,然后设置TMR2/3的pwm输出,设置主定时器的输出信号,设置次定时器的输入关联,最后使能TMR2即可。
初始化代码
/**
*TMR pwm 移相
*主定时器:TMR2
*从定时器:TMR3
*phase:移相值
*div:定时器预分频系数
*pre:定时器重载值
*duty:通道数据寄存器值
*pwm周期:(pre/(240/div))us
*频率:1/(pre/(240/div))hz
*pwm占空比:duty/pre
*移相幅度:phase/pre
*/void pwm_phase_shift(u16 phase,u16 div,u32 pre,u32 duty)
{gpio_init_type gpio_init_struct = {0};tmr_output_config_type tmr_output_struct;tmr_reset(TMR2);tmr_reset(TMR3);/* enable gpioa/tmr2/tmr3 clock */crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); //开启gpioa时钟crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE); //开启tmr2时钟crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE); //开启tmr3时钟gpio_default_para_init(&gpio_init_struct);gpio_init_struct.gpio_pins = GPIO_PINS_0|GPIO_PINS_6 ; //PA0/6gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; //推挽输出gpio_init_struct.gpio_pull = GPIO_PULL_NONE; //无上下拉gpio_init_struct.gpio_mode = GPIO_MODE_MUX; //复用gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;gpio_init(GPIOA, &gpio_init_struct);tmr_base_init(TMR2, pre, div); // 240M/(0+1)/(23999+1)=10khztmr_cnt_dir_set(TMR2, TMR_COUNT_UP); //向上计数方式tmr_base_init(TMR3, pre, div); // 240M/(0+1)/(23999+1)=10khztmr_cnt_dir_set(TMR3, TMR_COUNT_UP); //向上计数方式/* channelx Configuration in output mode */tmr_output_default_para_init(&tmr_output_struct);tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B; //PWM B模式tmr_output_struct.oc_output_state = TRUE; //使能输出tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_LOW; //极性低/* timer2 channel 1 */tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_1, &tmr_output_struct); //TMR2-CH1 (PA0)tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_1, duty); //设置TMR2的通道1的数据寄存器的值(占空比)/* timer3 channel 1 */ tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_1, &tmr_output_struct); //TMR3-CH1 (PA6)tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_1, duty); //设置TMR3的通道1的数据寄存器的值(占空比)/* timer2 channel 2 */tmr_output_struct.oc_output_state = FALSE; //可输出也可不输出,因为是使用的中间信号.tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_2, &tmr_output_struct); //TMR2-CH2 tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_2, phase); //设置TMR2的通道2的数据寄存器的值(占空比)/* timer2 select enable signal to sub timer */tmr_primary_mode_select(TMR2, TMR_PRIMARY_SEL_C2ORAW); //设置TMR2为主模式,通道2中间信号作为次定时器的输入tmr_sub_sync_mode_set(TMR2, TRUE); //主次定时器高度同步/* sub mode selection: tmr3 */tmr_sub_mode_select(TMR3, TMR_SUB_TRIGGER_MODE); //设置TMR3为次定时器,设定为触发模式tmr_trigger_input_select(TMR3, TMR_SUB_INPUT_SEL_IS1); //设置主次定时器内部关联/* enable tmr2*/tmr_counter_enable(TMR2, TRUE); //使能主定时器}
测试
测试代码
设定输出10k hz,占空比 25%的pwm波形,移相幅度为周期的1/4,也就是和占空比一样。

测试结果:
捉到的波形和预期的一致。蓝色是PA0的输出,黄色是PA6的输出,频率和占空比一样,相差1/4周期的幅度。

最后
有问题的可以加QQ群技术交流,同时相关代码上传到QQ群中。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
