Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Кармин Новиелло - Освоение STM32.pdf
Скачиваний:
2743
Добавлен:
23.09.2021
Размер:
47.68 Mб
Скачать

Таймеры

340

Period (которое соответствует регистру автоперезагрузки (ARR)) каждые 1 мс. Это означает, что менее чем за 1 с светодиод становится полностью ярким. Второй цикл аналогичным образом уменьшает поле Pulse, пока оно не достигнет нуля.

Частота обновления таймера установлена на 84МГц34/(499+1)(999+1)=168Гц. Такую же частоту можно получить, установив Prescaler в 249, а Period в 1999. Однако эффект плавного мерцания меняется. Почему так происходит? Если вы не можете объяснить различие, я настоятельно рекомендую сделать перерыв перед тем, как продолжать, и провести эксперименты самостоятельно.

11.3.7.1. Генерация синусоидального сигнала при помощи ШИМ

Выходной прямоугольный сигнал, сгенерированный с помощью метода ШИМ, может быть отфильтрован для генерации сглаженного сигнала, который является аналоговым сигналом, имеющим пониженную двойную амплитуду напряжения или, как говорят,

размах напряжения (peak-to-peak voltage, Vpp). RC-фильтр нижних частот (см. рисунок

24) способен срезать все эти переменные сигналы, имеющие частоту выше заданного порогового значения. Общее правило низкочастотных RC-фильтров заключается в том, что чем ниже частота среза (cut-off frequency), тем ниже Vpp35. В низкочастотном RCфильтре используется важная характеристика конденсаторов: способность блокировать постоянные токи при одновременном пропускании переменных: учитывая постоянную времени R/C, образованную цепочкой резистор-конденсатор, фильтр закорачивает на землю переменные сигналы с частотой выше, чем постоянная RC-цепочки, позволяющая пропускать постоянную составляющую сигнала и более низкую частоту переменного напряжения.

Рисунок 24: Типовой фильтр нижних частот, реализованный с резистором и конденсатором

Хотя эта схема очень проста, выбор подходящих значений для R (сопротивления) и C (емкости) включает в себя некоторые конструктивные решения: какую пульсацию мы можем допустить и как быстро должен реагировать фильтр. Эти два параметра являются взаимоисключающими. В большинстве фильтров мы хотели бы иметь идеальный фильтр, который пропускал бы все частоты ниже частоты среза, без пульсации напряжения. К сожалению, такого идеального фильтра не существует: чтобы уменьшить пульсацию до нуля, мы должны выбрать очень большой фильтр, что приведет к тому, что будет затрачиваться много времени, прежде чем выходной сигнал станет стабильным. Хотя это может быть приемлемым для постоянного и фиксированного напряжения, это

34Максимальная частота таймеров в микроконтроллере STM32F401RE при тактировании от шины APB1 составляет 84 МГц.

35При работе с фильтрами для сглаживания выходного сигнала удобнее учитывать влияние на выходное напряжение, чем отклик по частоте фильтра. Однако математический аппарат расчета передаточной функции фильтра выходит за рамки данной книги. Если интересно, этот онлайн-калькулятор (http://sim.okawa-

denshi.jp/en/PWMtool.php) позволяет оценить выходной сигнал Vpp с учетом VIN, частоты ШИМ и значений

R и C.

TВКЛ

Таймеры

341

оказывает серьезное влияние на качество выходного сигнала, если мы пытаемся генерировать сложную форму сигнала из ШИМ-сигнала.

Частота среза fc RC-фильтра нижних частот первого порядка выражается формулой:

f

=

1

 

c

 

2 RC

 

 

[9]

На рисунке 25 показано влияние фильтра нижних частот на ШИМ-сигнал с частотой 100 Гц. Здесь мы выбрали резистор 1 кОм и конденсатор 10 мкФ. Это означает, что частота среза равна:

f

=

 

1

 

15.9

Гц

 

3

 

−5

c

 

2 10

10

 

 

 

 

 

 

 

 

Рисунок 25: Влияние фильтра нижних частот с частотой среза, равной 15,9 Гц

На рисунке 26 показано влияние фильтра нижних частот с резистором 4300 кОм и конденсатором 10 мкФ. Это означает, что частота среза равна:

f

=

1

 

 

 

3.7 Гц

 

 

 

 

c

 

2 (4.3 10

3

) 10

−5

 

 

 

 

 

 

Рисунок 26: Влияние фильтра нижних частот с частотой среза, равной 3,7 Гц

Как видите, второй фильтр позволяет получить значение Vpp, равное примерно 160 мВ, которое является колебанием напряжения, применимым для многих приложений.

Изменяя выходное напряжение (которое подразумевает, что мы меняем коэффициент заполнения), мы можем генерировать произвольный выходной сигнал, частоту которого составляет часть периода ШИМ. Основная идея здесь состоит в том, чтобы разделить желаемую форму сигнала, например, синусоидальную, на количество «x» делений. На каждое деление у нас имеется один цикл ШИМ. Время (то есть коэффициент

заполнения) напрямую соответствует амплитуде сигнала на этом делении, которая рассчитывается с использованием функции sin().

Таймеры

342

Рисунок 27: Как синусоида может быть аппроксимирована несколькими сигналами ШИМ

Рассмотрим диаграмму, показанную на рисунке 27. Здесь синусоида была разделена на 10 делений. Поэтому здесь нам потребуется 10 различных импульсов ШИМ, увеличивающихся/уменьшающихся синусоидальным образом. Импульс ШИМ с коэффициентом заполнения 0% будет представлять минимальную амплитуду (0 В), импульс с коэффициентом заполнения 100% будет представлять максимальную амплитуду (3,3 В). Поскольку выходной импульс ШИМ имеет перепад напряжения от 0 до 3,3 В, наша синусоида также будет колебаться от 0 до 3,3 В.

Для завершения одного цикла синусоиды требуется 360 градусов. Следовательно, для 10 делений нам нужно будет увеличивать угол с шагом 36 градусов. Это называется угловой скоростью шага (Angle Step Rate, ASR) или угловым разрешением (Angle Resolution). Мы мо-

жем увеличить количество делений, чтобы получить более точную форму сигнала. Но по мере увеличения деления нам также необходимо увеличивать разрешение, что означает, что мы должны увеличить частоту таймера, используемого для генерации сигнала ШИМ (чем быстрее работает таймер, тем меньше период).

Обычно 200 делений являются хорошим приближением для выходного сигнала. Это означает, что, если мы хотим генерировать синусоидальный сигнал 50 Гц, нам нужно запустить таймер на частоте 50 Гц * 200 = 10 кГц. Период импульса будет равен 200 (шагов

– это означает, что мы изменяем выходное напряжение на 3,3 В / 200 = 0,016 В), и поэтому значение Prescaler будет (при условии, что микроконтроллер STM32F030 работает на частоте 48 МГц) :

Prescaler =

48 МГц

 

= 24

50 Гц 200

 

200

 

делений

Pulse

 

 

 

В следующем примере показано, как генерировать чистый синусоидальный сигнал 50 Гц в микроконтроллере STM32F030, работающем на частоте 48 МГц.

 

Имя файла: src/main-ex9.c

 

 

 

14

#define PI

3.14159

15

#define ASR

1.8 //360 / 200 = 1.8

16

 

 

17int main(void) {

18uint16_t IV[200];

19float angle;

20

21 HAL_Init();

22

Таймеры

343

23Nucleo_BSP_Init();

24MX_TIM3_Init();

26for (uint8_t i = 0; i < 200; i++) {

27angle = ASR*(float)i;

28IV[i] = (uint16_t) rint(100 + 99*sinf(angle*(PI/180)));

29

}

30

 

31

HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1, (uint32_t *)IV, 200);

32

 

33while (1);

34}

35

36/* Функция инициализации TIM3 */

37void MX_TIM3_Init(void) {

38TIM_OC_InitTypeDef sConfigOC;

40htim3.Instance = TIM3;

41htim3.Init.Prescaler = 23;

42htim3.Init.CounterMode = TIM_COUNTERMODE_UP;

43htim3.Init.Period = 199;

44htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4;

45

HAL_TIM_PWM_Init(&htim3);

46

 

47sConfigOC.OCMode = TIM_OCMODE_PWM1;

48sConfigOC.Pulse = 0;

49sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

50sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

51HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);

53hdma_tim3_ch1_trig.Instance = DMA1_Channel4;

54hdma_tim3_ch1_trig.Init.Direction = DMA_MEMORY_TO_PERIPH;

55hdma_tim3_ch1_trig.Init.PeriphInc = DMA_PINC_DISABLE;

56hdma_tim3_ch1_trig.Init.MemInc = DMA_MINC_ENABLE;

57hdma_tim3_ch1_trig.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;

58hdma_tim3_ch1_trig.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

59hdma_tim3_ch1_trig.Init.Mode = DMA_CIRCULAR;

60hdma_tim3_ch1_trig.Init.Priority = DMA_PRIORITY_LOW;

61 HAL_DMA_Init(&hdma_tim3_ch1_trig); 62

63/* Несколько указателей дескриптора DMA периферии указывают на один

64и тот же дескриптор DMA.

65Имейте в виду, что существует только один канал для выполнения всех запросов к DMA. */

66__HAL_LINKDMA(&htim3, hdma[TIM_DMA_ID_CC1], hdma_tim3_ch1_trig);

67__HAL_LINKDMA(&htim3, hdma[TIM_DMA_ID_TRIGGER], hdma_tim3_ch1_trig);

68}

Наиболее значимая часть представлена в строках [26:29]. Эти строки кода используются для генерации вектора инициализации (Initialization Vector, IV), то есть вектора, содержащего значения Pulse, используемые для генерации синусоидального сигнала (который

Таймеры

344

соответствует уровням выходного напряжения). Функция Си sinf() возвращает синус заданного угла, выраженный в радианах. Поэтому нам нужно преобразовать угловые выражения в градусах в радианы по формуле:

Радианы = 180 Градусы

Однако в нашем случае мы разделили цикл синусоидального сигнала на 200 шагов (то есть мы разделили окружность на 200 шагов), поэтому нам нужно вычислить значение в радианах для каждого шага. Но так как синус дает отрицательные значения для угла между 180° и 360° (см. рисунок 28), мы должны масштабировать его, так как выходные значения ШИМ не могут быть отрицательными.

Рисунок 28: Значения, принятые синусоидальной функцией между 180° и 360°

Как только сгенерирован вектор IV, мы можем запустить ШИМ в режиме DMA. DMA1_Channel4 сконфигурирован для работы в циклическом режиме, поэтому он автоматически устанавливает значение регистра TIMx_CCRx в соответствии со значениями Pulse, содержащимися в IV. Использование таймера в режиме DMA – лучший способ для генерации произвольной функции без задержки и влияния на ядро Cortex-M. Тем не менее, часто векторы IV внутри программы жестко закодированы с использованием массивов с модификатором const, автоматически сохраняемых во Flash-памяти. Вы можете найти несколько онлайн-инструментов для этого, например, представленный здесь36.

Рисунок 29: Как таймеры позволяют аппроксимировать синусоидальный сигнал частотой 50 Гц с использованием ШИМ

36 https://daycounter.com/Calculators/Sine-Generator-Calculator.phtml