Hal tim base start it

Hal tim base start it

Блог технической поддержки моих разработок

HAL_TIM_Base_Init

HAL_StatusTypeDef HAL_TIM_Base_Init (TIM_HandleTypeDef * htim)

Устанавливает конфигурацию таймера согласно параметрам, заданным в структуре типа TIM_HandleTypeDef .

  • htim – указатель на структуру параметров конфигурации типа TIM_HandleTypeDef .

Возвращает тип HAL_Status :

  • HAL_OK – при успешном выполнении;
  • HAL_ERROR – при ошибке.

Структура параметров конфигурации.

typedef struct <
TIM_TypeDef *Instance; // базовый адрес регистров
TIM_Base_InitTypeDef Init; // основные параметры таймера
HAL_TIM_ActiveChannel Channel; // активные каналы
DMA_HandleTypeDef *hdma[7U]; // параметры DMA
HAL_LockTypeDef Lock; // блокировка объекта
__IO HAL_TIM_StateTypeDef State; // состояние таймера
> TIM_HandleTypeDef;

  • Instance – базовый адрес регистров таймера (TIM1 … TIM4).
  • Init – структура основных параметров таймера. Описана ниже.
  • Channel – структура активных каналов таймера.
  • hdma — структура параметров DMA.
  • Lock – блокировка объекта. Сообщает системе о том, что таймер используется. Применяется для предотвращения случайного доступа к занятому ресурсу.
  • State – состояние таймера.
  • HAL_TIM_STATE_BUSY – занят, происходит инициализация;
  • HAL_TIM_STATE_READY – готов;
  • HAL_TIM_STATE_RESET – сброшен, не установлен.

Структура основных параметров таймера.

typedef struct <
uint32_t Prescaler; // предделитель
uint32_t CounterMode; // режим счета
uint32_t Period; // значение перезагрузки
uint32_t ClockDivision; // делитель
uint32_t RepetitionCounter; // значение повторов
uint32_t AutoReloadPreload; // режим перезагрузки
> TIM_Base_InitTypeDef;

  • Prescaler – предделитель. Делит частоту входных импульсов таймера. Может иметь значение 0 … 65535, что соответствует коэффициенту деления 1 … 65536.
  • CounterMode – режим счетчика. Может принимать значения:
  • TIM_COUNTERMODE_UP – прямой счет.
  • TIM_COUNTERMODE_DOWN – реверсивный счет.
  • TIM_COUNTERMODE_CENTERALIGNED1 — двунаправленный счет, прерывание генерируется в момент, когда счетчик считает в обратную сторону и доходит до 0.
  • TIM_COUNTERMODE_CENTERALIGNED2 — двунаправленный счет, прерывание генерируется, когда счетчик считает в прямом направлении и достигает значения перезагрузки.
  • TIM_COUNTERMODE_CENTERALIGNED3 — двунаправленный счет, прерывание генерируется, в обоих случаях — при достижении 0 и значения перезагрузки.
  • Period – значение регистра перезагрузки. Определяет период работы таймера. Может принимать значения 0 … 65535, что соответствует периоду 1 … 65535 импульсов тактирования.
  • ClockDivision – делитель входной частоты для внутренних нужд таймера.
    • TIM_CLOCKDIVISION_DIV1 ;
    • TIM_CLOCKDIVISION_DIV2 ;
    • TIM_CLOCKDIVISION_DIV4 .
    • RepetitionCounter – значение регистра счетчика повторов. Делит частоту событий таймера. Может принимать значение 0 … 255, что соответствует делителю 1 … 256. Есть только у таймеров TIM1 и TIM8.
    • AutoReloadPreload – управляет режимом доступа регистра перезагрузки.
      • TIM_AUTORELOAD_PRELOAD_DISABLE – регистр перезагрузки не буферизирован;
      • TIM_AUTORELOAD_PRELOAD_ENABLE — регистр перезагрузки буферизирован.
      • Пример инициализации таймера 1.

        /* конфигурация TIM1 */
        htim1.Instance = TIM1;
        htim1.Init.Prescaler = 719;
        htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
        htim1.Init.Period = 100;
        htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
        htim1.Init.RepetitionCounter = 0;
        htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
        if (HAL_TIM_Base_Init(&htim1) != HAL_OK) <

        HAL_TIM_Base_DeInit

        HAL_StatusTypeDef HAL_TIM_Base_DeInit (TIM_HandleTypeDef * htim)

        Деинициализация таймера, отключение.

        • htim – указатель на структуру параметров конфигурации типа TIM_HandleTypeDef .

        Возвращает тип HAL_Status :

        • HAL_OK – при успешном выполнении;
        • HAL_ERROR – при ошибке.

        HAL_TIM_Base_DeInit(&htim1); // отключение таймера

        HAL_TIM_Base_Start

        HAL_StatusTypeDef HAL_TIM_Base_Start (TIM_HandleTypeDef * htim)

        Разрешает работу таймера, запускает его.

        • htim – указатель на структуру параметров конфигурации типа TIM_HandleTypeDef .

        Возвращает тип HAL_Status :

        • HAL_OK – при успешном выполнении;
        • HAL_ERROR – при ошибке.

        HAL_TIM_Base_Start(&htim1); // запуск таймера

        HAL_TIM_Base_Stop

        HAL_StatusTypeDef HAL_TIM_Base_Stop (TIM_HandleTypeDef * htim)

        • htim – указатель на структуру параметров конфигурации типа TIM_HandleTypeDef .

        Возвращает тип HAL_Status :

        • HAL_OK – при успешном выполнении;
        • HAL_ERROR – при ошибке.

        HAL_TIM_Base_Stop(&htim1); // остановка таймера

        HAL_TIM_Base_Start_IT

        HAL_StatusTypeDef HAL_TIM_Base_Start_IT (TIM_HandleTypeDef * htim)

        Запускает таймер в режиме генерации прерываний. Запускает таймер и разрешает прерывания.

        • htim – указатель на структуру параметров конфигурации типа TIM_HandleTypeDef .

        Возвращает тип HAL_Status :

        • HAL_OK – при успешном выполнении;
        • HAL_ERROR – при ошибке.
        Читайте также:  Как настроить четкость шрифта в windows 10

        HAL_TIM_Base_Start_IT(&htim1); // запуск таймера

        HAL_TIM_Base_Stop_IT

        HAL_StatusTypeDef HAL_TIM_Base_Stop_IT (TIM_HandleTypeDef * htim)

        Останавливает таймер, запрещает его прерывания.

        • htim – указатель на структуру параметров конфигурации типа TIM_HandleTypeDef .

        Возвращает тип HAL_Status :

        • HAL_OK – при успешном выполнении;
        • HAL_ERROR – при ошибке.

        HAL_TIM_Base_Stop_IT(&htim1); // остановка таймера

        HAL_TIM_IRQHandler

        void HAL_TIM_IRQHandler (TIM_HandleTypeDef * htim)

        Завершает обработку прерывания по таймеру, сбрасывает флаг прерывания.

        • htim – указатель на структуру параметров конфигурации типа TIM_HandleTypeDef .

        Возвращает тип HAL_Status :

        • HAL_OK – при успешном выполнении;
        • HAL_ERROR – при ошибке.

        void TIM1_UP_IRQHandler(void) <

        // обработка прерывания по таймеру

        HAL_TIM_ConfigClockSource

        HAL_StatusTypeDef HAL_TIM_ConfigClockSource (TIM_HandleTypeDef * htim, TIM_ClockConfigTypeDef * sClockSourceConfig)

        Конфигурирует источник тактирования таймера.

        • htim – указатель на структуру параметров конфигурации типа TIM_HandleTypeDef .
        • sClockSourceConfig – указатель на структуру параметров конфигурации тактирования типа TIM_ClockConfigTypeDef.

        Возвращает тип HAL_Status :

        • HAL_OK – при успешном выполнении;
        • HAL_ERROR – при ошибке.

        Структура конфигурации тактирования.

        typedef struct <
        uint32_t ClockSource; // источник тактирования
        uint32_t ClockPolarity; // полярность
        uint32_t ClockPrescaler; // предделитель
        uint32_t ClockFilter; // фильтр
        > TIM_ClockConfigTypeDef;

        • ClockSource – источник тактирования таймера.
        • TIM_CLOCKSOURCE_ETRMODE2 – внешнее тактирование режим 2;
        • TIM_CLOCKSOURCE_INTERNAL – внутреннее тактирование (шина APB);
        • TIM_CLOCKSOURCE_ITR0 – внутренний триггер;
        • TIM_CLOCKSOURCE_ITR1 – внутренний триггер;
        • TIM_CLOCKSOURCE_ITR2 – внутренний триггер;
        • TIM_CLOCKSOURCE_ITR3 – внутренний триггер;
        • TIM_CLOCKSOURCE_TI1ED – вход TI1ED;
        • TIM_CLOCKSOURCE_TI1 – вход TI1;
        • TIM_CLOCKSOURCE_TI2 – вход TI2;
        • TIM_CLOCKSOURCE_ETRMODE1 – внешнее тактирование режим1.
      • ClockPolarity — полярность сигнала тактирования.
        • TIM_CLOCKPOLARITY_INVERTED – инверсия для внешнего тактирования (ETRx);
        • TIM_CLOCKPOLARITY_NONINVERTED – без инверсии для внешнего тактирования (ETRx);
        • TIM _CLOCKPOLARITY_RISING – положительный фронт для входов TIx;
        • TIM_CLOCKPOLARITY_FALLING – отрицательный фронт для входов TIx;
        • TIM_CLOCKPOLARITY_BOTHEDGE – оба фронта для входов TIx.
        • ClockPrescaler – параметры предделителя для внешнего тактирования (ETR).
          • TIM_CLOCKPRESCALER_DIV1 ;
          • TIM_CLOCKPRESCALER_DIV2 ;
          • TIM_CLOCKPRESCALER_DIV4;
          • TIM_CLOCKPRESCALER_DIV8 .
          • ClockFilter – параметр входного фильтра. Значение может быть в пределах 0 … 15.
          • Решил более основательно разобраться с таймерами. Дабы закрепить материал, родилось два простеньких примера.

            Первый, на мой взгляд, хороший пример, это извлечение звука ногодрыгом. Здесь используется сразу два таймера. Принцип я когда то уже описывал в 7 уроке AVR. Для тех кому лень искать: звук это колебание воздуха, чтобы воздух колебался, мы гоняем его колебанием мембраны динамика. Мембрана колеблется за счет того, что внутри динамика есть катушка. Когда подаем ток, катушка притягивается к постоянному магниту, когда не подаем ток, то катушка возвращается в исходное состояние. К катушке непосредственно прикреплена мембрана, таким образом она колеблется.

            Чем быстрее колеблется мембрана, тем «писклявее» звук, чем медленнее тем более «пердячий», «басистый» &#128578; То каким образом мы будем втягивать, будет влиять на форму звука. Мы можем врубить сразу максимум тока и динамик резко втянется до упора, а можем постепенно прибавлять ток и катушка будет постепенно втягиваться, т.е. формально это закон, по которому изменяется ток за секунду. Это будет влиять на то, какой звук слышим, например гитара и пианино играют одну и ту же ноту, но звучат совершенно по разному. Музыканты любят называть это «тембром».

            Самый простой пример это формировать меандр, т.е. сначала включить на полную ток, а потом выключить. Как раз в этом нам поможет таймер. В прошлый раз для формирования меандра я использовал прерывание, на самом деле не обязательно так делать. У stm32 есть замечательный режим Output compare. Мы настраиваем таймер на определенную частоту и задаем ему количество тиков (период). Как только он отсчитает это количество, ножка сама по себе инвертируется, а таймер перезапустится. Т.е. чтобы играть ноты нам просто достаточно менять значение регистра задающего период таймера.

            Читайте также:  Как освободить память на ps3

            Следующий момент, нам останется подставлять ноты через нужные нам промежутки времени. Для этого уже удобнее использовать прерывание. Где изменение длительности ноты меняется уже регистром сравнения. Думаю это понятно, что чем больше число в регистре сравнения, тем дольше играет нота.

            Аппаратная часть проста. Динамик подключается к ножке через транзистор.

            Программная часть. Я решил использовать ножку PD15, просто потому что она с краю, как раз на ней оказался TIM4_CH4. В окошке слева нужно выбрать тактирование Clock source и output compare для четвертого канала.

            Для третьего таймера достаточно включить тактирование

            Далее следует настройка общего тактирования. Для этого задействуем внешний кварц. Хоть мы и используем генератор кода, но на этом моменте нужно достаточно четко представлять, на какой шине сидит таймер, ибо частота на которой работает таймер не факт что равна частоте на которой работает камень ибо по пути есть куча предделителей шин. Поэтому не брезгуем референс мануалом и смотрим что таймер4 сидит на APB1.

            В разделе configuration настраиваем предделитель и прерывание для таймера3. На вкладке NVIC settings нужно поставить галку TIM3 global interrupt

            Для таймера4 настраиваем период и предделитель.

            Далее генерим проект, main.c нас в принципе не интересует, ибо весь код выполняется в прерывании. Поэтому нас интересует только stm32f4xx_it.c

            #include "stm32f4xx_hal.h" #include "stm32f4xx.h" #include "stm32f4xx_it.h" #include #define SIZE 96 #define BPM 320 #define N16 BPM/16 #define N8 BPM/8 #define N4 BPM/4 #define N2 BPM/2 #define N1 BPM //first octave #define C1 152 #define Cd1 143 #define D1 135 #define Dd1 127 #define E1 120 #define F1 113 #define Fd1 107 #define G1 101 #define Gd1 95 #define A1 90 #define B1 84 #define H1 80 //second octave #define C2 75 #define Cd2 71 #define D2 67 #define Dd2 63 #define E2 60 #define F2 56 #define Fd2 53 #define G2 50 #define Gd2 47 #define A2 44 #define B2 42 #define H2 39 #define P 0 uint16_t mass2[SIZE]=//; < E2,N16,E2,N8,E2,N16,P,N16,C2,N16,E2,N8,G2,N4,G1,N4, C2,N8,P,N16,G1,N16,P,N8,E1,N16,P,N16,A1,N8,H1,N16,P,N16,B1,N16,A1,N8,//38 G1,N16,E2,N16,G2,N16,A2,N8,F2,N16,G2,N16,P,N16,E2,N8,P,N16,C2,N16,D2,N16,H1,N16, //62 C2,N8,P,N16,G1,N16,P,N8,E1,N16,P,N16,A1,N8,H1,N16,P,N16,B1,N16,A1,N8, //84 >; extern TIM_HandleTypeDef htim3; uint16_t x = 0, i = 0, g = 0, p = 0; void SysTick_Handler(void) < HAL_IncTick(); HAL_SYSTICK_IRQHandler(); >void TIM3_IRQHandler(void) < /* USER CODE BEGIN TIM3_IRQn 0 */ /* USER CODE END TIM3_IRQn 0 */ HAL_TIM_IRQHandler(&htim3); /* USER CODE BEGIN TIM3_IRQn 1 */ //choose note freq if(p == 0) < //play TIM4->CNT = 0; TIM4->ARR = mass2[i]; i++; g = 0; p = 1; > else < g++; if(g >mass2[i]) < p = 0; i++; g = 0; >if(g > (mass2[i]-5)) < TIM4->CNT = 0; TIM4->ARR = 0; > > if(i == (SIZE)) < g = 0; i = 0; p = 0; >>

            Пояснения сделать стоит, есть массив mass2 содержащий ноты c1-до первой октавы,e2-ми второй, нечто похожее на то что используют гитаристы. Следующий за нотой элемент массива это длительность ноты, т.е. ноты идут через одну и длительности через одну. Сама нота это тупо дефайн, с заранее посчитанной величиной регистра формирующий период таймера(ARR).

            Читайте также:  Z blur что это в играх

            Допустим, нужно посчитать сколько нужно тиков, чтобы сформировать частоту, например нота До 1 октавы 261Гц. Для этого исходные 4 000 000 таймера делим на предделитель 50. Предделитель просто позволяет сделать величины нот в разумными, т.е. в пределах uint16_t.
            4000 000/50= 80 000 это рабочая частота после всех делителей.

            Теперь нужно найти число, которое нужно положить в ARR, чтобы из исходных 80 000 получить нужные нам 261Гц.
            (80 000/(261*2))-1= 152

            Почему тут умножаем на 2, потому что при достижении таймером регистра ARR, ножка инвертирует свое состояние, а нам нужно чтобы она успела включиться и выключиться.

            Примечательно то, что если значение счетного регистра CNT превысит значение ARR, то вся эта система зависнет. Поэтому при каждой смене ноты, лучше обнулять CNT руками. Флаг P показывает нужно ли играть ноту или нет, g отсчитывает длительности нот, i это текущая нота. P в массиве это пауза. В общем то и все.

            Второй пример намного проще, да и собственно здесь он скорее потому, что на днях дали покрутить одну штуку, которая меня впечатлила, поэтому не мог не упомянуть про нее. Это адский моторчик, который именуется бесколлекторным, управляется с помощью хитрожопого алгоритма, думаю когда нибудь я доберусь и реализую подобное. Но пока есть читерский вариант, в виде готового регулятора. Юзаются подобные моторчики во всяких коптерах и иже с ними.

            Выглядит это чудо так:

            Хочется отметить, что рвет мотор просто жестко, такая мелочь, а того и гляди из рук вырвется. Кроме того он высокооборотистый. К сожалению даташит, который был в комплекте как то не блистал технической информацией, поэтому кроме того, что работает он на 12В, жрет около 1А. Управляется хоть от 5В, хоть от 3.3В норм.

            С программной части все довольно таки просто. На регулятор подается ШИМ с частотой 50Гц. Все аналогично управлению сервоприводом. При запуске скважность должна быть 900мкс иначе движок не стартанет(такая вот защита от дурака), чтобы руки винтом не пообрубало. Если все ок, то он пропищит и тогда можно врубать газу, крайнее значение 2000мкс.

            Чтобы настроить возьмем тот же TIM4.

            Весь код в main, для удобства добавил кнопку — жмакаем, заполнение увеличивается на 50 мкс, мотор газует. Если достигли максимума, то начинаем с минимальных оборотов.

            Im giving a try to stm32 after a long time programming on avr, and seems like im struggling with timer. I want to use timer for handling freezes:

            In the code above im waiting when GPIO_PIN_3 will become in a low state. The thing is that its possible that it will stay high state forever, so i want to start timer1 and after 500ms it sohuld trigger interrupt. The problem is while loop catches 0 it tooks around 100us, and my timer configured with:

            so it much more then 100us, but whatever it fires once , i dont know why. As i understand timer, after you start it, it should start count and when the value is reached it will trigger the interrupt. But here even if i immediatly start and stop the timer:

            Ссылка на основную публикацию
            Canon mg3600 как сканировать
            Можно выполнять сканирование исходных документов, помещенных на рабочую поверхность, со специальными параметрами для документов. Поместите объект на рабочую поверхность. Щелкните...
            2Пир что за формула
            Здесь легко и интересно общаться. Присоединяйся! Ответ: Это либо длина окружности. С = 2пR Либо площадь круга S = пR^2...
            4000 Часов в секундах
            4000 секунд в минутах Автор Мариша задал вопрос в разделе Школы 1 час дольше чем 4000 секунд и получил лучший...
            Diablo 2 большой сундук
            PlugY - The Survival Kit 11.02 (Последняя версия. Подходит для Diablo 2 v1.09 - 1.13d) PlugY - The Survival Kit...
            Adblock detector