【嵌入式-定时器】通过呼吸灯案例使用逻辑分析仪分析PWM波形

本文详细描述了如何在STM32F10x平台上使用C语言实现PWM波形,通过TIM2定时器控制GPIO输出,驱动LED呼吸灯进行0-100%的占空比变化,展示了完整的代码和逻辑分析结果。
摘要由CSDN通过智能技术生成

目的:通过实现呼吸灯分析PWM波形

代码:

PWM.c

#include "stm32f10x.h"                  // Device header

/**
  * @brief	PWM初始化
  * @param	无
  * @retval	无
*/
void PWM_Init(void)
{
	// 使能IO和TIM2
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 初始化GPIOA
	GPIO_InitTypeDef GPIO_InitStructure;
	// 必须使用GPIO_Mode_AF_PP, 使用片上外设的输出替代输出数据寄存器的输出. 因此使用复用推挽输出代替普通推挽输出
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 初始化时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;		// ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;	// PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	// 初始化输出比较寄存器
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCStructInit(&TIM_OCInitStructure);
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0;
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);
	
	// 运行控制
	TIM_Cmd(TIM2, ENABLE);
}

/**
  * @brief	设置脉冲宽度. 占空比=Compare1/TIM_TimeBaseInitStructure.TIM_Period
  * @param	
  * @retval	
*/
void PWM_SetCompare1(uint16_t Compare1)
{
	TIM_SetCompare1(TIM2, Compare1);
}

main.c

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Delay.h"
#include "PWM.h"

uint16_t Compare1;

int main(void)
{
	OLED_Init();
	PWM_Init();
	
	while(1)
	{
		PWM_SetCompare1(Compare1);
		if(Compare1 >= 100)
		{
			Compare1 = 0;
		}
		Compare1 += 20;
		Delay_ms(10);
	}
}

逻辑分析仪结果

在这里插入图片描述
可以看到呼吸灯的占空比从20%到100%,且周期T=1ms。
下面用C1代表Compare1,CCR代表捕获/比较寄存器值,下图是使用代码逻辑分析的各变量值及变化关系

C1	CCR		C1		占空比	持续时间
0	0		20		0%		10ms
20	20		40		20%		10ms
40	40		60		40%		10ms
60	60		80		60%		10ms
80	80		100		80%		10ms
100	100		0		100%	10ms
0	0		20		0%		10ms
...

分析

在这里插入图片描述

这里设置了ARR自动重装寄存器值为100,预分频系数为720,即由TIMx定时器输出的频率f=72MHz/100/720=1000Hz,因此周期T=1/f=1ms。所以我们看到的每个周期都是t(高电平)+t(低电平)=1ms。
占空比=t(高电平)/T,这里TIMx定时器使用上升沿模式,计数器值从0到ARR后重装载再次变为0,那么这个ARR值相当于周期(的缩放),那么占空比=TIM_Pulse/TIM_Period 。TIM_Period =100。

main.c中,Compare1 从0递增到100再次变为0,也就是,CCR的值从0递增到100再次变为0,通过控制这个CCR实现对有效电平和无效电平控制。我认为这个电平应该是从最开始的无效电平开始的,但是我采集出来的是20%占空比开始的,因此尝试复位后,终于看到完整波形如下。
在这里插入图片描述

main.c呼吸灯代码如下. 分析同上.

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Delay.h"
#include "PWM.h"

uint8_t i;

int main(void)
{
	OLED_Init();
	PWM_Init();
	
	
	while(1)
	{
		for(i = 0; i<=100; i++)
		{
			PWM_SetCompare1(i);
			Delay_ms(10);
		}
		
		for(i = 0; i<=100; i++)
		{
			PWM_SetCompare1(100 - i);
			Delay_ms(10);
		}
	}
}

参考:

PWM驱动LED呼吸灯、舵机、直流电机

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值