之前按照《梁山Pi开发板学习指南》去配置PWM输出,发现不能配置TIMER3的PWM输出,查找了一堆的资料,终于让TIMER3的PWM跑起来了。流泪
话不多说,上代码
/*
使用TIME3的PB6 7 8 9 作为PWM输出
PB6 - TIME3_CH0
PB7 - TIME3_CH1
PB8 - TIME3_CH2
PB9 - TIME3_CH3
*/
void TIM3_PWM_Init_AllChannel(void)
{
/* 关闭定时器3 */
timer_deinit(TIMER3);
/* 开启对应引脚时钟 */
rcu_periph_clock_enable(RCU_GPIOB);
/* 开启定时器3时钟 */
rcu_periph_clock_enable(RCU_TIMER3);
/* 配置定时器时钟 CK_TIMERx = 4 x CK_APB1 = 4x50M = 200MHZ */
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
/* 设置引脚模式为复用浮空输出 */
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
/* 设置复用线为2,具体见数据手册47页 */
gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_6);
gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_7);
gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_8);
gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_9);
/* 定时器初始化参数结构体定义 */
timer_parameter_struct timer_initpara;
/* 计算公式:周期 T=(prescaler+1)*(period+1)/200000000 频率 f = 1/T */
timer_initpara.prescaler = 2000-1;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE; //触发方式设置根据边沿决定
timer_initpara.counterdirection = TIMER_COUNTER_UP; //设置为上升沿触发
timer_initpara.period = 2000-1; //设置周期20ms
timer_initpara.repetitioncounter = 0;
timer_init(TIMER3, &timer_initpara); //定时器3更新配置
/* 定时器PWM初始化参数结构体定义 */
timer_oc_parameter_struct timer_ocintpara;
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; //通道输出极性为高电平有效
timer_ocintpara.outputstate = TIMER_CCX_ENABLE; //使能 PWM 输出到端口
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; //通道互补输出极性为高电平
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; //通道互补输出状态失能
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; //信道输出的空闲状态为低
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; //信道互补输出的空闲状态为低
/* 将修改的内容设置定时器3的通道0 通道1 通道2 通道3 */
timer_channel_output_config(TIMER3,TIMER_CH_0,&timer_ocintpara);
timer_channel_output_config(TIMER3,TIMER_CH_1,&timer_ocintpara);
timer_channel_output_config(TIMER3,TIMER_CH_2,&timer_ocintpara);
timer_channel_output_config(TIMER3,TIMER_CH_3,&timer_ocintpara);
/*设置定时器3通道0输出占空比为50%,输入值 = period * (想要输出的占空比)= 2000 * 0.5 = 1000*/
timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_0, 1000);
timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_1, 200);
timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_2, 500);
timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_3, 1500);
/* 设置定时器3所有通道的输出模式为PWM0模式 */
timer_channel_output_mode_config(TIMER3, TIMER_CH_0, TIMER_OC_MODE_PWM0);
timer_channel_output_mode_config(TIMER3, TIMER_CH_1, TIMER_OC_MODE_PWM0);
timer_channel_output_mode_config(TIMER3, TIMER_CH_2, TIMER_OC_MODE_PWM0);
timer_channel_output_mode_config(TIMER3, TIMER_CH_3, TIMER_OC_MODE_PWM0);
/* 设置定时器3所有通道禁止输出比较影子寄存器 */
timer_channel_output_shadow_config(TIMER3, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
timer_channel_output_shadow_config(TIMER3, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);
timer_channel_output_shadow_config(TIMER3, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE);
timer_channel_output_shadow_config(TIMER3, TIMER_CH_3, TIMER_OC_SHADOW_DISABLE);
/* 使能TIMERx_CAR寄存器的影子寄存器 */
timer_auto_reload_shadow_enable(TIMER3);
/* 所有通道输出使能 */
timer_primary_output_config(TIMER3, ENABLE);
/* 使能定时器3 */
timer_enable(TIMER3);
/* 外设TIMER3中断使能 更新中断 */
timer_interrupt_enable(TIMER3,TIMER_INT_UP);
}
具体复用线是多少,复用其他功能应该怎么看,见数据手册的47页上下,这里只截图了该代码使用的引脚复用线
后面想要修改占空比的值,只要调用timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_0, 1000);这个函数进行修改就行(里面的参数根据你的情况来改,我这里懒的改了)。当然你要开启了这个通道的PWM输出功能才有用哦。
主函数
#include "gd32f4xx.h"
#include "systick.h"
#include "usart0.h"
#include "pwm.h"
int main(void)
{
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 优先级分组
systick_config(); //系统滴答定时器 定时1MS
USART1_Init();
TIM3_PWM_Init_AllChannel();
while(1)
{
}
}
输出结果
定时器3通道0--PB6:输出50%占空比 频率50Hz 周期20ms
定时器3通道1--PB7:输出10%占空比 频率50Hz 周期20ms
定时器3通道2--PB8:输出25%占空比 频率50Hz 周期20ms
定时器3通道3--PB9:输出75%占空比 频率50Hz 周期20ms
玩过舵机的应该有发现了,我在搞舵机的PWM周期(狗头)
下一个功能见