PWM部分可以参考这篇文章
呼吸灯
使用定时器输出PWM波形到LED灯的引脚,并改变占空比实现呼吸灯的效果。pwm.h
#ifndef __PWM_H
#define __PWM_H
#include "stm32f4xx.h"
void tim14_pwm_led0(uint16_t psc, uint32_t arr);
void PWM_SetCompare1(uint32_t Compare);
#endif
代码思路:
1.看原理图确定GPIO以及定时器OC引脚 PF9 TIM14_CH1
2.GPIO配置
复用模式 GPIO_PinAFConfig
3.定时器配置
向上计数模式
4.频道配置
a.申明结构体 TIM_OCInitTypeDef
b.结构体配置 模式、极性、输出使能
c.初始化(每个频道函数的下标不一样) TIM_OC1Init
5.定时器ARR寄存器与频道CCR寄存器使能
TIM_OC1PreloadConfig
TIM_ARRPreloadConfig
6.定时器使能
TIM_Cmd
7.修改占空比
调用TIM_SetCompare1
要点:
1.计数器为向上计数模式,递增计数
2.设置PWM1模式,CNT<CCR时为有效电平,结合递增计数模式,也就是前半段为有效电平
3.输出极性低,前半段为高电平
pwm.c
#include "pwm.h"
void tim14_pwm_led0(uint16_t psc, uint32_t arr)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//通电还是断电
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE); //时钟使能
GPIO_PinAFConfig(GPIOF, GPIO_PinSource9, GPIO_AF_TIM14); //复用为定时器14
//开始配置F端口下的9号跟10号引脚
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; //led0 led1
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF; //复用模式
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推挽输出
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉模式
GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed; //引脚响应速度
GPIO_Init(GPIOF, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseStructure.TIM_Prescaler = psc-1; //PSC值
TIM_TimeBaseStructure.TIM_Period = arr-1; //ARR值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM14, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //pwm模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性低
TIM_OC1Init(TIM14, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); //使能TIM14在OC1上的CCR预装载寄存器
TIM_ARRPreloadConfig(TIM14, ENABLE); //定时器14 ARR寄存器
TIM_Cmd(TIM14, ENABLE); //定时器使能
}
//封装TIM_SetCompare1 - 固定定时器TIM14 - 方便传参只传一个
void PWM_SetCompare1(uint32_t Compare)
{
TIM_SetCompare1(TIM14,Compare);
}
SysTick_Init();在上篇文章的delay.c给出了,这里就不展示出来了
main.c
PSC的值为84,ARR值为1000
#include "stm32f4xx.h"
#include "pwm.h"
#include "delay.h"
int main(void)
{
// usart1_init();
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// LED_Init();
SysTick_Init();
//f = 84Mhz/ (83+1) / (999+1) = 1Khz
//pwm频率 = 时钟频率/(分频值+1)/(自动重装载值+1)
tim14_pwm_led0(84, 1000);
uint32_t cmp;
u8 flag = 1;
u8 direction = 1;
//while(1)
//{
// delay_ms(1);
// if(flag == 1)
// cmp++;
// else
// cmp--;
//
// if(cmp>500)
// flag = 0;
//
// if(cmp == 0)
// flag = 1;
// PWM_SetCompare1(cmp);
//}
while (1)
{
if (direction)
{
for (cmp=0; cmp < 800; cmp += 1) // 渐亮
{
PWM_SetCompare1(cmp);
delay_ms(1); // 根据期望的渐变速度调整延时
}
direction = 0; // 切换方向
}
else
{
for (cmp=800; cmp > 0; cmp -= 1) // 渐暗
{
PWM_SetCompare1(cmp);
delay_ms(1); // 根据期望的渐变速度调整延时
}
direction = 1; // 切换方向
}
}
}