一、PWM脉冲宽度调制
1、什么是PWM脉冲宽度调制
脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
脉冲宽度调制是一种模拟控制方式,其根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字信号对模拟电路进行控制的一种非常有效的技术。
2、基本原理
冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。PWM控制技术就是以该结论为理论基础,对半导体开关器件的导通和关断进行控制,使输出端得到一系列幅值相等而宽度不相等的脉冲,用这些脉冲来代替正弦波或其他所需要的波形。按一定的规则对各脉冲的宽度进行调制,既可改变逆变电路输出电压的大小,也可改变输出频率。
3、调制过程
脉冲宽度调制(PWM)是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。
要改变PWM输出波形的宽度,就要改变比较寄存器 CCRx 的值,想要输出不通宽度来拟合正弦波,则需要CCRx的值呈现如下图的变化趋势,即要生成一张CCRx的数值表,按周期变化将表中元素的值赋给CCRx。
二、stm32cubeMX配置
1、SYS配置
2、RCC配置
选择Clock configuration进行配置
3、TIMER3配置
时钟为internal clock,通道为PWM grenation CH4
parameter settings进行设置
GPIO设置
NVIC 设置
4、生成项目
三、函数配置
1、main.c头部添加PWM表`
TIM_HandleTypeDef htim3;
/* USER CODE BEGIN PV */
uint16_t indexWave[] = {
1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4,
4, 5, 5, 6, 7, 8, 9, 10, 11, 13,
15, 17, 19, 22, 25, 28, 32, 36,
41, 47, 53, 61, 69, 79, 89, 102,
116, 131, 149, 170, 193, 219, 250,
284, 323, 367, 417, 474, 539, 613,
697, 792, 901, 1024, 1024, 901, 792,
697, 613, 539, 474, 417, 367, 323,
284, 250, 219, 193, 170, 149, 131,
116, 102, 89, 79, 69, 61, 53, 47, 41,
36, 32, 28, 25, 22, 19, 17, 15, 13,
11, 10, 9, 8, 7, 6, 5, 5, 4, 4, 3, 3,
2, 2, 2, 2, 1, 1, 1, 1
};
uint16_t POINT_NUM = sizeof(indexWave)/sizeof(indexWave[0]);
/* USER CODE END PV */
2、stm32f1xx_it.c文件中声明`
/* External variables --------------------------------------------------------*/
extern TIM_HandleTypeDef htim3;
/* USER CODE BEGIN EV */
extern uint16_t indexWave[];
extern uint16_t POINT_NUM; /*PWM表中的点数*/
/* USER CODE END EV */
3、修改中断回调函数
在stm32f1xx_it.c最后添加
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static uint8_t pwm_index = 1; /* 用于PWM查表 */
static uint8_t period_cnt = 0; /* 用于计算周期数 */
period_cnt++;
/* 若输出的周期数大于20,输出下一种脉冲宽的PWM波 */
if(period_cnt >= 20)
{
/* 根据PWM表修改定时器的比较寄存器值 */
__HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_4, indexWave[pwm_index]);
/* 标志PWM表的下一个元素 */
pwm_index++;
/* 若PWM脉冲表已经输出完成一遍,重置PWM查表标志 */
if( pwm_index >= POINT_NUM)
{
pwm_index=0;
}
/* 重置周期计数标志 */
period_cnt=0;
}
}
4、添加定时启动函数
int main(void)
{
/* USER CODE BEGIN 1 */
/* 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_TIM3_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim3);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
四、结果
PWM呼吸灯
五、参考
https://blog.csdn.net/qq_36347513/article/details/113599959
六、总结
通过PWM脉冲调制的方式来实现呼吸灯,让我对PWM的工作方式有了一个深刻的了解,让我对stm32的功能多元性有了更进一步的了解,并通过整个实验过程,丰富了我的实验经历。