两颗LED分别是一颗红色和一颗蓝色,把两颗LED连在定时器通道1上,红色LED连接在通道1正常输出,蓝色LED连接在通道1互补输出;通过定时器1的通道1产生一组互补的PWM信号驱动这两颗LED,然后通过调节PWM的占空比让LED出现明暗变化,就会出现呼吸灯的效果
1.呼吸灯原理
如何实现呼吸灯的效果:要让LED连续变化,一会亮一会暗,这种情况跟正弦函数类似

配置定时器输出如右图的PWM波
配置参数:
占空比=0.5(sin(2πt)+1)
周期=1ms
2.初始化IO引|脚
定时器:TIM1
通道1
引脚:CH1、CH1N

需要先找到引脚位置



再初始化引脚


#include "stm32f10x.h"
void App_PWM_Init(void);
int main(void)
{
while(1)
{
}
}
void App_PWM_Init(void)
{
//#1.初始化IO引脚PA8 PB13
GPIO_InitTypeDef GPIO_InitStruct;
// PA8 AF_PP
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// PA13 AF_PP
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
3.配置时基单元




//#2.配置时基单元
//#2.1开启TIM1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE) ;
//#2.2配置时基单元的参数
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period=999;
TIM_TimeBaseInitStruct.TIM_Prescaler=71;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);
//#2.3 开启ARR寄存器预加载,防止定时器跑飞
TIM_ARRPreloadConfig(TIM1,ENABLE);
//#2.4 闭合时基单元的开关
TIM_Cmd (TIM1,ENABLE);
}
4.配置输出比较的参数


//#3.初始化输出比较
//#3.1初始化输出比较通道1的参数
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = 0;
TIM_OC1Init(TIM1,&TIM_OCInitStruct);
//#3.2闭合MOE总开关
TIM_CtrlPWMOutputs(TIM1,ENABLE);
5.改变PWM占空比

实现呼吸灯的效果要让PWM占空比按正弦的关系去变化,t代表单片机里的当前时间
a.获取单片机里的当前时间:GetTick获取的是毫秒值,所以小换算成秒

b.声明一个变量(duty)存放占空比值,由于用了sin函数所以要引用math.h头文件
while(1)
{
float t=GetTick() *1.0e-3f;
float duty = 0.5* (sin(2*3.14*t) + 1);
}
c.再计算CCR1的值
CCR1的值决定高电压所占用的时间=1000μs*占空比=0.5 (sin(2πt) + 1)*1000
uint16_t ccrl = duty * 1000;
d.把ccr1的值设置到寄存器里

TIM_SetCompare1(TIM1, ccrl);
总代码:
#include "stm32f10x.h"
#include "delay.h"
#include "math.h"
void App_PWM_Init(void);
int main(void)
{
App_PWM_Init();
while(1)
{
float t=GetTick() *1.0e-3f;
float duty = 0.5* (sin(2*3.14*t) + 1);
uint16_t ccrl = duty * 1000;
TIM_SetCompare1(TIM1, ccrl);
}
}
void App_PWM_Init(void)
{
//#1.初始化IO引脚PA8 PB13
GPIO_InitTypeDef GPIO_InitStruct;
// PA8 AF_PP
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// PA13 AF_PP
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//#2.配置时基单元
//#2.1开启TIM1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE) ;
//#2.2配置时基单元的参数
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period=999;
TIM_TimeBaseInitStruct.TIM_Prescaler=71;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);
//#2.3 开启ARR寄存器预加载,防止定时器跑飞
TIM_ARRPreloadConfig(TIM1,ENABLE);
//#2.4 闭合时基单元的开关
TIM_Cmd (TIM1,ENABLE);
//#3.初始化输出比较
//#3.1初始化输出比较通道1的参数
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = 0;
TIM_OC1Init(TIM1,&TIM_OCInitStruct);
//#3.2闭合MOE总开关
TIM_CtrlPWMOutputs(TIM1,ENABLE);
//#使能CCR1预加载功能
TIM_CCPreloadControl(TIM1,ENABLE);
}
1071

被折叠的 条评论
为什么被折叠?



