利用旋钮控制小灯亮度

利用旋钮控制

1、初始化

该项目以复刻旋钮的项目为基础进行扩展,前置步骤请参考以下帖子:复刻江协旋钮控制模块

(1)PWM配置

  • 将时钟按照如下方式重新配置
    img
  • 使能TIM3计时器
    img

(2)写入代码

  • 在主循环外启用计时器的PWM模式
	HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
  /* USER CODE END 2 */

2、写入代码

(1)OLED显示

  • 已知旋钮转动一圈会触发20次,所以在该项目中需要在转满一圈后清零相对位置
/**
  * @brief This function handles EXTI line1 interrupt.
  */
void EXTI1_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI1_IRQn 0 */
	if(__HAL_GPIO_EXTI_GET_FLAG(PinA_Pin)){
		if(Flag == false){
			FlagToggle();
            //判断是否转满一圈
			if(Counter >= 20)
				Counter = 0;
			Counter++;
		}		
	}
		
  /* USER CODE END EXTI1_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(PinA_Pin);
  /* USER CODE BEGIN EXTI1_IRQn 1 */

  /* USER CODE END EXTI1_IRQn 1 */
}

同理,在PinB的中断处理函数中也需加入是否转满的判断

/**
  * @brief This function handles EXTI line2 interrupt.
  */
void EXTI2_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI2_IRQn 0 */
	if(__HAL_GPIO_EXTI_GET_FLAG(PinB_Pin)){
		if(Flag == false){
			FlagToggle();
			if(-Counter >= 20)
				Counter = 0;
			Counter--;
		}		
	}
  /* USER CODE END EXTI2_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(PinB_Pin);
  /* USER CODE BEGIN EXTI2_IRQn 1 */

  /* USER CODE END EXTI2_IRQn 1 */
}

/* USER CODE BEGIN 1 */
int16_t GetCounter(){
	return Counter;
}
void FlagToggle(void){
	Flag = !Flag;
}
bool ReturnFlag(void){
	return Flag;
}

(2)PWM部分

  • 在项目放置头文件和源文件的地方分别加入LED.hLED.c
    img
  • LED.h内写入相应函数的声明
#ifndef __LED_H
#define __LED_H
void SetValue(int32_t Value);

#endif

  • 因为PWM的预装载值为20000,所以装载值计算按照如下公式:
    \(预装载值 \div 2 + 旋钮相对位置 \times 500\)
  • 因此,LED.c内部代码如下:
#include "tim.h"
#include "LED.h"
// 设置重装载值的函数
void SetValue(int32_t Value){
	__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (Value * 500 + 10000));
}
	

3、流程图

(1)主程序部分

img

(2)中断部分

  • EXTI Line1
    img
  • EXTI Line2
    img

4、实验效果

  • 顺时针转动,亮度增加
    img
  • 逆时针转动,亮度减小
    img
posted @ 2025-10-09 21:29  奶龙大王  阅读(21)  评论(0)    收藏  举报