【STM32】【STM32CubeMX】STM32CubeMX的使用之六:定时器配置输出PWM,实现变色呼吸灯
程序员文章站
2022-06-08 19:06:18
...
文章目录
下载工程文件:
https://gitee.com/Joseph_Cooper/stm32-cube-mx-stm32-l151-c8-t6
0、前言
有关STM32实现PWM的理论知识戳这里。
1、硬件设计
▲ 核心板上的RGB_LED原理图
查阅数据手册可知引脚对应的定时器通道:
▲ STM32L151手册截图
2、CubeMX配置
▲ CubeMX PWM配置图
时基设置,设置2ms
定时器溢出,即500Hz
的PWM
。
▲定时器时基设置
3、软件设计
在配置占空比参数之前需要先使能定时器的各个通道。
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
逻辑实现:main.c
...
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t ColorIndex = 1; //颜色索引
double Duty = 0; //待计算的占空比
double DutyTempR = 0; //占空比临时值R
double DutyTempG = 0; //占空比临时值G
double DutyTempB = 0; //占空比临时值B
double OperateTemp = 0; //计算产生的临时变量,用于使DutyTemp逼近Duty
//RGB数值列表
uint8_t ValR[] = {255, 255, 255, 0 , 0 , 0 , 255};
uint8_t ValG[] = {0 , 125, 255, 255, 255, 0 , 0 };
uint8_t ValB[] = {0 , 0 , 0 , 0 , 255, 255, 255};
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
Duty = 100 - ((ValR[0] / 255) * 100); //根据RGB数值计算出相应的占空比参数
DutyTempR = Duty;
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, DutyTempR*(2000-1)/100); //赋值
Duty = 100 - ((ValG[0] / 255) * 100); //根据RGB数值计算出相应的占空比参数
DutyTempG = Duty;
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, DutyTempG*(2000-1)/100); //赋值
Duty = 100 - ((ValB[0] / 255) * 100); //根据RGB数值计算出相应的占空比参数
DutyTempB = Duty;
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3, DutyTempB*(2000-1)/100); //赋值
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
//R
Duty = 100 - ((ValR[ColorIndex] / 255) * 100); //根据RGB数值计算出相应的占空比参数
OperateTemp = Duty - DutyTempR; //计算总差值
OperateTemp /= 15; //差值分10次补偿给DutyTemp
while (DutyTempR != Duty)
{
if (OperateTemp > 0 && DutyTempR > Duty) //解决因小数精度问题而无法满足循环解除条件的问题
break;
if (OperateTemp < 0 && DutyTempR < Duty) //解决因小数精度问题而无法满足循环解除条件的问题
break;
DutyTempR += OperateTemp; //差值补偿
if(DutyTempR > 100) //防溢出操作
DutyTempR = 100;
else if(DutyTempR < 0)
DutyTempR = 0;
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, DutyTempR*(2000-1)/100); //赋值
HAL_Delay(100); //延时100ms
}
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, DutyTempR*(2000-1)/100);//最终赋确定值,此时DutyTemp=Duty
//G
Duty = 100 - ((ValG[ColorIndex] / 255) * 100); //根据RGB数值计算出相应的占空比参数
OperateTemp = Duty - DutyTempG; //计算总差值
OperateTemp /= 15; //差值分10次补偿给DutyTemp
while (DutyTempG != Duty)
{
if (OperateTemp > 0 && DutyTempG > Duty) //解决因小数精度问题而无法满足循环解除条件的问题
break;
if (OperateTemp < 0 && DutyTempG < Duty) //解决因小数精度问题而无法满足循环解除条件的问题
break;
DutyTempG += OperateTemp; //差值补偿
if(DutyTempG > 100) //防溢出操作
DutyTempG = 100;
else if(DutyTempG < 0)
DutyTempG = 0;
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, DutyTempG*(2000-1)/100); //赋值
HAL_Delay(100); //延时100ms
}
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, DutyTempG*(2000-1)/100);//最终赋确定值,此时DutyTemp=Duty
//B
Duty = 100 - ((ValB[ColorIndex] / 255) * 100); //根据RGB数值计算出相应的占空比参数
OperateTemp = Duty - DutyTempB; //计算总差值
OperateTemp /= 15; //差值分10次补偿给DutyTemp
while (DutyTempB != Duty)
{
if (OperateTemp > 0 && DutyTempB > Duty) //解决因小数精度问题而无法满足循环解除条件的问题
break;
if (OperateTemp < 0 && DutyTempB < Duty) //解决因小数精度问题而无法满足循环解除条件的问题
break;
DutyTempB += OperateTemp; //差值补偿
if(DutyTempB > 100) //防溢出操作
DutyTempB = 100;
else if(DutyTempB < 0)
DutyTempB = 0;
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3, DutyTempB*(2000-1)/100); //赋值
HAL_Delay(100); //延时100ms
}
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3, DutyTempB*(2000-1)/100);//最终赋确定值,此时DutyTemp=Duty
HAL_Delay(1000);
if(ColorIndex < 6) //使颜色于红~紫轮流切换
ColorIndex += 1;
else
ColorIndex = 0;
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
...
本程序的逻辑部分移植于https://blog.csdn.net/weixin_43444989/article/details/107401333。