利用旋钮控制小灯亮度
1、初始化
该项目以复刻旋钮的项目为基础进行扩展,前置步骤请参考以下帖子:复刻江协旋钮控制模块
(1)PWM配置
- 将时钟按照如下方式重新配置
- 使能
TIM3
计时器
(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.h
和LED.c
- 在
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)主程序部分
(2)中断部分
graph TD;subgraph EXTI_line1Begin((触发中断)) ---> PendSource{判断触发来源是否为PinA}PendSource --> |是|PendFlag{判断当前是否空闲}PendSource --> |否|End[退出中断]PendFlag --> |否|EndPendFlag --> |是|Toggle[翻转标识位] ---> PendRound{判断是否转满一圈}PendRound --> |否|Operation[对相对位置进行操作]PendRound --> |是|Clear[清零相对位置]Clear ---> EndOperation ---> Endendsubgraph EXTI_line2Begin1((触发中断)) ---> PendSource1{判断触发来源是否为PinB}PendSource1 --> |是|PendFlag1{判断当前是否空闲}PendSource1 --> |否|End1[退出中断]PendFlag1 --> |否|End1PendFlag1 --> |是|Toggle1[翻转标识位] ---> PendRound1{判断是否转满一圈}PendRound1 --> |否|Operation1[对相对位置进行操作]PendRound1 --> |是|Clear1[清零相对位置]Clear1 ---> End1Operation1 ---> End1end
4、实验效果
- 顺时针转动,亮度增加
- 逆时针转动,亮度减小