一、定时器
实验内容:使用STM32F103的 Tim2~Tim5其一定时器的某一个通道pin(与GPIOx管脚复用,见下图),连接一个LED,用定时器计数方式,控制LED以2s的频率周期性地亮-灭
1、STM32cubeMX配置
创建好芯片项目(stm32f103C8T6)后选择SYS,Debug改为Serial Wire
再打开RCC
然后将你所要做闪烁灯的端口初始化,然后点击TIM2修改Clock Source,我的设定值和学长博客一样,可以参考,然后修改clk
最后生成项目文件,注意要点击GENERATE CODE
2、keil代码
所需加入的定时器中断具体代码如下:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static unsigned char ledState = 0;
if (htim == (&htim2))
{
if (ledState == 0)
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
ledState = !ledState;
}
}
然后进行烧录效果。
二、PWM呼吸灯
实验内容:采用定时器PWM模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒,自己调整占空比变化到一个满意效果;使用Keil虚拟示波器,观察 PWM输出波形。
1、TM32cubeMX配置
前面配置步骤是不变的,但是需要改变PSC和Counter Period,改变步骤如下:
在 Parameter Settings 页配置预分频系数为 71,计数周期(自动加载值)为 499,定时器溢出频率,即PWM的周期,就是 72MHz/(71+1)/(499+1) = 2kHz
PWM频率:
Fpwm =Tclk / ((arr+1)*(psc+1))(单位:Hz)
arr 是计数器值
psc 是预分频值
占空比:
duty circle = TIM3->CCR1 / arr(单位:%)
TIM3->CCR1 用户设定值
比如 定时器频率Tclk = 72Mhz arr=499 psc=71 那么PWM频率就是720000/500/72= 2000Hz,即2KHz
arr=499,TIM3->CCR1=250 则pwm的占空比为50%
改CCR1可以修改占空比,修改arr可以修改频率
2、kei代码
keil参考代码如下:
#include "stm32f10x.h"
#define LED_PIN GPIO_Pin_8 //假设LED连接到GPIO Port C的Pin 8
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = LED_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //选择复用推挽输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void TIM3_PWM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 1000; //设置计数周期为1000,1秒
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; //设置预分频系数为72,得到计数频率为1MHz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//配置定时器3为PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 500; //初始占空比为50%
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_Cmd(TIM3, ENABLE);
}
int main(void)
{
LED_Init();
TIM3_PWM_Init();
while(1)
{
for(int i = 0; i <= 500; i += 10) //逐渐增加占空比
{
TIM_SetCompare1(TIM3, i); //设置PWM脉冲宽度
for(int j = 0; j < 10000; j++); //延时
}
for(int i = 500; i >= 0; i -= 10) //逐渐减小占空比
{
TIM_SetCompare1(TIM3, i); //设置PWM脉冲宽度
for(int j = 0; j < 10000; j++); //延时
}
}
}
根据代码可知输出端管脚,接上对应LED即可观察效果,最后我们进行烧录,即可观察呼吸灯效果。