Всем привет, продолжаем дальше на практике изучать ARM. Сегодня на повестки дня широтно-импульсная модуляция.
Широтно-импульсная модуляция (ШИМ, pulse-width modulation (PWM)) — управление средним значением напряжения на нагрузке путём изменения скважности импульсов, управляющих ключом. Различают аналоговую ШИМ и цифровую ШИМ, двоичную (двухуровневую) ШИМ и троичную (трёхуровневую) ШИМ.
PWM реализуется на таймере, каждый таймер поддерживает специальный режим генерации ШИМ-сигналов. В этом режиме период ШИМ задается с помощью регистра автоматической перезагрузки таймера. Значение заполнения импульсов задается через регистр захвата/сравнения канала. Таким образом, каждый таймер может генерировать до четырех независимых ШИМ-сигналов. В каждом канале можно генерировать ШИМ-сигнал с выравниванием по фронту или по центру. В режиме с выравниванием по фронту, падающий фронт импульса всегда совпадает с моментом перезагрузки таймера. Изменение значения в регистре захвата/сравнения позволяет легко управлять моментом возникновения нарастающего фронта ШИМ-сигнала. В режиме с выравниванием по центру, таймер конфигурируется как реверсивный счетчик, который сначала считает в прямом направлении, а затем – в обратном. Когда будет выявлено совпадение счетчика с регистром захвата/сравнения канала, инвертируется состояние выходного сигнала канала.
Задача следующего рода, менять яркость свечения светодиодов. Имеем STM32F401C-DISCO, на ней 4 светодиода, порты которые идут к ним, могут работать в ШИМ режиме, мы их с Вами заюзаем, и у нас получиться небольшая светодиодная гирлянда.
Программа для PWM->LED
#include "stm32f4xx_hal.h" #include <stdint.h> #include <math.h> TIM_HandleTypeDef htim4; TIM_OC_InitTypeDef sConfigOC1; TIM_OC_InitTypeDef sConfigOC2; TIM_OC_InitTypeDef sConfigOC3; TIM_OC_InitTypeDef sConfigOC4; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM4_Init(void); int main(void) { volatile int i = 0; volatile int j = 0; SystemClock_Config(); HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0); HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); MX_GPIO_Init(); MX_TIM4_Init(); HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2); HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3); HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4); while (1) { for(i = 0; i <= 65353 ; i++){ TIM4->CCR1 = i; TIM4->CCR2 = i; TIM4->CCR3 = i; TIM4->CCR4 = i; for(j = 0 ; j < 100; j++) __NOP(); } for(i = 65535; i >= 0 ; i--){ TIM4->CCR1 = i; TIM4->CCR2 = i; TIM4->CCR3 = i; TIM4->CCR4 = i; for(j = 0 ; j < 100; j++) __NOP(); } } }
Конфигурация ШИМ
void MX_TIM4_Init(void) { TIM_MasterConfigTypeDef sMasterConfig; htim4.Instance = TIM4; htim4.Init.Prescaler = 0; htim4.Init.CounterMode = TIM_COUNTERMODE_UP; htim4.Init.Period = 65535; htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim4.Init.RepetitionCounter = 0; HAL_TIM_PWM_Init(&htim4); sConfigOC1.OCMode = TIM_OCMODE_PWM1; sConfigOC1.Pulse = 0; sConfigOC1.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC1.OCFastMode = TIM_OCFAST_ENABLE; HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC1, TIM_CHANNEL_1); sConfigOC2.OCMode = TIM_OCMODE_PWM1; sConfigOC2.Pulse = 0; sConfigOC2.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC2.OCFastMode = TIM_OCFAST_ENABLE; HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC2, TIM_CHANNEL_2); sConfigOC3.OCMode = TIM_OCMODE_PWM1; sConfigOC3.Pulse = 0; sConfigOC3.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC3.OCFastMode = TIM_OCFAST_ENABLE; HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC3, TIM_CHANNEL_3); sConfigOC4.OCMode = TIM_OCMODE_PWM1; sConfigOC4.Pulse = 0; sConfigOC4.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC4.OCFastMode = TIM_OCFAST_ENABLE; HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC4, TIM_CHANNEL_4); sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE; HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig); }
На сегодня все! Всем пока, если есть вопросы, пишите, всегда отвечу! 🙂
One thought on “Старт ARM. Широтно-импульсная модуляция на STM32F4.”
Если уже идти по пути HAL то нужно писать:
htim4.Instance->CCR1
Comments are closed.