实现学习任务一:STM32WBA55 PWM控制LED灯亮度。
编程工程:keil5.38a,STM32cube MX 6.13(低版本没有本次活动的芯片)
测试定时器脉宽输出工具:RIGOL-DS1022C ,由于本次使用的LED3(红色),红色比较亮,使用示波器可直接看到占空比的变化。
PWM知识的介绍:PWM(Pulse Width Modulation 脉宽调制)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。它是一种对模拟信号电平进行数字编码的方法。是指在一定时间内波形的高电平(即 1 状态)所占用的时间比例。通过高分辨率计数器的使用,方波占空比被调制用来对一个模拟信号的电平进行编码。PWM 信号任然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有,要么完全无。比如我们的电压输出是 5V的,那么经过改变 PWM 的占空比,可以达到在一定时间内输出 3.3V 或者 1.3V 的效果。
PWM是脉冲宽度调制,具有两个非常重要的参数:频率和占空比。
频率:PWM的频率是整个周期的倒数。
占空比:占空比是指一个周期内高电平所占的比例。
STM32 CUBE的软件配置,参考图纸可以看到,板载在的LED灯是PB8引脚,然后我们看到可以查看到该引脚,可以配置成定时器1 、定时器3或者低功耗定时器1的PWM输出引脚,这里我们使用定时器1作为该引脚的PWM输出功能。
如下图所示:设置PWM的基本配置信息,并且使能定时器输出功能。
这里配置的一下,系统的时钟:
这里简单分享一下:输出频率的计算方法:
默认使用的主频为16Mhz,配置定时器的分频系数为15 ;则输出PWM的计算结果为:16Mhz/(15+1) /(1999+1) =500HZ
三:软件编写步骤如下:
使能定时器1和相关IO口时钟。
使能定时器1时钟:__HAL_RCC_TIM1_CLK_ENABLE();
使能GPIOB时钟:__HAL_RCC_GPIOB_CLK_ENABLE();
初始化IO口为复用功能输出。
HAL_TIM_MspPostInit
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
这里我们是要把PB8用作定时器的PWM输出引脚,所以要重映射配置,
所以需要开启AFIO时钟。同时设置重映射。
初始化定时器:Prescaler,Period等:MX_TIM1_Init();
使能定时器,设置PWM开始输出功能
调用函数如下:
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
修改脉冲宽度的方法:不断改变比较值CCRx,达到不同的占空比效果
主要代码如下:
static void MX_TIM1_Init(void) { /* USER CODE BEGIN TIM1_Init 0 */ /* USER CODE END TIM1_Init 0 */ TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; /* USER CODE BEGIN TIM1_Init 1 */ /* USER CODE END TIM1_Init 1 */ htim1.Instance = TIM1; htim1.Init.Prescaler = 15; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 2000; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; sBreakDeadTimeConfig.DeadTime = 0; sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; sBreakDeadTimeConfig.BreakFilter = 0; sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT; sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE; sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH; sBreakDeadTimeConfig.Break2Filter = 0; sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT; sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM1_Init 2 */ HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1); /* USER CODE END TIM1_Init 2 */ HAL_TIM_MspPostInit(&htim1); }
由于STM32cube软件,在生成工具的时候,默认定时器的输出功能是关闭的,所以在用户区代码中,我们需要手动开启PWM的输出功能,或者是在进入主程序之前开启PWM功能,
增加的代码如下所示:
/* USER CODE BEGIN TIM1_Init 2 */ HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1); /* USER CODE END TIM1_Init 2 */
在该工程下,添加修改脉宽的程序代码如下所示:
/* USER CODE BEGIN 4 */ void UpdataDutyData(int value) { TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim1.Instance = TIM1; htim1.Init.Prescaler = 15; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 1999; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_OC_Init(&htim1) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 1999 * value/100 ; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1); }
实物测试图片如下所示:
基本任务一:已完成,只是使用板载的LED完成,后期制作小夜灯时,使用购买的物料制作。
程序代码如下所示: