STM32F10X PWM输出小教程

前言(可绕开):
        今天大年初二,还是来温习下PWM输出的知识,献此教程给有所有初学者。

PWM输出,可以用来做很多事情,呼吸灯,蜂鸣器,当然了最主要的还是 电机和舵机 控制了,主要通过的方式,就是改变占空比,当然就就可以模拟电压了!  学好这个,你就迈进了控制机器的门!!!

这里我用的开发板时正点原子的MiniSTM32,芯片型号为STM32F103RCT6.   This is easy, so you can do that very easily!

[objc] view plain copy
  1. ***REMENBER STM32 is you! :)  
我们在这里进行通俗的讲解,详细的内容,可以在以后再去看STM32手册。

接下来,还是一块一块代码进行分析,将其中的重点进行说明:


void pwm_Config(u16 period, u16 psc){

    GPIO_InitTypeDef GPIO_InitStructure;
	  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	  TIM_OCInitTypeDef TIM_OCInitStructure;
	
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

这里我们定义函数, 这里不用使用AFIO模式,我们使用TIM1, PA8-通道1 ,PA11-通道4。 stm32f103的TIM的定时器一共有8个
其中可以输出和捕获的PWM的只有TIM1,TIM8高级定时器 ,  TIM2~TIM5普通定时器。 且能做到互补输出的只有高级定时器。
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	  GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	  GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_Mode,这里必须采用复用推挽输出 GPIO_Mode_AF_PP,不是复用推挽就需要打开AFIO复用模式,是在引脚复用时候需要打开!

	  TIM_TimeBaseStructure.TIM_Period = period-1;
	  TIM_TimeBaseStructure.TIM_Prescaler = psc-1;
	  TIM_TimeBaseStructure.TIM_ClockDivision= 0 ;
	  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	  TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
	
	  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
		TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
		TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
		TIM_OCInitStructure.TIM_Pulse = 0;

关键的地方到了! 一行一行来!
Peroid就是周期,PWM通俗讲是有规律的高低电平,比如低电平400,高电平600,那么总的周期就是1000,我们需要改变的占空比就是 低电平/周期   或者高电平/周期。 至于为什么要 -1 ,因为计数从0~9。

Prescaler就是预分频,我们用的 TIM1 是72MHz的,有些控制是要求频率限制的,我们计算时PWM频率是这样的:假如我们需要1KHz的频率,1000的周期,那么我们需要输入的参数为 周期:1000, 预分频:72, 你会发现 频率*周期*预分频 就是72MHz。 接下来有个通俗的讲解,分频后TIM频率就是 1000KHz ,就是每秒振动1000K下,振动1000下一个周期,其中一个周期振动400下为低电平,振动600下为高电平,换算成时间就是  高电平:400/1000K 就是0.4ms   低电平: 600/1000K 就是0.6ms   一个周期为1ms 。

为了配置上面的参数,就是后面的语句了:

TIM_ClockDivision为时钟分割,一般的我们都为0,TIM_CounterMode 这个计数模式影响到后面PWM模式,一般的我们采用向上计数模式TIM_CounterMode_Up

TIM_OCMode这里是非常讲究的:
PWM模式1- 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为
无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否
则为有效电平(OC1REF=1)。
PWM模式2- 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为
有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电
平。
我们这里采用的是PWM模式2,   TIMx_CCR1 为设置比较值,什么是有效电平呢?就是 TIM_OCPolarity_High这个表达的意思就是高电平为有效值,TIM_SetCompare1(TIM1,400);设置比较值得时候,意思为1000-400 =600 , 就是占空比为0.4,0.4个周期为低电平,0.6个周期为高电平。
TIM_OutputState设置输出使能。
TIM_Pulse这里设置一开始默认的比较值。
		TIM_OC1Init(TIM1,&TIM_OCInitStructure);
		TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
		
		TIM_OC4Init(TIM1,&TIM_OCInitStructure);
		TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);

这里我们使用TIM1  得通道1 和通道4 ,初始他们的结构体,然后最重要的的是,还要初始化重复装载,让周期重复进行。
		TIM_ARRPreloadConfig(TIM1,ENABLE);
		
     TIM_CtrlPWMOutputs(TIM1,ENABLE);
		
		TIM_Cmd(TIM1,ENABLE);
		
}
这里初始化 TM1得预装载,使能PWM输出,使能TIM1,这些都是常见得必须配置。

到这里整个初始化函数,就配置结束了,我们改变它得占空比,就可以通过

TIM_SetCompare1(TIM1,400);   //通道1的比较值

TIM_SetCompare4(TIM1,400);   //通道4的比较值

是不是很简单啊!说实话,如果你是单片机创建者,考虑这些参数配置,其实都是很有必要的。

祝大家学习愉快!如有错误,欢迎指正,共同进步! 希望今年参加的比赛都有好成绩!!

在这我又要为大家献上一首歌了,这首歌献给大一的我:格莱美-Stay with me-点击打开链接

悠扬的大提琴和合唱动人心弦,其实我曾经是一名艺术工作者。

猜你喜欢

转载自blog.csdn.net/qq_37389133/article/details/79331976