Перейти к содержанию
    

Генерация временных интервалов.

Я хочу на таймере TIM4 создать три временных события.

 

void Tim4Init(void)
{
 NVIC_SetPriority(TIM4_IRQn, 1);  
 NVIC_EnableIRQ(TIM4_IRQn);

 RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
  TIM4->PSC = 0x8CA0;  //72Mhz/36000 = 2ms

//TIM4->ARR = 1000; //reload every 200ms
 TIM4->CCMR1 &= ~TIM_CCMR1_OC1M; //MODE 000 - capture/comp for time events
 TIM4->CCMR1 &= ~TIM_CCMR1_OC2M;
 TIM4->CCMR2 &= ~TIM_CCMR2_OC3M;
 TIM4->DIER |= (TIM_DIER_CC1IE | TIM_DIER_CC2IE| TIM_DIER_CC3IE);
 TIM4->CCR1 = 500;  //1s
 TIM4->CCR2 = 1000; //2s 
 TIM4->CCR3 = 1500; //3s
 TIM4->CR1 |= TIM_CR1_CEN;
}

 

Проверяем

void TIM4_IRQHandler (void)  
{
 if(TIM4->SR & TIM_SR_CC1IF)
 {
   TIM4->SR &= ~TIM_SR_CC1IF;
   UsartSendString("CC1 Int\r");
 }
 if(TIM4->SR & TIM_SR_CC2IF)
 {
   TIM4->SR &= ~TIM_SR_CC2IF;
   UsartSendString("CC2 Int\r");
 }
 if(TIM4->SR & TIM_SR_CC3IF)
 {
   TIM4->SR &= ~TIM_SR_CC3IF;
   UsartSendString("CC3 Int\r");
 }
}

 

По идее каждую секунду я должен видеть capture/compare event. На самом деле таймер доходит до TIM4->ARR и только потом происходят интерапты. Как я понимаю таймер должен досчитать до TIM4->CCR1 - CCR3 регтстра и сгенерировать интерапт без всякой связи с TIM4->ARR.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В TIMx_DIER нужно разрешить прерывания по совпадению и соответственно обработчики прописать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В TIMx_DIER нужно разрешить прерывания по совпадению

а это не оно?

TIM4->DIER |= (TIM_DIER_CC1IE | TIM_DIER_CC2IE| TIM_DIER_CC3IE);

 

и соответственно обработчики прописать.

 

так прописан - void TIM4_IRQHandler (void)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если TIM4->CCR3 = 1500; //3s

то и TIM4->ARR = должен быть более 1500

 

а так должно работать. Хотябы TIM4->CCR1 = 500; //1s

 

может дело в этом "If channel CC1 is configured as output:"

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно разрешить работу каналов в CCER.

как я понял CCER нужен если хотим выдать сигнал наружу на соответствующую ножку.

 

 

Если TIM4->CCR3 = 1500; //3s

то и TIM4->ARR = должен быть более 1500

 

а так должно работать. Хотябы TIM4->CCR1 = 500; //1s

 

может дело в этом "If channel CC1 is configured as output:"

 

Я вижу на терминале

CC1 Int
CC2 Int
CC3 Int
тут проходит время = TIM4->ARR 
CC1 Int
CC2 Int
CC3 Int
и так далее ......

Но у меня capture/compare interrupt сравнивает значение таймера с кэпчэ\компэрэ регистром, почему вмешивается TIM4->ARR?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Счетчик считает от 0 до TIM4->ARR. Не совсем понимаю что куда вмешиваетс?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Счетчик считает от 0 до TIM4->ARR. Не совсем понимаю что куда вмешиваетс?

я понял в чем дело. таймер всегда досчитает до своего максимального значения которое задает ARR . то есть он генерит первое сравнение CC1 Int,потом второе CC2 Int,

третье CC3 Int, а дальше идет до ARR а интерапты в это время висят. в MSP430 было сделано очень срасиво - на CC1 я получал интерапт КАЖДУЮ 1сек, на CC2 КАЖДЫЕ 2сек, на CC3 КАЖДЫЕ 3сек.

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точно так же красиво можно и на STM. Самое простое - внутренний счетчик инкрементировать в прерывании. Досчитал до 3 - обнулить.

 

про "висят" не совсем понял. Если вызывается обработчик и сбрасываетя флаг, то что будет висеть?

 

Для секундных интервалов есть RTC с будильником. Вообще все просто.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точно так же красиво можно и на STM. Самое простое - внутренний счетчик инкрементировать в прерывании. Досчитал до 3 - обнулить.

в таком случае первый CC1 Int будет через секунду, второй CC1 Int будет через три секунды.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в таком случае первый CC1 Int будет через секунду, второй CC1 Int будет через три секунды.

Нет. Установить прерывание по "апдейт". Выбрать предустановки чтоб прерывался раз в секунду. В обработчике, вызываемом ежесекундно, инткрементировать переменную и в зависимости от ее значения производить действия. Если нужно несколько интервалов, то можно несколько переменных и действия выбирать по каждой отдельно и каждую отдельно обнулять.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет. Установить прерывание по "апдейт". Выбрать предустановки чтоб прерывался раз в секунду. В обработчике, вызываемом ежесекундно, инткрементировать переменную и в зависимости от ее значения производить действия. Если нужно несколько интервалов, то можно несколько переменных и действия выбирать по каждой отдельно и каждую отдельно обнулять.

спасибо. выглядит как неплохое решение. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо. выглядит как неплохое решение. :)

 

Рад был оказаться полезен.

 

Посмотрите на RTC. От специально для секундных интервалов предназначен. Да и в порядке освоения пригодится, чтоб таймер под другие задачи высвободить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Рад был оказаться полезен.

 

Посмотрите на RTC. От специально для секундных интервалов предназначен. Да и в порядке освоения пригодится, чтоб таймер под другие задачи высвободить.

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Не нужно настраивать. Он всегда считает с нуля, если питание резервное не делать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...