GD32F103VET将TIMER0_CH3映射到PE14引脚,使其输出PWM波形。测试时,使用示波器看PE14引脚输出的波形,效果更直观。
TIMER0之PWM输出引脚映射如下:
TIMER0_REMAP[1:0]="00"(没有映射):
TIMER0_CH0默认被映射到PA8引脚
TIMER0_CH1默认被映射到PA9引脚
TIMER0_CH2默认被映射到PA10引脚
TIMER0_CH3默认被映射到PA11引脚
TIMER0_REMAP[1:0]="01"(部分映射):
TIMER0_CH0被映射到PA8引脚
TIMER0_CH1被映射到PA9引脚
TIMER0_CH2被映射到PA10引脚
TIMER0_CH3被映射到PA11引脚
TIMER0_REMAP[1:0]="11"(全映射):
TIMER0_CH0被映射到PE9引脚
TIMER0_CH1被映射到PE11引脚
TIMER0_CH2被映射到PE13引脚
TIMER0_CH3被映射到PE14引脚
测试程序如下:
#include "PWM0.h"
/*
PWM输出引脚映射如下:
TIMER0_REMAP[1:0]="00"(没有映射):
TIMER0_CH0默认被映射到PA8引脚
TIMER0_CH1默认被映射到PA9引脚
TIMER0_CH2默认被映射到PA10引脚
TIMER0_CH3默认被映射到PA11引脚
rcu_periph_clock_enable(RCU_GPIOA);//使能TIMER0_CH0引脚的外设时钟
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
TIMER0_REMAP[1:0]="01"(部分映射):
TIMER0_CH0被映射到PA8引脚
TIMER0_CH1被映射到PA9引脚
TIMER0_CH2被映射到PA10引脚
TIMER0_CH3被映射到PA11引脚
rcu_periph_clock_enable(RCU_AF); //使能映射功能的时钟
gpio_pin_remap_config(GPIO_TIMER0_PARTIAL_REMAP, ENABLE);//设置为部分映射
rcu_periph_clock_enable(RCU_GPIOA);//使能TIMER0_CH0引脚的外设时钟
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
TIMER0_REMAP[1:0]="11"(全映射):
TIMER0_CH0被映射到PE9引脚
TIMER0_CH1被映射到PE11引脚
TIMER0_CH2被映射到PE13引脚
TIMER0_CH3被映射到PE14引脚
rcu_periph_clock_enable(RCU_AF); //使能映射功能的时钟
gpio_pin_remap_config(GPIO_TIMER0_FULL_REMAP, ENABLE);
rcu_periph_clock_enable(RCU_GPIOE);//使能GPIOE端口的外设时钟
gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_14);
*/
void PWM0_Interrupt_Initializtion(uint16_t arr,uint16_t psc);
//函数功能:PWM0初始化,将PE14用作TIMER0_CH3引脚,输出PWM波形
//arr:自动重装值。
//psc:时钟预分频数
//PWM0_Interrupt_Initializtion(TIMER0,50000,1080);//当arr=50000,psc=1080时,则为500ms,误差为10us;
void PWM0_Interrupt_Initializtion(uint16_t arr,uint16_t psc)
{
timer_parameter_struct TimerParameterStruct;
timer_oc_parameter_struct Timer_OC_ParameterStruct;
/初始化TIMER0_CH3引脚开始
rcu_periph_clock_enable(RCU_AF); //使能映射功能的时钟
gpio_pin_remap_config(GPIO_TIMER0_FULL_REMAP, ENABLE);
//TIMER0_REMAP[1:0]="11"(全映射),将TIMER0_CH3映射到PE4引脚
//TIMER0_REMAP[1:0]="01"(部分映射),将TIMER0_CH3映射到PA11引脚
//TIMER0_REMAP[1:0]="00"(没有映射),默认将TIMER0_CH3映射到PA11引脚
rcu_periph_clock_enable(RCU_GPIOE);//使能GPIOE端口的外设时钟
gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_14);
//配置GPIOE14的工作模式为复用功能IO推挽输出和输出速度最大为50MHz
//将PE14用作TIMER0_CH3引脚,输出PWM波形
/初始化TIMER0_CH3引脚结束
/初始化TIMER0计数器开始
rcu_periph_clock_enable(RCU_TIMER0); //使能TIMER0的APB2外设时钟
//nvic_irq_enable(TIMER0_UP_IRQn, 2U, 0U); //设置TIMER0_UP_IRQn的中断优先级,抢占优先级为2,子优先级为0
timer_deinit(TIMER0); //复位TIMERx
TimerParameterStruct.period = arr-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TimerParameterStruct.prescaler = psc-1; //设置用来作为TIMx时钟频率除数的预分频值(APB2时钟分频值)
TimerParameterStruct.clockdivision = TIMER_CKDIV_DIV1; //设置时钟分母值为1
//计算公式:arr*psc/108000000/1,当arr=250,psc=108时,则为0.25ms,误差为1us;
TimerParameterStruct.counterdirection = TIMER_COUNTER_UP; //设置计数方向为"向上计数"
TimerParameterStruct.alignedmode = TIMER_COUNTER_EDGE; //设置为无中央对齐计数模式(边沿对齐模式)
TimerParameterStruct.repetitioncounter = 0; //设置"重复计数次数"为0
timer_init(TIMER0,&TimerParameterStruct);//根据TimerParameterStruct所指向的参数初始化TIMERx的时间基数单位
timer_counter_value_config(TIMER0,0);//设置TIMERx的计数器初始值为0
//timer_counter_read(TIMER0);//读取TIMERx的计数器值
/初始化TIMER0计数器结束
/初始化PWM0在TIMER0_CH3引脚输出电平的极性开始
Timer_OC_ParameterStruct.outputstate = TIMER_CCX_ENABLE; //"通道引脚输出"使能
Timer_OC_ParameterStruct.ocidlestate = TIMER_OC_IDLE_STATE_LOW; //通道引脚空闲时输出为低电平
Timer_OC_ParameterStruct.ocpolarity = TIMER_OC_POLARITY_HIGH; //通道引脚输出极性为高电平
Timer_OC_ParameterStruct.outputnstate = TIMER_CCXN_DISABLE; //"互补通道引脚输出"不使能
Timer_OC_ParameterStruct.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;//互补通道引脚空闲时输出为高电平
Timer_OC_ParameterStruct.ocnpolarity = TIMER_OCN_POLARITY_HIGH; //互补通道引脚输出极性为高电平
timer_channel_output_config(TIMER0,TIMER_CH_3,&Timer_OC_ParameterStruct);
//根据Timer_OC_ParameterStruct所指定的参数初始化TIMER0通道0
timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_3,250);
//设置初始占空比为250/500
timer_channel_output_mode_config(TIMER0,TIMER_CH_3,TIMER_OC_MODE_PWM0);
//设置通道输出比较模式:PWM0模式
//在向上计数时,一旦计数器值小于TIMERx_CH0CV时,O0CPRE为高电平,否则为低电平,这里是向上计数;
//在向下计数时,一旦计数器的值大于TIMERx_CH0CV时,O0CPRE为低电平,否则为高电平;
timer_channel_output_shadow_config(TIMER0,TIMER_CH_3,TIMER_OC_SHADOW_DISABLE);
//禁止"通道0输出/比较影子寄存器"
timer_primary_output_config(TIMER0,ENABLE);//使能TIMER0输出比较功能
/初始化PWM0在TIMER0_CH3引脚输出电平的极性结束
timer_auto_reload_shadow_enable(TIMER0);//使能TIMERx自动重装载
/*
timer_flag_clear(TIMER0,TIMER_FLAG_UP); //清除"TIMERx更新标志位"
timer_interrupt_flag_clear(TIMER0,TIMER_INT_FLAG_UP); //清除"TIMERx更新中断标志位"
timer_interrupt_enable(TIMER0,TIMER_INT_UP); //使能"TIMERx更新"产生中断
timer_internal_clock_config(TIMER0);//设置"内部时钟"作为定时器时钟
//timer_slave_mode_select(TIMER0,TIMER_SLAVE_MODE_DISABLE);
//设置"关闭从模式",如果TIMER计数器使能,则预分频器直接由内部时钟驱动
*/
timer_enable(TIMER0);//TIMERx计数器使能,开始工作
}
#include "LED.h"
void LED_Init(void);
//函数功能:初始化MCU_Led
void LED_Init(void)
{
rcu_periph_clock_enable(RCU_GPIOD);//使能GPIOD时钟,enable GPIO clock
gpio_init(GPIOD, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
//将GPIOD15设置为输出上拉
MCU_Led_Off();
// GPIO_BC(GPIOD) = GPIO_PIN_15;//清除GPIOD15输出,GPIO bit clear register
}
#ifndef __LED_H
#define __LED_H
#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#define MCU_Led_Off() GPIO_BOP(GPIOD)=GPIO_PIN_15 //GD15输出高电平
#define MCU_Led_On() GPIO_BC(GPIOD)=GPIO_PIN_15 //GD15输出低电平
#define MCU_Led_Toggle() gpio_bit_write( GPIOD,GPIO_PIN_15,(bit_status)((1-gpio_input_bit_get(GPIOD,GPIO_PIN_15))) )
//GD15取反输出电平
extern void LED_Init(void);
#endif
main.c程序如下:
#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "delay.h"
#include "LED.h"
#include "PWM0.h"
int main(void)
{
int16_t i = 0;
FlagStatus breathe_flag = SET;
//NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)
//NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)
//NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)
//NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)
//NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)
nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"
INTX_ENABLE();//开启所有中断
LED_Init();//初始化MCU_Led
delay_init();//系统时钟配置
PWM0_Interrupt_Initializtion(50000,1080);
//PWM0初始化,将PE14用作TIMER0_CH3引脚,输出PWM波形
//设置PWM0周期为500ms,误差为10us;
while(1)
{
delay_ms(40);
if (SET == breathe_flag)
{
i = i + 10;
}
else
{
i = i - 10;
}
if(i>500)
{
breathe_flag = RESET;
}
if(i<=0)
{
breathe_flag = SET;
}
timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_3,i);
//每隔40ms,修改TIMER0_CH0引脚输出占空比为i/500
MCU_Led_Toggle();
}
}