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

Таймеры

331

11.3.6. Режим сравнения выходного сигнала

До сих пор мы использовали несколько методов для управления формой выходного сигнала: один с использованием прерываний и один – с DMA. Оба они используют генерацию события UEV для переключения GPIO, сконфигурированного в качестве выходного вывода. Сравнение выходного сигнала (Output compare) – это режим, предоставляемый тай-

мерами общего назначения и расширенного управления, который позволяет управлять со-

стоянием выходных каналов, когда регистр сравнения каналов (TIMx_CCRx) совпадает с регистром счетчика таймера (TIMx_CNT).

Для программистов доступно шесть28 режимов сравнения выходного сигнала:

Времязадание в режиме сравнения выходного сигнала (Output compare timing)29: сов-

падение регистра сравнения выходного сигнала (CCRx) и счетчика (CNT) не влияет на выходной сигнал. Данный режим используется для генерации временного отсчета.

Активный выходной сигнал сравнения (Output compare active): в момент совпадения выходной сигнал канала устанавливается на активный уровень. Выходной сигнал канала становится высоким в момент совпадения счетчика (CNT) и регистра захвата/сравнения (CCRx).

Неактивный выходной сигнал сравнения (Output compare inactive): в момент совпа-

дения выходной сигнал канала устанавливается на неактивный уровень. Выходной сигнал канала становится низким в момент совпадения счетчика (CNT) и регистра захвата/сравнения (CCRx).

Инвертирование выходного сигнала сравнения (Output compare toggle): выходной сиг-

нал канала инвертируется в момент совпадения счетчика (CNT) и регистра захвата/сравнения (CCRx).

Установка активным/неактивным выходного сигнала сравнения (Output compare forced active/inactive): выходной сигнал канала принудительно устанавливается высоким (активный режим) или низким (неактивный режим) независимо от значения счетчика.

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

typedef struct {

 

 

uint32_t OCMode;

/* Задает режим TIM.

*/

uint32_t Pulse;

/* Задает значение импульса для загрузки в

 

 

регистр сравнения/захвата.

*/

uint32_t OCPolarity;

/* Задает полярность выходного сигнала.

*/

uint32_t OCNPolarity;

/* Задает полярность комплементарного выхода.

*/

uint32_t OCFastMode;

/* Задает состояние быстрого режима (Fast mode).

*/

uint32_t OCIdleState; /* Задает состояние вывода сравнения выходного

 

 

сигнала TIM во время состояния простоя (Idle state)

*/

uint32_t OCNIdleState;

/* Задает состояние комплементарного вывода сравнения

 

 

выходного сигнала TIM во время состояния простоя.

*/

} TIM_OC_InitTypeDef;

 

 

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

29Этот режим в CubeMX называется Frozen mode.

Таймеры

332

OCMode: задает режим сравнения выходного сигнала и может принимать значение

из таблицы 19.

Pulse: содержимое данного поля будет храниться в регистре CCRx, и оно опреде-

ляет, когда активировать выход.

OCPolarity: задает полярность выходного канала, когда регистры CCRx совпадают с регистрами CNT. Может принимать значение из таблицы 20.

OCNPolarity: задает полярность комплементарного выхода. Данный режим досту-

пен только в таймерах расширенного управления TIM1 и TIM8, которые позволяют генерировать на дополнительных выделенных каналах комплементарные сигналы (то есть, когда CH1 – ВЫСОКИЙ, CH1N – НИЗКИЙ, и наоборот). Эта функция специально разработана для приложений управления двигателем, и она не описана в данной книге. Может принимать значение из таблицы 21.

OCFastMode: задает состояние быстрого режима (fast mode state). Данный параметр

действует только в режимах ШИМ 1 и ШИМ 2 и может принимать значения

TIM_OCFAST_DISABLE и TIM_OCFAST_ENABLE.

OCIdleState: задает состояние вывода канала сравнения выходного сигнала во

время режима простоя (idle state) таймера. Может принимать значения TIM_OCIDLESTATE_SET и TIM_OCIDLESTATE_RESET. Данный параметр доступен только в тайме-

рах расширенного управления TIM1 и TIM8.

OCNIdleState: задает состояние вывода комплементарного канала сравнения вы-

ходного сигнала во время режима простоя (idle state) таймера. Может принимать

значения TIM_OCNIDLESTATE_SET и TIM_OCNIDLESTATE_RESET. Данный параметр досту-

пен только в таймерах расширенного управления TIM1 и TIM8.

Таблица 19: Доступные режимы сравнения выходного сигнала

Режим сравнения

выходного

сигнала

Описание

TIM_OCMODE_TIMING

Сравнение между регистром сравнения выходного сиг-

 

нала (CCRx) и счетчиком (CNT) не влияет на выходной

 

сигнал (он же режим Frozen mode).

TIM_OCMODE_ACTIVE

При совпадении устанавливает выходной сигнал канала на активный уровень.

TIM_OCMODE_INACTIVE

TIM_OCMODE_TOGGLE

При совпадении устанавливает выходной сигнал канала на неактивный уровень.

Выходной сигнал канала инвертируется в момент совпадения счетчика (CNT) и регистра захвата/сравнения

(CCRx).

TIM_OCMODE_PWM1

TIM_OCMODE_PWM2 TIM_OCMODE_FORCED_ACTIVE

TIM_OCMODE_FORCED_INACTIVE

Режим ШИМ 1 – см. в следующем параграфе. Режим ШИМ 2 – см. в следующем параграфе.

Выходной сигнал канала устанавливается в высокий уровень независимо от значения счетчика.

Выходной сигнал канала устанавливается в низкий уровень независимо от значения счетчика.

Таймеры

333

Таблица 20: Доступные режимы полярности сравнения выходного сигнала

Режим полярности сравнения

 

выходного сигнала

Описание

TIM_OCPOLARITY_HIGH

При совпадении регистров CCRx и CNT выходной сигнал

 

канала устанавливается высоким

TIM_OCPOLARITY_LOW

При совпадении регистров CCRx и CNT выходной сигнал канала устанавливается низким

Таблица 21: Доступные режимы полярности комплементарного вывода сравнения выходного сигнала

Режим полярности комплементарного

 

вывода сравнения выходного сигнала

Описание

TIM_OCNPOLARITY_HIGH

При совпадении регистров CCRx и CNT выход-

 

ной сигнал комплементарного канала устанавли-

 

вается высоким

TIM_OCNPOLARITY_LOW

При совпадении регистров CCRx и CNT выходной сигнал комплементарного канала устанавливается низким

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

CHx _Update =

TIMx _ CLK

CCRx

 

[5]

где:

TIMx _ CLK – рабочая частота таймера, а CCRx – значение импульса Pulse структуры TIM_OnePulse_InitTypeDef, используемой для конфигурации канала. Это означает, что мы можем вычислить значение Pulse, учитывая частоту канала, следующим образом:

Pulse =

TIMx _ CLK

CHx _Update

 

[6]

Важно подчеркнуть, что частота таймера должна быть установлена таким образом, чтобы значение Pulse, рассчитанное с помощью [6], было меньше значения Period таймера (значение CCRx не может быть выше значения TIM->ARR, которое соответствует значению Period таймера).

В следующем примере показано, как генерировать два выходных сигнала прямоугольной формы, один из которых работает на частоте 50 кГц, а другой – на частоте 100 кГц. Пример использует каналы 1 и 2 (привязаны к OC1 и OC2) таймера TIM3 и предназначен для работы на Nucleo-F030R8.

Таймеры

334

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

17volatile uint16_t CH1_FREQ = 0;

18volatile uint16_t CH2_FREQ = 0;

20int main(void) {

21

HAL_Init();

22

 

23Nucleo_BSP_Init();

24MX_TIM3_Init();

26HAL_TIM_OC_Start_IT(&htim3, TIM_CHANNEL_1);

27HAL_TIM_OC_Start_IT(&htim3, TIM_CHANNEL_2);

29while (1);

30}

31

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

33void MX_TIM3_Init(void) {

34TIM_OC_InitTypeDef sConfigOC;

36htim3.Instance = TIM3;

37htim3.Init.Prescaler = 2;

38htim3.Init.CounterMode = TIM_COUNTERMODE_UP;

39htim3.Init.Period = 65535;

40htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

41

HAL_TIM_OC_Init(&htim3);

42

 

43CH1_FREQ = computePulse(&htim3, 50000);

44CH2_FREQ = computePulse(&htim3, 100000);

46sConfigOC.OCMode = TIM_OCMODE_TOGGLE;

47sConfigOC.Pulse = CH1_FREQ;

48sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

49sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

50HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);

52sConfigOC.Pulse = CH2_FREQ;

53HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);

54}

Строки [46:53] конфигурируют каналы 1 и 2 для работы в качестве каналов сравнения выходного сигнала. Оба конфигурируются в режиме переключения toggle mode (то есть они инвертируют состояние GPIO каждый раз, когда регистр CCRx совпадает с регистром CNT таймера). TIM3 сконфигурирован для работы на частоте 16 МГц, и, следовательно, функция computePulse(), которая использует уравнение [6], вернет значения 320 и 160, чтобы иметь частоты переключения каналов, равные 50 кГц и 100 кГц соответственно. Однако приведенного выше кода все еще недостаточно для управления GPIO на данной частоте. Здесь мы конфигурируем каналы так, чтобы они переключали свой выход каждый раз, когда регистр таймера CNT равен 320 для канала 1 и 160 для канала 2. Но это означает, что частота переключения равна:

Таймеры

 

335

 

16000000

= 244 Гц

 

65535 +1

 

 

и мы имеем только смещение 10 мкс между двумя каналами, как показано на рисунке 21. Значение 65535 соответствует значению Period таймера, то есть максимальному значению, достигаемому регистром CNT таймера.

Рисунок 21: Смещение переключения между каналами 1 и 2

Чтобы достичь желаемой частоты переключения30, нам нужно переключать выход каждые 320 и 160 тиков регистра CNT таймера TIM3. Для этого мы можем определить следующую процедуру обратного вызова:

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

61void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) {

62uint16_t pulse;

63

64/* Переключение TIM2_CH1 с частотой = 50 кГц */

65if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)

66{

67pulse = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);

68/* Установка значения регистра захвата/сравнения */

69__HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, (pulse + CH1_FREQ));

70}

71

72/* Переключение TIM2_CH2 с частотой = 100 кГц */

73if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)

74{

75pulse = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);

76/* Установка значения регистра захвата/сравнения */

77__HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_2, (pulse + CH2_FREQ));

78}

79}

HAL_TIM_OC_DelayElapsedCallback() автоматически вызывается HAL каждый раз, когда регистр канала CCRx совпадает со счетчиком таймера. Таким образом, мы можем увеличить Pulse (то есть регистр CCRx) значением 320 для канала 1 и значением 160 для канала 2. Это приведет к тому, что соответствующий канал будет переключаться на желаемой частоте, как показано на рисунке 22.

30 Обратите внимание, что на качество выходного сигнала влияет параметр GPIO скорость нарастания, как описано в Главе 6.