STM8 PWM модуляція

Трохи базису для тих хто як і  я не знав як це працює.

Що таке таймер

Це окремий лічильник в мікроконтроллері. Тактуватись може або якимось зовнішнім джерелом, або тіками самого мікроконтролеру (з переддільника частоти).

В STM8 є два 16-бітних таймери (TIM1/TIM2), та один 8-бітний (TIM4). Окрім того TIM1 та TIM2 ще мають окремі CAPCOM (capture-compare) канали, з допомгою яких можна конфігурувати окреми умови спрацювання таймеру. Наприклад можна задати на першому каналі PWM сигнал з заповненням 20%, на 2-ому 50% і на 3ому 90%. В TIM2 є 3 канали, а в TIM1 - чотири.

Піни на яких є PWM від TIM2

Пін Альтернативний Канал таймеру
PD4PC5TIM2_CH1
PD3-TIM2_CH2
PA3PD2TIM2_CH3

Переддільник частоти  (prescaler)

Переддільник частоти (англ. prescaler) це електронний лічильник, що використовується для зменшення електричного сигналу високої частоти до менших значень частоти за допомогою цілочисленного ділення. Переддільник бере за основу базову частоту таймеру (яка може бути тактовою частотою процесора) і ділить її на деяке значення перед тим як передати її таймеру, відповідно до того як сконфігуровані регістри переддільника. Значення переддільника, які можна конфігурувати можуть бути обмежені до деякого набору фіксованих значень (степенів двійки), або бути будь-яким цілим числом від 1 до 2^P, де P кількість біт переддільника. - wiki

Отже цей блок на вході отримує тіки з частотою процессору (fCPU) і далі може їх ділити на 1,2,4..32768 (від TIM2_PRESCALER_1 до TIM2_PRESCALER_32768).
Якщо в нас STM8 працює на частоті 16Мгц, то TIM2_PRESCALER_1 дасть тіж самі 16Мгц на таймері, TIM2_PRESCALER_2 - 8Мгц, і далі ви напевно вже здогадались.

Як працює таймер в PWM режимі

Таймер на кожний тік від прескалеру збільшує на одиницю значення лічильнику каналу. Для змін характеристик PWM в нас є декілька налаштувань:

ARR - auto reload register. Коли лічильник таймеру досягає значення регістру ARR + 1, то його буде скинуто в 0.

OCPOLARITY - задає що має бути на виході, коли значення лічильника таймера меньше аніж CCRx.  Може бути OCPOLARITY_HIGH - тоді на початку буде 1 або  OCPOLARITY_LOW - тоді буде 0 на початку відліку.

CCRx (Capture/Compare Register) - по регістру на кожний CAPCOM канал, коли лічильник таймеру досягає значення регістру CCRx, то вихід скидається в 0 (ну або в 1 якщо увімкнена POLARITY_LOW).

Подивимось це все в динаміці, нижче два приклади роботи PWM з OCPOLARITY_HIGH та OCPOLARITY_HIGH




Функції налаштування таймеру

TIM2_OCXInit

TIM2_OC1Init(TIM2_OCMode, TIM2_OutputState, TIM2_Pulse, TIM2_OCPolarity);
TIM2_OC2Init(TIM2_OCMode, TIM2_OutputState, TIM2_Pulse, TIM2_OCPolarity);
TIM2_OC3Init(TIM2_OCMode, TIM2_OutputState, TIM2_Pulse, TIM2_OCPolarity);
  • TIM2_OCMode - режим роботи таймеру, нас цікавить TIM2_OCMODE_PWM1;
  • TIM2_OutputState - дозвіл виходу , нам потрібно TIM2_OUTPUTSTATE_ENABLE;
  • TIM2_Pulse - це значення CCRx (Capture/Compare Register);
  • TIM2_OCPolarity - це OCPOLARITY

TIM2_TimeBaseInit

Цією фукнцією можна задати значення ARR та переддільника частоти.
TIM2_TimeBaseInit(TIM2_Prescaler, TIM2_Period);
  • TIM2_Prescaler - значення переддільника, від TIM2_PRESCALER_1 до TIM2_PRESCALER_1;
  • TIM2_Period - це значення ARR (auto reload register).

TIM2_SetCompareX

TIM2_SetCompare1(ccr1);
TIM2_SetCompare2(ccr2);
TIM2_SetCompare3(ccr3);
Цією функцією можна змінити значення регістрів CCRx в процесі роботи.

TIM2_Cmd

TIM2_Cmd(NewState);
Цією функцією можна змінити стан роботи другого таймеру (DISABLE або ENABLE).

Приклади коду

Перший приклад 10% заповнення - ARR 499, CRR1 50, TIM2_OCPOLARITY_HIGH:
  GPIO_DeInit(GPIOD);
  TIM2_DeInit();
  GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);
  TIM2_OC1Init(TIM2_OCMODE_PWM1,
                TIM2_OUTPUTSTATE_ENABLE, 50,
                TIM2_OCPOLARITY_HIGH);
  TIM2_TimeBaseInit(TIM2_PRESCALER_16, 499);
  TIM2_Cmd(ENABLE);
Що маємо на виході:


Другий приклад змінили лише OCPOLARITY - тепер TIM2_OCPOLARITY_LOW
  GPIO_DeInit(GPIOD);
  TIM2_DeInit();
  GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);
  TIM2_OC1Init(TIM2_OCMODE_PWM1,
                TIM2_OUTPUTSTATE_ENABLE, 50,
                TIM2_OCPOLARITY_LOW);
  TIM2_TimeBaseInit(TIM2_PRESCALER_16, 499);
  TIM2_Cmd(ENABLE);

На цьому поки завершую це обзорну статтю. Головна документація від STM доступна за посиланням an3332-generating-pwm-signals-using-stm8sdiscovery-stmicroelectronics.pdf

Коментарі

Популярні дописи з цього блогу

Огляд DC-DC Step-down Buck перетворювачів

ESP8266 модуль з OLED екраном (HW-364A)

Модуль PD тригер IP2721 на 15 та 20 вольт