一、引言
介绍
定时器PWM(脉宽调制)是一种利用定时器来产生周期性信号的方法,通过调节信号的占空比(高电平时间占整个周期的比例)来控制电力传输或信号强度。这种技术广泛应用于LED调光、电机速度控制、音频信号生成等领域,通过改变占空比,可以实现对外设的精确控制和调节。
工作原理
使用定时器生成一个固定频率的方波信号,通过设置占空比来调节方波的高电平时间,从而控制输出信号的平均电压或功率。定时器周期性地计数,当计数达到设定的阈值时切换信号电平,通过动态调整该阈值,即占空比,实现对负载的调节,例如使LED亮度从暗到亮变化。
二、代码
1.main.c
先初始化PWM,配置定时器以PWM模式工作,设定频率和初始占空比,使能PWM输出
在主循环中,通过两个for循环来改变PWM信号的占空比(占空比是指一个PWM信号周期内高电平的持续时间与周期总时间的比例),第一个for循环逐渐减小占空比(LED低电平亮),第二个for循环逐渐增加占空比,实现了PWM占空比的线性减小和增加,从而控制LED的亮度在一个周期内从暗到亮,再从亮到暗,形成呼吸灯效果。
每次改变占空比后,再用延时函数延时10毫秒,使LED亮度变化平滑
#include "stm32f10x.h"
#include "Delay.h"
#include "tim.h"
uint8_t i;
int main(void)
{
PWM_Init();
while(1)
{
for(i = 0; i < 100; i++) // 逐渐减小PWM占空比
{
PWM_SetCompare1(100 - i); // 设置PWM通道1的占空比为100 - i
Delay_ms(10);
}
for(i = 0; i < 100; i++) // 逐渐增加PWM占空比
{
PWM_SetCompare1(i); // 设置PWM通道1的占空比为i
Delay_ms(10);
}
}
}
2.tim.c
PWM_Init
()用于初始化PWM模块,使其能够生成所需的PWM信号。具体内容为:先使能TIM1和GPIOA的时钟,配置GPIOA的引脚8(LED)为复用推挽输出模式,以便输出TIM1的PWM信号。然后初始化TIM1的定时器参数,包括时钟分频、计数模式、自动重载值和预分频器等。最后初始化TIM1的输出比较参数,包括PWM模式、输出使能、比较值和输出极性等。
PWM_SetCompare1
()用于设置PWM的占空比,通过调用 TIM_SetCompare1(TIM1, compare)
,将比较值设置为指定的占空比,从而控制PWM信号的高电平持续时间,进而影响LED的亮度。
具体请见代码旁的注释
#include "stm32f10x.h"
#include "tim.h"
void PWM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM1_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM1_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// 时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 初始化定时器参数
TIM1_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟划分
TIM1_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数器模式向上计数
TIM1_TimeBaseInitStructure.TIM_Period = 100 - 1; // 自动重载值
TIM1_TimeBaseInitStructure.TIM_Prescaler = 720 - 1; // 预分频器
TIM1_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseInitStructure); // 初始化TIM1定时器参数
// 初始化定时器输出比较参数
TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 选择定时器模式:TIM脉冲宽度调制模式1
TIM1_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 比较输出使能
TIM1_OCInitStructure.TIM_Pulse = 0; // 设置待装入捕获比较寄存器的脉冲值
TIM1_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性:TIM输出比较极性高
TIM_OC1Init(TIM1, &TIM1_OCInitStructure); // 根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_CtrlPWMOutputs(TIM1, ENABLE); // MOE 主输出使能
TIM_Cmd(TIM1, ENABLE); // 使能TIM1
}
void PWM_SetCompare1(uint16_t compare)
{
TIM_SetCompare1(TIM1, compare); // 设置TIM1的比较值,控制PWM的占空比
}
3.tim.h
头文件
#ifndef __TIM_H
#define __TIM_H
#include "stdint.h"
void PWM_Init(void);
void PWM_SetCompare1(uint16_t compare);
#endif
4.其他
LED代码不用改,跟之前一样
三、实验结果
作业六
四、总结
改老师的代码灯一直亮不会呼吸,所以学习参考了网上的代码
本次作业让我更好地了解了PWM,锻炼了我的动手实践能力,拓展了专业知识,令我受益匪浅