STM32F103RB通用定时器功能(二)输出比较产生PWM
实验功能:
用TIM3_CH3_CH4实现,占空比为CH3(25%) CH4(50%)的方波,
并使用软件仿真的方式进行验证本实验采用 TIM3的完全重映像,
查找数据手册可以知道对应引脚(完全重映像)
TIM3_CH3 | TIM3_CH4 |
---|---|
PC8 | PC9 |
这里注意对应使用TIM是否有重映像功能与芯片的引脚封装有关
配置TIM3 代码片如下(示例)
void TIM3_Config(uint16_t duty3,uint16_t duty4) //TIM3(完全重映射) CH3_PC8 CH3_PC9
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 999; //1KHz //自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = 0; //预分频系数
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //基本定时器配置
TIM_PrescalerConfig(TIM3,71, TIM_PSCReloadMode_Immediate); // TIM3 预分频值 预分频重载模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式,脉冲宽度调制模式2 //***********
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//使能比较输出功能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//设置比较输出有效电平 //***********
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//定时器的完全重映射(必须加)
TIM_OCInitStructure.TIM_Pulse = duty3;//占空比
TIM_OC3Init(TIM3, &TIM_OCInitStructure);//通道3
TIM_OCInitStructure.TIM_Pulse = duty4;//占空比
TIM_OC4Init(TIM3, &TIM_OCInitStructure);//通道4
TIM_Cmd(TIM3, ENABLE);//使能TIM2定时计数器
}
此两条语句中涉及到有电平效性
1.若使用
TIM_OCMode=TIM_OCMode_PWM1 使用 TIM_OCPolarity=TIM_OCPolarity_High (高电平有效)
TIM_OCMode=TIM_OCMode_PWM2 使用 TIM_OCPolarity=TIM_OCPolarity_Low (高电平有效)
颠倒其中任意一个都是低电平有效
这种写法正确
TIM_OCInitStructure.TIM_Pulse = duty3;//占空比
TIM_OC3Init(TIM3, &TIM_OCInitStructure);//通道3
TIM_OCInitStructure.TIM_Pulse = duty4;//占空比
TIM_OC4Init(TIM3, &TIM_OCInitStructure);//通道4
这种写法错误
TIM_OCInitStructure.TIM_Pulse = duty3;//占空比
TIM_OCInitStructure.TIM_Pulse = duty4;//占空比
TIM_OC3Init(TIM3, &TIM_OCInitStructure);//通道3
TIM_OC4Init(TIM3, &TIM_OCInitStructure);//通道4
配置GPIO 代码片如下(示例)
void PWM_TIM3_IO_(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时计器3的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //使能A端口,并开启AFIO时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; // CH2_PA1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置电气属性
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
使用TIM重映射
1.必须开启AFIO时钟
2.GPIO设置为复用推挽
3.添加选择映射方式(没有用到不添加)
GPIO_PinRemapConfig(GPIO_PartialRemap2_TIM3,ENABLE);//定时器3的部分重映射
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//定时器3的完全重映射
完整代码如下(示例)
#include "stdio.h"
#include "misc.h"
void PWM_TIM3_IO_(void);
void TIM3_Config(uint16_t duty3,uint16_t duty4);
unsigned char ucLed;
int main(void)
{
SysTick_Config(72000); // 定时1ms(HCLK = 72MHz)
PWM_TIM3_IO_();
TIM3_Config(999/4,999/2); //25% 50%
while(1)
{
}
}
/*
使用TIM重映射
1.必须开启AFIO时钟
2.GPIO设置为复用推挽
3.添加选择映射方式(没有用到不添加)
GPIO_PinRemapConfig(GPIO_PartialRemap2_TIM3,ENABLE);//定时器3的部分重映射
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//定时器3的完全重映射
*/
/*
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
注:此两条语句中涉及到有电平效性
1.若使用
TIM_OCMode=TIM_OCMode_PWM1 使用 TIM_OCPolarity=TIM_OCPolarity_High (高电平有效)
TIM_OCMode=TIM_OCMode_PWM2 使用 TIM_OCPolarity=TIM_OCPolarity_Low (高电平有效)
颠倒其中任意一个都是低电平有效
*/
//通用定时器无互补输出功能
void TIM3_Config(uint16_t duty3,uint16_t duty4) //TIM3(完全重映射) CH3_PC8 CH3_PC9
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 999; //1KHz //自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = 0; //预分频系数
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //基本定时器配置
TIM_PrescalerConfig(TIM3,71, TIM_PSCReloadMode_Immediate); // TIM3 预分频值 预分频重载模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式,脉冲宽度调制模式2 //***********
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//使能比较输出功能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//设置比较输出有效电平 //***********
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//定时器的完全重映射(必须加)
TIM_OCInitStructure.TIM_Pulse = duty3;//占空比
TIM_OC3Init(TIM3, &TIM_OCInitStructure);//通道3
TIM_OCInitStructure.TIM_Pulse = duty4;//占空比
TIM_OC4Init(TIM3, &TIM_OCInitStructure);//通道4
TIM_Cmd(TIM3, ENABLE);//使能TIM2定时计数器
}
void PWM_TIM3_IO_(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时计器3的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //使能A端口,并开启AFIO时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; // CH2_PA1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置电气属性
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
//此函数必须有
void SysTick_Handler(void)
{
}
进行软件仿真验证
1)Debug内勾选Use simulator >ok
2)点击进行仿真
3)点击setup输入PORTC.8 / PORTC.9 并设置Display Typ为:Bit
4)全速运行即可得到方波
总结:本实验主要掌握通用定时器的PWM比较输出,
完整工程下载>>GitHub
选择第2个工程