【STM32】【STM32CubeMX】STM32CubeMX的使用之六:定时器配置输出PWM,实现变色呼吸灯

it2025-07-22  13

文章目录

0、前言1、硬件设计2、CubeMX配置3、软件设计


  下载工程文件:   https://gitee.com/Joseph_Cooper/stm32-cube-mx-stm32-l151-c8-t6   MCU:STM32L151C8T6-A   IDE:MDK-Keil5   固件库:STM32Cube FW_L1 V1.10.1



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。

最新回复(0)