Микроконтроллеры

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Микроконтроллеры » Архив » STM32 TIMx Time base generator


STM32 TIMx Time base generator

Сообщений 1 страница 30 из 40

1

необходимые документы - RM, AN4013- STM32 cross-series timer overview, AN4776 -General-purpose timer cookbook

Time base generator   является основой любого таймера STM, как STM8 так и STM32 и по сути это сердце таймера
Time base generator определяет временные характеристики таймера.

Состав Time base generator :
CNT- Counter Счетчик таймера
PSC - Prescaler Прескалер - предделитель
ARR - Auto reload Регистр автоперезагрузки
Опционально:
RCR - Repetition counter  счетчик повторов

Рассмотрим частный случай работы таймера - режим счетчика, счет вверх.
Счетчик инкриминируется (увеличивается) с частотой определяемой в PSC .
Счетчик считает с 0 до значения в ARR.
Если в Time base generator нет Repetition counter(RCR) либо его значение равно 0,
то при достижении счетчиком значения равного тому что занесено в ARR,
счетчик сбрасывается ,
генерируется событие Update и выставляется флаг прерывания UIF: Update interrupt flag
Если значение RCR отлично от 0, то генерация события Update и установка флага прерывания UIF: Update interrupt flag
произойдут только после переполнения счетчиком количество раз равному значению в RCR.

Диаграммы поясняющие работу таймера.

ARR=36

http://s020.radikal.ru/i704/1703/ae/202249e498ad.png

Действие RCR - Repetition counter
http://s019.radikal.ru/i633/1703/4e/f1c9986ba4eb.png




Таким образом частота Update_event = TIM_CLK/((PSC + 1)*(ARR + 1)*(RCR + 1))
Где:
TIM_CLK - тактовая TIMx
PSC -значение предделителя
ARR - значение регистра ARR(по сути период)
RCR - значение RCR

Подставляем значения:
TIM_CLK - 48 000 000 Hz
PSC - 48 000-1
ARR - 500-1
RCR -0

48 000 000/((47999 + 1)*(499+ 1)*(0 + 1)) =2

http://s020.radikal.ru/i713/1703/fa/d2af016ccdd5.png

Применим на практике.
чип F0, таймер TIM2, частота тактирования таймера 48MHz, выхлоп на PA1 -2Hz.

Определяем необходимые тайминги.

Код:
define TIMx_CLK                48000000UL // Hz 
	#define TIMx_Internal_Frequency 1000UL     // Hz 
	#define TIMx_Out_Frequency      2UL        // Hz
	
	#define Prescaler (TIMx_CLK /TIMx_Internal_Frequency)-1UL
	#define Period (TIMx_Internal_Frequency/TIMx_Out_Frequency)-1UL

   

Включаем тактирование таймера и PORTA для наблюдения за процессом.
       

Код:
 RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
	  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;

     Конфигурируем пин . 

Код:
     	GPIOA->MODER &=~GPIO_MODER_MODER1;
	  GPIOA->MODER |= GPIO_MODER_MODER1_0 ;

         
Загружаем регистры таймера.

Код:
     TIM2->PSC = Prescaler;
    TIM2->ARR = Period;


Разрешаем прерывания от Update и запускаем счетчик.

Код:
TIM2->DIER |= TIM_DIER_UIE;
	TIM2->CR1|=TIM_CR1_CEN;

 
Включаем прерывание TIM2.

Код:
NVIC_SetPriority(TIM2_IRQn,0);
	NVIC_EnableIRQ(TIM2_IRQn);

Само прерывание.  Инвертируем состояние пина  и сбрасываем флаг прерывания.

Код:
void TIM2_IRQHandler (void)
{
	GPIOA->ODR ^= GPIO_ODR_1;
	
	TIM2->SR = ~TIM_SR_UIF;
	
}


Код целиком.

Код:
#define TIMx_CLK                48000000UL // Hz 
	#define TIMx_Internal_Frequency 1000UL     // Hz 
	#define TIMx_Out_Frequency      2UL        // Hz
	
	#define Prescaler (TIMx_CLK /TIMx_Internal_Frequency)-1UL
	#define Period (TIMx_Internal_Frequency/TIMx_Out_Frequency)-1UL

    void TIM2_IRQHandler (void)
{
	GPIOA->ODR ^= GPIO_ODR_1;
	
	TIM2->SR = ~TIM_SR_UIF;
	
}




 void tim2_led_init(void)
 
 {
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
	  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
	 
    GPIOA->MODER &=~GPIO_MODER_MODER1;
	  GPIOA->MODER |= GPIO_MODER_MODER1_0 ;
	 
    
	 
	  TIM2->PSC = Prescaler;
    TIM2->ARR = Period;

	TIM2->DIER |= TIM_DIER_UIE;
	TIM2->CR1|=TIM_CR1_CEN;
	NVIC_SetPriority(TIM2_IRQn,0);
	NVIC_EnableIRQ(TIM2_IRQn);
	 
	 
 
 }

http://s015.radikal.ru/i332/1703/58/5a73d2c48e00.png

2

Тактирование Time base generator.
Источники тактирования:

Internal clock - внутренняя тактовая.
External clock- внешний источник, имеет варианты:
– External mode1 (TI1 or TI2 pins)
– External clock mode2 (ETR pin)
– Internal trigger clock (ITRx).

2.1 Clock input sources
The timer always needs a clock source. It also can be synchronized by several clocks
simultaneously:
• Internal clock
• External clock
– External mode1 (TI1 or TI2 pins)
– External clock mode2 (ETR pin)
– Internal trigger clock (ITRx).
2.1.1 Internal clock
The timer is clocked by default by the internal clock provided from the RCC. To select this
clock source, the TIMx_SMCR->SMS (if present) bits should be reset.
2.1.2 External clock
The external clock timer is divided in two categories:
• External clock connected to TI1 or TI2 pins
• External clock connected to ETR pin
In these cases, the clock is provided by an external signal connected to TIx pins or ETR pin.
The maximum external clock frequency should be verified.
Note: 1 In addition to all these clock sources, the timer should be clocked with the APBx clock.
2 The external clocks are not directly feeding the prescaler, but they are first synchronized
with the APBx clock through dedicated logical blocks.
External clock mode1 (TI1 or TI2 pins)
In this mode the external clock will be applied on timer input TI1 pin or TI2 pin. To do this:
1. Configure the timers to use the TIx pin as input:
a) Select the pin to be used by writing CCxS bits in the TIMx_CCMR1 register.
b) Select the polarity of the input:
For the STM32F100/101/102/103/105/107 lines: by writing CCxP in the
TIMx_CCER register to select the rising or the falling edge;
For the other series & lines: by writing CCxP and CCxNP in the TIMx_CCER
register to select the rising/falling edge, or both edges(a).
c) Enable corresponding channel by setting the CCEx bit in the TIMx_CCER register.
2. Select the timer TIx as the trigger input source by writing TS bits in the TIMx_SMCR
register.
3. Select the external clock mode1 by writing SMS=111 in the TIMx_SMCR register
External clock mode2 (ETR pin)
The external clock mode2 uses the ETR pin as timer input clock. To use this feature:
1. Select the external clock mode2 by writing ECE = 1 in the TIMx_SMCR register.
2. Configure, if needed, the prescaler, the filter and the polarity by writing ETPS [1:0], ETF
[3:0] and ETP in the TIMx_SMCR register.
Internal trigger clock (ITRx)
This is a particular mode of timer synchronization. When using one timer as a prescaler for
another timer, the first timer update event or output compare signal is used as a clock for the
second one.

3

Решил вспомнить еще таймеры в stm32f103c8t6,накидал тестовую программку по переполнению таймера. Но прерывание не отрабатывает нормально,через раз.
Почему то прерывание срабатывает без поднятия флага UIF, с разрешенной маской только UIE. Может что неправильно настраиваю. Пробовал на 1 таймере и 2 .

Код:
#include "stm32f10x.h"


#define TIMx_CLK                72000000UL // Hz 
#define TIMx_Internal_Frequency 10000UL     // Hz 
#define TIMx_Out_Frequency      1UL        // Hz
	
#define Prescaler (TIMx_CLK /TIMx_Internal_Frequency)-1UL
#define Period (TIMx_Internal_Frequency/TIMx_Out_Frequency)-1UL


int32_t mig,flag_tik,flag_err,delay_tick,flag_tick;

void NMI_Handler(void)
{
	// otkaz HSE
	if(RCC->CIR & RCC_CIR_CSSF)
	{
    RCC->CIR |= RCC_CIR_CSSC; // ??????? ???? CSS
    GPIOA->BSRR|=GPIO_BSRR_BS0;
    flag_err=1;
	}
}

void TIM1_UP_IRQHandler(void)
{
	GPIOC->ODR ^= GPIO_ODR_ODR13;
	TIM1->SR &= ~TIM_SR_UIF;
  //TIM2->CNT=0;
	
}

void SysTick_Handler(void)  // 1 ms
{
	

    // 
    delay_tick++;
    if(delay_tick==500)
    {
    	delay_tick=0;
    	flag_tick=1;
    }
    
	
	
}

int main(void)
{
	
	 //enable CSS
	 RCC->CR |= RCC_CR_CSSON ;
	 
   // taktirovanie
    //RCC->APB2ENR|=RCC_APB2ENR_AFIOEN; // tatirovanie alternativ
	  //RCC->APB2ENR|=RCC_APB2ENR_IOPAEN;
	 // RCC->APB2ENR|=RCC_APB2ENR_IOPBEN;
	  RCC->APB2ENR|=RCC_APB2ENR_IOPCEN;
	 // RCC->APB1ENR|=RCC_APB1ENR_I2C1EN;  // taktirovanie i2c
    RCC->APB2ENR|=RCC_APB2ENR_TIM1EN;  // TIM1
	
	  // miganie PC13
    GPIOC->CRH&=~GPIO_CRH_MODE13;
	  GPIOC->CRH|=GPIO_CRH_MODE13_1;   //  50 mhz
	  GPIOC->CRH|=GPIO_CRH_MODE13_0;
	  GPIOC->CRH&=~GPIO_CRH_CNF13; 
	
    //  1 mC
    //SysTick_Config(SystemCoreClock /1000);
	
	  TIM1->PSC = 65000;
    TIM1->ARR = 65000;
    TIM1->DIER |= TIM_DIER_UIE;
    NVIC_SetPriority(TIM1_UP_IRQn,0);
    NVIC_EnableIRQ(TIM1_UP_IRQn);
    
	  TIM1->CR1|=TIM_CR1_CEN;
	  
    
	  while(1)
    {

    	mig=1;
    	mig=0;
    }
    
}

http://sh.uploads.ru/c0HI3.png
http://sd.uploads.ru/zCfaH.png
http://s6.uploads.ru/DJupz.png

4

Пробуй...

Код:
void TIM1_UP_IRQHandler(void)
{
   
if (TIM1->SR & TIM_SR_UIF)       
   {
     TIM1->SR  = ~TIM_SR_UIF;	
      GPIOC->ODR ^= GPIO_ODR_ODR13;
    }
}

5

Так все отлично,но все равно почему попадает в прерывания по таймеру когда стоит разрешение на один флаг на прерывание )))

6

Это на TIM2 ? На TIM1 не должно . Посмотри , когда брякнешься в прерывании, какие еще флаги установлены.
И читай о флагах CCx когда они устанавливаются...

7

Проштудирую как смогу таймер по R0008 :)

8

CERGEI что-то я не осознал ситуацию, попробую завтра на F103c8. По идее все нормально должно быть, тоже поиграюсь.

9

CERGEI У меня на обоих все нормально, одновременно.

Код:
void TIM1_UP_IRQHandler(void)
{
  TGL_TST0;
  TIM1->SR &= ~TIM_SR_UIF;
}

void TIM3_IRQHandler(void)
{
  TGL_TST1;
  TIM3->SR &= ~TIM_SR_UIF;
}

10

Подскажите, по коду dosikus-а.
"Разрешаем прерывания от Update и запускаем счетчик."

Код:
TIM2->DIER |= TIM_DIER_UIE;
	TIM2->CR1|=TIM_CR1_CEN;

дальше произойдет установка TIM_SR_UIF. потому что счетчик через ноль прошел. так?

11

ну я вот не понял вопрос....
ну сработает прерывание по переполнению когда СNT сравняется с ARR. далее CNT сбрасывается и срабатывает прерывание.
Может я где-то ошибаюсь , но я так все понимаю.

12

Atomic-dm написал(а):

ну я вот не понял вопрос....
ну сработает прерывание по переполнению когда СNT сравняется с ARR. далее CNT сбрасывается и срабатывает прерывание.
Может я где-то ошибаюсь , но я так все понимаю.

Суть вопроса, если на пальцах, когда стартуем счет в счетном регистре 0 или уже 1?

13

RA, первая же картинка в этой ветке. UE и UIF происходят в момент переполнение счетчика , т.е. при переходе счетчика со значения в ARR  в 0.(если счет вверх) Естественно после перехода в счетчике 0. И при первом старте в счетчике 0.

14

dosikus да. все так. это у меня перекос в мозгах,  на фоне, что считать началом, а что концом. философия ...

15

Вот когда начнёшь крутить режимами таймера... вот тогда и погрузишься в нирвану этой философии...
http://sh.uploads.ru/t/pmEWF.png
Вот где здесь модэ 1... а где модэ2??? А выглядит вроде всё одинаково...

16

HHIMERA написал(а):

Вот когда начнёшь крутить режимами таймера... вот тогда и погрузишься в нирвану этой философии...

Вот где здесь модэ 1... а где модэ2??? А выглядит вроде всё одинаково...

это же как вникать надо  :O  , чтобы режимы различить... у Вас там спи на таймере крутиться? или еще чего похлеще?
хочу сказать, что из нирваны выскочил на гребень волны фундаментального недопонимания, что есть начало, а что конец. вдохнул свежего воздуха и опять в нирвану.

Отредактировано RA (2018-07-08 21:58:32)

17

RA написал(а):

у Вас там спи на таймере крутиться? или еще чего похлеще?

Это СПИ под МАХ7219... на таймере...

18

HHIMERA написал(а):

Это СПИ под МАХ7219... на таймере...

%-)  ? цель какая?

Отредактировано RA (2018-07-08 23:47:53)

19

Подключить хардварно... при надобности... МАХ7219... если основной СПИ вдруг занят...

20

RA написал(а):

? цель какая?

(Вчера 23:47:53)

К примеру делали как-то SPI на 16 каналов с одним клоком ...

21

HHIMERA написал(а):

Подключить хардварно... при надобности... МАХ7219... если основной СПИ вдруг занят...

:) можно было не спрашивать. ответ очевиден.

22

dosikus написал(а):

К примеру делали как-то SPI на 16 каналов с одним клоком ...

вот это уже из области применения ... интересно... что там такое было? на 16-ть каналов. ну хоть намекни что ли...

Отредактировано RA (2018-07-09 12:22:01)

23

RA, какой-то дисплей , я только идею подал и сам SPI разрулил . Где-то на изиэлектроникс.
Нашел
http://forum.easyelectronics.ru/viewtop … mp;t=31222

24

RA написал(а):

dosikus да. все так. это у меня перекос в мозгах,  на фоне, что считать началом, а что концом. философия ...

Копался с TIM2 (TIM3) в STM32F103C8T6 у меня нормально работает (запускается) только в таком порядке

Код:
void TIM2_Init (void)
{    
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
    TIM2->CR1 &= ~TIM_CR1_ARPE;
    TIM2->CR1 &= ~TIM_CR1_DIR;             
    TIM2->ARR = Period;
    TIM2->PSC = Prescaler;
    
    TIM2->EGR |=TIM_EGR_UG;         // устанавливаем бит UG для занесения данных из ARR и PSC в теневые регистры
                                                       //  сразу выставится флаг прерывания  UIF 
    ...........    
}
//---------------------------------------------------------------------------
void TIM2_Start (void)
{
    TIM2->SR &= ~TIM_SR_UIF;                 // очистим выставленный флаг UIF (можно было очистить в Init)
    TIM2->DIER |= TIM_DIER_UIE;             
    TIM2->CR1|=TIM_CR1_CEN;                 // запускаем таймер
    NVIC_EnableIRQ(TIM2_IRQn);  
}
//----------------------------------------------------------------------------
void TIM2_IRQHandler (void)
{
    // Здесь как обычно
}
//-----

Отредактировано vadiv (2018-10-20 18:57:46)

25

vadiv, и все же TIM2->SR = ~TIM_SR_UIF ...

26

dosikus написал(а):

vadiv, и все же TIM2->SR = ~TIM_SR_UIF ...

может кто нибудь внятно пояснить почему  TIM2->SR = ~TIM_SR_..., а не TIM14->SR &= ~TIM_SR_... ?

Отредактировано RA (2019-01-20 00:36:34)

27

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

А с другой стороны в резервные биты нельзя писать единицы так что если совсем правильно делать нужно записать все биты кроме сбрасываемого.

28

RA написал(а):

может кто нибудь внятно пояснить почему  TIM2->SR = ~TIM_SR_..., а не TIM14->SR &= ~TIM_SR_... ?

Потому, что  регистре TIMx_SR  биты обозначены как - rc_w0.

Read/clear (rc_w0) Software can read as well as clear this bit by writing 0. Writing ‘1’ has no effect on the bit value.
Т.е ТОЛЬКО запись 0 очищает бит. Запись единицы не производит ни каких изменений (Даже правильнее  - запись 1 не влияет на значение данного бита).

Поэтому надо сразу записывать то, что нужно.

Отредактировано vadiv (2019-01-20 12:21:54)

29

спасибо. доступно. понятно.

30

F4 , таймер работает по OPM. запускается по сигналу и выдает импульс. далее по окончанию работает обработчик таймера. Вопрос вот в чем - если в момент работы обработчика на сигнальную ножку поступит сигнал, то таймер опять выдаст импульс ? несмотря на то что происходит обработка прерывания ? иль я что-то не понимаю.... мне казалось что когда работает обработчик, таймер не должен аппаратно сработать , а по факту он срабатывает...(если я правильно понял) . Т.е. получается что аппаратная часть всегда работает ? Если в прерывании таймер вырубать, то все "крашится", но задача именно на период обработчика отрубать аппаратную часть....

Единственное что смог придумать это по импульсу активировать другое прерывание(Exti) , в нем отрубать таймер OPM и делать нужную обработку и перед выходом опять активировать таймер.
В общем интересны мнения по этому вопросу.

P.S. сразу хочу сказать - софтверная обработка занимает не много кода и является самой важной частью работы, поэтому обрабатывается именно в прерывании, а не по флагу в мейне. По флагу не прокатит, так других обработчиков(с меньшим приоритетом) там достаточно и нельзя допустить чтобы из-за них тормозилась основная задача.


Вы здесь » Микроконтроллеры » Архив » STM32 TIMx Time base generator