#include"stm32f10x.h"
void pwm_init(void);
int main(void)
{
pwm_init();
return 0;
}
void pwm_init(void){
GPIO_InitTypeDef GPIO_InitStrue;
TIM_OCInitTypeDef TIM_OCInitStrue;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //使能TIM3和相关GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);// 使能GPIOB时钟,使能AFIO时钟(定时器3通道2需要重映射到BP5引脚)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_5; // TIM_CH2
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP; // 复用推挽
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz; //设置最大输出速度
GPIO_Init(GPIOB,&GPIO_InitStrue); //GPIO端口初始化设置
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//这里设置的是部分重映射,TIM3的CH2被分配了PB5引脚,不同程度的映射,引脚也会不同。具体可以看数据手册的定时器引脚复用功能。
TIM_TimeBaseInitStrue.TIM_Period=9000-1; //设置自动重装载值,这里减去1是从0开始也算一个值。
TIM_TimeBaseInitStrue.TIM_Prescaler=0; //预分频系数
TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up; //计数器向上溢出
TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1; //时钟的分频因子,起到了一点点的延时作用,一般设为TIM_CKD_DIV1
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue); //TIM3初始化设置(设置PWM的周期)
TIM_OCInitStrue.TIM_OCMode=TIM_OCMode_PWM2; // PWM模式2:CNT>CCR时输出有效
TIM_OCInitStrue.TIM_OCPolarity=TIM_OCPolarity_High; // 设置极性-有效为高电平
TIM_OCInitStrue.TIM_Pulse = 4500-1; //设置占空比为 4500/9000 = 50%
TIM_OCInitStrue.TIM_OutputState=TIM_OutputState_Enable;// 输出使能
//下面的函数都是OC2,代表着OC的第二个通道。以此类推有OCx.
TIM_OC2Init(TIM3,&TIM_OCInitStrue); //TIM3的通道2PWM 模式设置
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能预装载寄存器
TIM_Cmd(TIM3,ENABLE); //使能TIM3
}
PWM 的学习笔记:
1.在STM32中想要产生PWM波有两种形式,一种产生类似中断的程序,在中断里使IO翻转电平,这种方法缺点是中断里的代码会对产生高频信号的准确性产生影响。而除了TIM6与TIM7两个基本定时器,其他的
定时器都有PWM功能,只需多配置TIMCCRx,TIMCMRRx等关于TIM输出比较的寄存器即可。TIM的PWM功能是基于硬件的,在发生时无需CPU参与。
2.基本步骤为:1.先要配置IO口的复用功能,这是因为TIM的PWM输出没有专门的自己的IO口,所以得启动一些特定IO口的重映射也叫复用功能。
2.一个TIM有4个输出或者输入捕获通道,这些通道互相独立,各不影响。实际中在选择一个通道时要注意在编程时某些函数和变量也是有各个通道的,要加以区分。
3.关于时钟和占空比,在默认情况下,如果不对TIM的RCC进行分频,其为72Mhz,TIM-OCInit有一个Pulse变量是用来设置占空比的。具体作用原理有很多种,cnt计数器在达到Pulse变量的
值后有效值会变成无效值,无效值变为有效值,这里的无效有效其实就是1或0,对应关系也可以自己设置.