基于stm32的pwm调节占空比实验HAL库方式实现

基于stm32的pwm调节占空比实验HAL库方式实现

本文目标:基于stm32的pwm调节占空比实验HAL库方式实现

按照本文的描述,应该可以跑通实验并举一反三。

先决条件:装有编译和集成的开发环境,比如:Keil uVision5、STM32CubeMX

使用外设:TIM、GPIO

前言

这篇文章是自己捣鼓一个rgb灯时需要实现亮度调节,于是根据自己所拥有的硬件平台进行验证一下,顺便给一些初学者一些启发。

实验目的

基于stm32的pwm调节占空比实验HAL库方式实现,使用两个按键实现灯的亮度实验。在本实验过程中,我们将涉及 STM32 的 GPIO 端口配置、TIM等。

学习了前面几篇博客的基础上,我们可以实现完成这个实验。

基于stm32的time定时器HAL库编程_独处东汉的博客-CSDN博客

基于HAL库的stm32呼吸灯实验_基于stm32的呼吸灯设计_独处东汉的博客-CSDN博客

基于stm32的gpio实验HAL库方式实现_独处东汉的博客-CSDN博客

关于实验原理图

在这里插入图片描述

在这里插入图片描述

根据我这里的硬件原理图,想要驱动LED_R亮,那么mcu的PB0低电平可以亮,给高电平灯灭。我们想实现变亮度需要是利用定时器的TIM外设,可以看到我这里的原理图设计在TIM3_CH3上,于是我们这里可以利用TIM3来实现灯的亮度调节,按键这里的原理图解析则是常态下都是高电平,按下按键则可以读取到低电平。基于这个原理图,准备好一个工程模板。

搭建工程

使用STM32CubeMX配置stm32的基本配置。基本的配置如下:开启swd调试,开启外部时钟。

在这里插入图片描述

在这里插入图片描述

  • 配置TIM3

在这里插入图片描述

这个CH有效电平按照我的理解,就我的这个场景中,期望的有效电平是低电平,所以笔者这里设置成了低电平。

  • 配置按键gpio

在这里插入图片描述

  • 时钟界面选项卡:

在这里插入图片描述

  • 工程选项卡:

在这里插入图片描述

在这里插入图片描述

点击右上角的的生成代码:

在这里插入图片描述

使用keil打开工程,编译工程,一切都是ok

在这里插入图片描述

编写代码实现需求

我们使用场景是使用两个按键实现加减灯的亮度,按下KEY1按键亮度增加,按下KEY2的按键亮度减少。接下来创建两个文件,led_pwm.c和led_pwm.h简单粗暴的写一些代码,实现我们亮度调节的逻辑,其中led_pwm.c的代码如下:

#include "led_pwm.h"
#include "stm32f1xx_ll_tim.h"
#include "key.h"

LED led_pwm = {0};

float aDutyCycle[TIM_DUTYCYCLE_NB] = {
	0.0,   /*   0% */
	0.1,   /*  10% */
	0.2,   /*  20% */
	0.3,   /*  30% */
	0.4,   /*  40% */
	0.5,   /*  50% */
	0.6,   /*  60% */
	0.7,   /*  70% */
	0.8,   /*  80% */
	0.9,   /*  90% */
	1.0,   /*  100% */
};

/*********************************************************************************
 * 函数名  :led_pwm_test
 * 描述    :pwm灯测试一下
**********************************************************************************/
void led_pwm_test(void)
{
		static uint8_t iDutyCycle = 0;
		iDutyCycle = (iDutyCycle + 1) % TIM_DUTYCYCLE_NB;

		/* Set  duty cycle */
		LL_TIM_OC_SetCompareCH3(TIM3, (LL_TIM_GetAutoReload(TIM3) * aDutyCycle[iDutyCycle]));	
}

/*********************************************************************************
 * 函数名  :led_pwm_init
 * 描述    :灯初始化
**********************************************************************************/
void led_pwm_init(void)
{
	led_pwm.dutycycle = 5;
	// 直接设置50%的占空比
	LL_TIM_OC_SetCompareCH3(TIM3, (LL_TIM_GetAutoReload(TIM3) * aDutyCycle[led_pwm.dutycycle]));	
	HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
}



/*********************************************************************************
 * 函数名  :led_pwm_add
 * 描述    :灯亮度加
**********************************************************************************/
void led_pwm_add(void)
{
	if(key_even_flag == 1)
	{
		led_pwm.dutycycle++;
		if(led_pwm.dutycycle >= TIM_DUTYCYCLE_NB-1) led_pwm.dutycycle = TIM_DUTYCYCLE_NB-1;
		LL_TIM_OC_SetCompareCH3(TIM3, (LL_TIM_GetAutoReload(TIM3) * aDutyCycle[led_pwm.dutycycle]));		
		key_even_flag = 0;
	}
}

/*********************************************************************************
 * 函数名  :led_pwm_sub
 * 描述    :灯亮度减
**********************************************************************************/
void led_pwm_sub(void)
{
	if(key_even_flag == 2)
	{
		led_pwm.dutycycle--;
		if(led_pwm.dutycycle <= 0)  led_pwm.dutycycle = 0;
		LL_TIM_OC_SetCompareCH3(TIM3, (LL_TIM_GetAutoReload(TIM3) * aDutyCycle[led_pwm.dutycycle]));		
		key_even_flag = 0;
	}
}


/*********************************************************************************
 * 函数名  :led_pwm_poll
 * 描述    :灯轮询
**********************************************************************************/
void led_pwm_poll(void)
{
	key_poll(); // 按键轮询
	led_pwm_add();
	led_pwm_sub();
}


其中这个LL_TIM_OC_SetCompareCH3(TIM3, (LL_TIM_GetAutoReload(TIM3) * aDutyCycle[led_pwm.dutycycle]));这个函数是在#include "stm32f1xx_ll_tim.h"中找到了,需要把对应的头文件包含进来。
在这里插入图片描述

是哪个定时器就修改对应的定时器,这个函数其实是设置定时器的CCR比较值的。比如你的板子对应的硬件定时器是TIM1的通道4,就要设置成LL_TIM_OC_SetCompareCH4(TIM1, (LL_TIM_GetAutoReload(TIM1) * aDutyCycle[iDutyCycle])); 使用时需要根据对应的硬件进行适配。

led_pwm.h的内容如下:

#ifndef __LED_PWM_H__
#define __LED_PWM_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "key.h"


#define TIM_DUTYCYCLE_NB   11


typedef struct LED{
	int8_t  dutycycle;   // 占空比档位
}LED;

extern LED led_pwm;

void led_pwm_init(void);
void led_pwm_add(void);
void led_pwm_sub(void); 
void led_pwm_poll(void);

#ifdef __cplusplus
}
#endif

#endif /* __SIGHTING_H__ */



在main函数中简单进行测试一下

  /* USER CODE BEGIN 2 */
	led_pwm_init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		led_pwm_poll();
  }

main.c中的编写的代码片段

在这里插入图片描述

接下来简单的对工程配置一下

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

实验现象

在这里插入图片描述

可以观察到,当我按下板子的KEY1时,灯的亮度在增加,每次增加10%的亮度,当我按下板子的KEY2时,灯的亮度在减小,每次减少10%,表明此次实验成功,使用简单直观的代码可以实现我们的小需求。

本文中使用的测试工程

https://download.csdn.net/download/weixin_44317448/88222802

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独处东汉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值