Функция коммутации таймера STM32



 Функция коммутации используется в комбинации с функцией пред загрузки (preload) для изменения конфигурации канала таймера в четкой синхронизации с внешними событиями таймера, которые поступают на него через один из внутренних или внешних входов таймера. Конфигурация, к которой это относится, может быть, например, режимом вывода канала, разрешения/запрещения канала или другое. Входы ITRx являются примерами внутренних входов, и ETR, TI1 или TI2 это примеры внешних входов.

Как было установлено в описании базовых режимов GP-таймеров, управляющие биты OCxM, CCxE и CCxNE предоставляют функцию пред загрузки (preload). Когда функция пред загрузки разрешена этими полями, любой доступ к ним на запись не меняет рабочий режим канала таймера, потому что на самом деле операция записи выполняется над теневыми полями предварительной загрузки. В активные поля, которые в настоящее время управляют работой выхода таймера, остаются неизменными.

Как только событие коммутации было сгенерировано внутри таймера, содержимое теневых preload-полей будут перенесены в активные поля, и, следовательно, режим выходного канала поменяется.

В зависимости от конфигурации битового поля CCUS control в регистре управления таймера TIMx_CR2, событие коммутации может генерироваться после детектирования активного перепада на сигнале входа триггера (timer trigger input, TRGI). В частности, оно может генерироваться после детектирования активного перепада на входе синхронизации таймера ITRx (входы ITRx являются частью источников сигнала TRGI).

Эта функция может использоваться для управления одним таймером, когда сработало событие коммутации на другом таймере, через внутреннюю синхронизацию между таймерами. Альтернативно событие коммутации может генерироваться программно путем установки битового поля COMG в регистре таймера TIMx_EGR.

 

Таймеры общего назначения TIM 9- TIM 14

TIM9 — TIM14 работают полностью независимо друг от друга, не имея никаких общих ресурсов, при этом они обладают следующим функционалом:

· 16-битный автоматически перезагружаемый нарастающий счётчик (то есть он может считать от нуля до заданного значения)

· 16-битный программируемый предделитель (позволяет увеличивать счётчик не каждый такт, а через заданное количество тактов)

· модуль «захвата/сравнения» с одним (TIM10/11, TIM13/14) или двумя (TIM9, TIM12) независимыми каналами, которые, в зависимости от настройки направления (на вход или на выход) можно использовать для решения следующих задач:

o фиксация событий на входах («захват»)

o управление выходами по достижению определённых промежуточных значений («сравнение»)

o генерация ШИМ-сигнала на выходах (с выравниванием по фронтам счётчика)

o генерация единичного импульса на выходах (только TIM9, TIM12)

· генерация прерываний по следующим событиям:

o update (UEV) — событие обновления счётчика. Генерируется в результате переполнения (достижения заданнного значения) или при инициализации (реинициализации по триггеру или программной)

o input capture (ICx) — изменение уровня на входе (событие «захват»)

o output compare (OCx) — достижение заданного промежуточного значения счётчика (событие «сравнение»)

o события триггера — старт/стоп счётчика, инициализация или счёт (одно увеличение счётчика) от внутреннего триггера (только для TIM9/14).

 

Блок-схема таймеров TIM10/11, TIM13/14

Блок-схема таймеров TIM9, TIM12

Базовый модуль таймеров TIM9-TIM14 точно такой же как и для простейших таймеров.

Основу базового модуля составляют три регистра:

  • TIMx_CNT — регистр-счётчик
  • TIMx_PSC — регистр предделителя (с буферизацией)
  • TIMx_ARR — регистр автоматической перезагрузки (с буферизацией)

Включение/выключение счётчика производится установкой/сбросом бита CEN в регистре TIMx_CR1.

Для регистров с буферизацией данные сначала записываются в буферы, а уже оттуда в рабочие регистры. В случае с регистром TIMx_PSC загрузка данных из буфера в рабочий регистр происходит только по событию обновления счётчика. Для регистра TIMx_ARR, в зависимости от состояния бита ARPE регистра TIMx_CR1, возможны два варианта: 1) данные сразу записываются в рабочий регистр (сквозная запись, ARPE = 0); 2) данные записываются в рабочий регистр по событию обновления счётчика (отложенная запись, ARPE = 1).

Базовый модуль может генерировать только одно событие — update (UEV). Оно генерируется при переполнении счётчика (когда счётчик досчитает до величины, записанной в регистр TIMx_ARR) или программно, установкой бита UG в регистре TIMx_EGR. Генерацию UEV можно отключить установкой бита UDIS регистра TIMx_CR1. При этом счётчик и предделитель будут по прежнему сбрасываться в ноль при переполнении, однако значения рабочих регистров TIMx_PSC и TIMx_ARR не будут обновляться.

Кроме того, установкой бита URS можно добиться того, что при возникновении события UEV не будет устанавливаться флаг UIF. Это позволяет избежать генерации прерываний по событиям обновления и «захвата» (при сбросе счётчика по событию «захвата»).

Тактирование счётчиков

В качестве источника счётных импульсов таймеров могут быть выбраны следующие варианты:

  • внутренний тактовый сигнал (CK_INT) — выбирается установкой битов SMS[2:0]=’000′ (контроллер slave-режима — выключен). Для TIM10/11 и TIM13/14 это единственный вариант тактирования. Если выбран такой режим, то тактирование начинается сразу после установки в 1 бита CEN.
  • внешнее тактирование (только для TIM9 и TIM12). Для использования этого способа битами SMS[2:0] должен быть выбран режим внешнего тактирования 1. Источник тактового сигнала в этом случае выбирается битами TS[2:0]. Таким источником могут быть:
    • внешние входы (TIx) — передний или задний фронт на выбранном выходе
    • внутренние входы триггера (ITRx) — каскадно подключенные к выходам других таймеров).

 

Лекция 5

Прерывания

Прерывания – это сигнализация от устройства (его контроллера) центральному процессору о некоторых событиях, требующих программных действий. Прерывания требуют приостановки текущего потока инструкций (с сохранением состояния) и запуска процедуры обработки прерывания. Эта процедура первым делом должна идентифицировать источник прерывания (их может быть несколько), а затем выполнить действия, связанные с реакцией на событие. Если события должны вызывать некоторые действие прикладной программы, то обработчику прерывания следует только подать через ОС сигнал, который запустит поток инструкций, выполняющий эти действия.

Одними из главных усовершенствований ядра Cortex по сравнению с предшествующими ЦПУ ARM являются структура прерываний и механизм обработки исключительных ситуаций. ЦПУ ARM7 и ARM9 использовали две линии прерывания: быстродействующая линия прерывания и линия прерывания общего назначения. Данные линии поддерживали все источники прерываний в рамках микроконтроллера конкретного производителя. Однако, несмотря на использование, казалось бы, одинаковых подходов, конкретная реализация могла отличаться между разными производителями МК. Структуре прерываний ARM7 и ARM9 свойственны еще две проблемы. Во-первых, она недетерминистическая, т.к. время, которое требуется на завершение текущей инструкции при возникновении прерывания непостоянно. Конечно же, во многих приложениях это не создает проблем, но в системах реального времени могут возникнуть большие трудности. Во-вторых, поддержка вложенных прерываний в архитектуре ARM7 и ARM9 реализована неэффективно и требует написания дополнительных кодов программы в виде ассемблерных макросов или ОСРВ. Таким образом, ключевой задачей, которая стояла перед разработчиками ядра Cortex, являлась преодоление всех этих ограничений и     разработка стандартной структуры прерываний, отличающейся предельным быстродействием и детерминистичностью.

Прерывания и события

I nterrupt — это прерывание. При прерывании обычно программа пакует регистры в стек и бросается по вектору, а оттуда через JMP сигает уже в обработчик прерывания. В Cortex все немного не так. Тут вектора прерывания — это просто вектор-адреса, лежащие в нужном месте. В виде констант. А при прерывании программа не прыгает на вектор, а берет этот вектор-адрес и сразу же пихает его в программный счетчик, тем самым переходит сразу на обработчик. Так быстрей, исчезает лишняя операция по переходу на вектор.

Event — это аппаратное событие. Опустел буфер UART — держи event, натикал таймер — еще один event. Событие может вызвать прерывание, может запустить какую-либо периферию, например пнуть DMA, чтобы оно выгрузило данные. Но событие далеко не всегда может вызвать прерывание. Каждое прерывание вызывается событием, но не каждое событие вызывает прерывание.

В STM32 существуют вектора прерываний. Управление и обработка прерываниями производится контроллером приоритетных векторных прерываний NVIC (Nested Vectored Interrupt Controller). Это особые адреса, куда контроллер переходит если происходит прерывание. Они записаны в таблицу и располагаются вначале памяти. Впрочем, система гибкая и переконфигурировав NVIC можно поставить ее куда угодно.

В процессор STM32 входит контроллер вложенных векторизованных прерываний, поддерживающий до 240 внешних УВВ. Контроллер поддерживает одно немаскируемое прерывание и еще до 240 внешних линий прерывания, которые можно подключить к пользовательским УВВ. В ядре Cortex поддерживается еще 15 дополнительных источников прерываний, использующихся для обработки внутренних исключительных ситуаций ядра Cortex. Максимальное число маскируемых линий прерывания КВВП микроконтроллеров STM32 равно 43. При инициации прерывания NVIC переключает ядро в режим обработки прерывания. После перехода в режим обработки прерывания регистры ядра помещаются в стек. Непосредственно во время записи значения регистров в стек осуществляется выборка начального адреса функции обработки прерывания. В стек перемещается регистр регистр статуса программы ( Program Status Register (PSR)), счетчик программы (Program Counter (PC)) и регистр связи (Link Register (LR) ). Благодаря этому, запоминается состояние, в котором находилось ядро перед переходом в режим обработки прерываний. Также сохраняются регистры R0 — R3 и R12. Эти регистры используются в инструкциях для передачи параметров, поэтому, помещение в стек делает возможным их использование в функции обработки прерывания, а R12 часто выступает в роли рабочего регистра программы. По завершении обработки прерывания все действия выполнятся в обратном порядке: извлекается содержимое стека и, параллельно с этим, осуществляется выборка адреса возврата. С момента инициации прерывания до выполнения первой команды обработчика прерываний проходит 12 тактов, такое же время необходимо для возобновления основной программы после завершения обработки прерывания.

 Таблицу векторов можно увидеть для конкретного контроллера в STM32F10x.s файле.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 ; Vector Table Mapped to Address 0 at Reset              AREA RESET, DATA,               READONLY            EXPORT __Vectors   __Vectors  DCD __initial_sp         ; Top of Stack            DCD Reset_Handler        ; Reset Handler            DCD NMI_Handler          ; NMI Handler            DCD HardFault_Handler    ; Hard Fault Handler            DCD MemManage_Handler    ; MPU Fault Handler            DCD BusFault_Handler     ; Bus Fault Handler            DCD UsageFault_Handler   ; Usage Fault Handler            DCD 0                    ; Reserved            DCD 0                    ; Reserved            DCD 0                    ; Reserved            DCD 0                    ; Reserved            DCD SVC_Handler              ; SVCall Handler            DCD DebugMon_Handler     ; Debug Monitor Handler            DCD 0                    ; Reserved            DCD PendSV_Handler       ; PendSV Handler            DCD SysTick_Handler      ; SysTick Handler              ; External Interrupts            DCD WWDG_IRQHandler     ; Window Watchdog            DCD PVD_IRQHandler      ; PVD through EXTI Line detect            DCD TAMPER_IRQHandler   ; Tamper            DCD RTC_IRQHandler      ; RTC            DCD FLASH_IRQHandler    ; Flash            DCD RCC_IRQHandler       ; RCC            DCD EXTI0_IRQHandler     ; EXTI Line 0            DCD EXTI1_IRQHandler     ; EXTI Line 1            DCD EXTI2_IRQHandler     ; EXTI Line 2            DCD EXTI3_IRQHandler     ; EXTI Line 3            DCD EXTI4_IRQHandler     ; EXTI Line 4            DCD DMAChannel1_IRQHandler ; DMA Channel 1            DCD DMAChannel2_IRQHandler ; DMA Channel 2            DCD DMAChannel3_IRQHandler ; DMA Channel 3            DCD DMAChannel4_IRQHandler ; DMA Channel 4            DCD DMAChannel5_IRQHandler ; DMA Channel 5            DCD DMAChannel6_IRQHandler ; DMA Channel 6            DCD DMAChannel7_IRQHandler ; DMA Channel 7            DCD ADC_IRQHandler       ; ADC            DCD USB_HP_CAN_TX_IRQHandler ; USB High Priority or CAN TX            DCD USB_LP_CAN_RX0_IRQHandler ; USB Low Priority or CAN RX0            DCD CAN_RX1_IRQHandler   ; CAN RX1            DCD CAN_SCE_IRQHandler   ; CAN SCE            DCD EXTI9_5_IRQHandler   ; EXTI Line 9..5            DCD TIM1_BRK_IRQHandler  ; TIM1 Break           DCD TIM1_UP_IRQHandler   ; TIM1 Update            DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation            DCD TIM1_CC_IRQHandler   ; TIM1 Capture Compare            DCD TIM2_IRQHandler      ; TIM2            DCD TIM3_IRQHandler      ; TIM3            DCD TIM4_IRQHandler      ; TIM4            DCD I2C1_EV_IRQHandler   ; I2C1 Event            DCD   I2C1_ER_IRQHandler   ; I2C1 Error            DCD I2C2_EV_IRQHandler   ; I2C2 Event            DCD I2C2_ER_IRQHandler   ; I2C2 Error            DCD SPI1_IRQHandler      ; SPI1            DCD SPI2_IRQHandler      ; SPI2            DCD USART1_IRQHandler    ; USART1            DCD USART2_IRQHandler    ; USART2            DCD USART3_IRQHandler    ; USART3            DCD   EXTI15_10_IRQHandler ; EXTI Line 15..10            DCD RTCAlarm_IRQHandler  ; RTC Alarm through EXTI Line            DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend                AREA |.text|, CODE, READONLY

вначале идут так называемые Fault Interrupt, Прерывания ядра. Которые имеют наивысший приоритет и не подчиняются команде общего запрета/разрешения прерываний:
Для них свой флажок и своя команда:

1 2 __enable_fiq (); __disable_fiq();

Разрешение прерываний

· Разрешить глобальные прерывания

· Разрешить нужное прерывание в NVIC

· Настроить и разрешить конкретные прерывания непосредственно в периферии. Т.е. настроить нужные events на прерывания.

Разрешение глобальных прерываний
Достаточно всего лишь поставить флажок состояния процессора. В CMSIS за это отвечает крошечная функция

1  __enable_irq ();

 

Разрешить прерывания в NVIC
Описание на NVIC можно найти в файле PM0056 STM32F10xxx Cortex-M3 programming manual. Там описывается только то, что есть в ядре Cortex M3. Можно конечно открыть более общее описание, взятое с сайта ARM. Но там будут небольшие отличия. Например, у STM32 урезана система группировки приоритетов.

За работу с прерываниями в NVIC отвечают несколько регистров. Вот они все указаны в таблице 41.


· ISER — Interrupt Set Enable Register. Запись бита в нужную позицию включает прерывание.

· ICER — Interrupt Clr Enable Register. Запись сюда наоборот выключает прерывание.

Запись 1 в биты этих регистров запрещает/разрешает прерывания. Запись 0 не делает ничего, а чтение возвращает текущее состояние разрешено/запрещено

· ISPR — Interrupt Set Pending Register. Поставить прерывание в ожидание.

· I С PR — Interrupt Clr Pending Register. Сбросить прерывание с ожидания.

Запись 1 в биты этих регистров ставит/снимает прерывания в очередь на исполнение. Запись 0 не делает ничего, а чтение возвращает текущее состояние прерывания. Ждет он обработки или уже нет. Т.е. если в этом регистре где то стоит бит 1, значит это прерывание еще не вызывалось.

· IABR — Interrupt active bit registers. Регистр показывающий активно ли в данный момент прерывание. Автоматически ставится когда мы попадаем в обработчик и автоматом же снимается когда мы уходим из него. Этот регистр можно только читать.

· Да, но тут возникает вопрос. Прерывания то у нас все именные. Таймер там, UART еще что то. А тут какие то номера? Где узнать у какого прерывания какой номер? А все в той же таблице векторов, что я привел в самом начале. Пропускаем FAULT INTERRUPT и начиная с

1 2 3 4 5 6  ; External Interrupts            DCD WWDG_IRQHandler    ; Window Watchdog    Номер 0            DCD PVD_IRQHandler     ; PVD through EXTI Line detect Номер 1            DCD TAMPER_IRQHandler  ; Tamper               Номер 2            DCD RTC_IRQHandler     ; RTC         Номер 3 ...

· И так далее до конца. Ну, а номер регистра выбираем исходя из того, что в один регистр влазит всего 32 бита. А еще, в составе CMSIS есть удобные функции для руления NVIC контроллером. Они стандартные для всех МК на Cortex M3.

1 2 void NVIC_EnableIRQ(IRQn_t IRQn) // Enable IRQn void NVIC_DisableIRQ(IRQn_t IRQn) // Disable IRQn

· Одна запрещает, другая разрешает. Все просто :)

· Пример:

1 NVIC_EnableIRQ (EXTI1_IRQn); // Разрешить прерывание EXTI1 в NVIC

· Там же есть функции для остальных ковыряний с NVIC. Вот весь список:

1 2 3 4 5 6 7 8 9 10 void NVIC_SetPriorityGrouping(uint32_t priority_grouping)  // Задать группы/подгруппы приоритетов void NVIC_EnableIRQ(IRQn_t IRQn)                          // Включить IRQn void NVIC_DisableIRQ(IRQn_t IRQn)                         // Выключить IRQn uint32_t NVIC_GetPendingIRQ (IRQn_t IRQn)                  // Вернуть true (точнее IRQ-Number) если IRQn в ожидании void NVIC_SetPendingIRQ (IRQn_t IRQn)             // Поставить IRQn в ожидание void NVIC_ClearPendingIRQ (IRQn_tIRQn)            // Выкинуть из очереди на ожидание IRQn uint32_t NVIC_GetActive (IRQn_t IRQn)              // Функция "Бля, где это я?" Возвращает номер текущего активного прерывания если такое имеется void NVIC_SetPriority (IRQn_t IRQn, uint32_t priority)      // Задать приоритет IRQn uint32_t NVIC_GetPriority (IRQn_t IRQn)            // Считать приоритет IRQn void NVIC_SystemReset (void)                       // Reset the system

 


Дата добавления: 2020-01-07; просмотров: 389; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!