前言
今天我们来进行PWM的学习,今天使用到的是通用定时器TIM14 ,在此之前我们已经简单学习过定时器的使用了,这样配置起来就会比较简单。
一、定时器及PWM的概述
1.通用定时器
TIMx主要功能通用TIMx定时器功能包括: ● 16位向上、向下、向上/向下自动装载计数器 ● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值 ● 4个独立通道: ─ 输入捕获 ─ 输出比较 ─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出 ● 使用外部信号控制定时器和定时器互连的同步电路 ● 如下事件发生时产生中断/DMA: ─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─ 输入捕获 ─ 输出比较 ● 支持针对定位的增量(正交)编码器和霍尔传感器电路 ● 触发输入作为外部时钟或者按周期的电流管理
其中加粗部分是我们今天需要使用到的功能,今天只使用到1路pwm。
2.PWM
如图所示: 输出1个100Hz的脉冲,设置占空比为50的话,LED灯的亮度就是直接低电平点亮的一半,我们可以通过调整脉冲的占空比来调整LED灯的亮度,使LED灯逐渐变暗再逐渐变亮不断循环来实现呼吸灯的效果
二、配置步骤及代码实现
代码如下:
#include "stm32f4xx.h"
#include "sys.h"
static GPIO_InitTypeDef GPIO_InitStructure;
static TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
static TIM_OCInitTypeDef TIM_OCInitStructure;
void delay_ms(uint32_t n)
{
while(n--)
{
SysTick->CTRL = 0;
SysTick->LOAD = (168000)-1;
SysTick->VAL = 0;
SysTick->CTRL = 5;
while ((SysTick->CTRL & 0x00010000)==0);
}
SysTick->CTRL = 0;
}
void Tim14_init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 10000/100-1;
TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM14, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 80;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM14, &TIM_OCInitStructure);
TIM_Cmd(TIM14, ENABLE);
}
int main(void)
{
int16_t pwm_cmp=0;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_SetBits(GPIOF,GPIO_Pin_9);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource9, GPIO_AF_TIM14);
Tim14_init();
while(1)
{
for(pwm_cmp=0;pwm_cmp<=100;pwm_cmp++)
{
TIM_SetCompare1(TIM14,pwm_cmp);
delay_ms(20);
}
for(pwm_cmp=100;pwm_cmp>=0;pwm_cmp--)
{
TIM_SetCompare1(TIM14,pwm_cmp);
delay_ms(20);
}
}
}
总结
一点一点的积累知识,学的东西多了,慢慢的发现把所学的一个功能和另一个功能组合起来就会实现一中新的效果。
|