Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите разобраться с TIMER_A
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
Left Radio
Возможно ли включить прерывание по переполнению таймера при задействовании PWM ?
Вот код :
Код
  CCR0 = 1024-1;                            // PWM Period
  CCTL1 = OUTMOD_7;                         // CCR1 reset/set
  CCR1 = 250;                               // CCR1 PWM duty cycle
  CCTL2 = OUTMOD_7;                         // CCR2 reset/set
  CCR2 = 128;                               // CCR2 PWM duty cycle
  TACTL = TASSEL_2 + MC_1 + ID_3;


А если сделать так:
Код
  CCR0 = 1024-1;                            // PWM Period
  CCTL1 = OUTMOD_7;                         // CCR1 reset/set
  CCR1 = 250;                               // CCR1 PWM duty cycle
  CCTL2 = OUTMOD_7;                         // CCR2 reset/set
  CCR2 = 128;                               // CCR2 PWM duty cycle
  TACTL = TASSEL_2 + MC_1 + ID_3 + TAIE;
  ...
  __enable_interrupt();
  ...
  ...
  
  // Timer A0 interrupt service routine
  #pragma vector=TIMERA0_VECTOR
  __interrupt void Timer_A0 (void)
  {
    if( !(BIT5 & P2IN) )chanel = 0;
      else chanel = 1;
  }

То попадая в прерывание мк выполняет то что там написано по кругу и из прерывания не выходит. Что я делаю не правильно?
serg_ok
У Вас неверно задан вектор прерывания. Для прерывания по переполнению используется TIMERA1_VECTOR (см. раздел "Timer_A Interrupts" в юзергайде)
Left Radio
Спасибо, просмотрел указанный раздел юзергайда , но так все равно не работает.
Если не включаю PWM то все работает как надо, не получается использовать прерывание по переполнению при задействованном PWM.
VAI
Цитата
CCR0 = 1024-1;
ACTL = TASSEL_2 + MC_1 + ID_3 + TAIE;

01 Режим «вверх»: таймер считает вверх к TACCR0
О каком переполнении может идти речь?
rezident
Цитата(VAI @ Jul 7 2009, 17:14) *
01 Режим «вверх»: таймер считает вверх к TACCR0
О каком переполнении может идти речь?
В этом режиме прерывание от переполнения все равно генерируется, TAIFG устанавливается при переходе от совпадения CCR0->0. См. скриншот из User's Guide.
Проблема скорее всего в том, что топикстартер неправильно обработчик вектора TIMERA1_VECTOR написал (мы-то ведь этот код не видели). TIMERA1_VECTOR расшарен для трех источников прерывания CCR1 CCIFG, CCR2 CCIFG и TAIFG. Поэтому нужно использовать TAIV внутри обработчика так, как это описано в User's Guide.
MrYuran
Цитата(rezident @ Jul 7 2009, 16:07) *
TIMERA1_VECTOR расшарен для трех источников прерывания CCR1 CCIFG, CCR2 CCIFG и TAIFG. Поэтому нужно использовать TAIV внутри обработчика так, как это описано в User's Guide.

Судя по коду, CCR1 и CCR2 прерывания не формируют (выключен CCIE)
Кстати, с CCR0 тоже неочевидно (не видно инициализации CCTL0)

Если всё время сидит в прерывании, значит, либо вызывается TIMERA1_VECTOR и не считывается TBIV (предположительно), соответственно CCIFG остаётся стоять и вызывает прерывание опять.
Ещё возможно, что определён один вектор, а вызывается другой, соответственно программа улетает в неведомую даль. (опять же, предположение)
=DS=
Цитата(MrYuran @ Jul 7 2009, 16:19) *
... не считывается TBIV (предположительно), соответственно CCIFG остаётся стоять и вызывает прерывание опять ...

Очень может быть. Нарывался на это как-то.
rezident
Цитата(MrYuran @ Jul 7 2009, 18:19) *
Если всё время сидит в прерывании, значит, либо вызывается TIMERA1_VECTOR и не считывается TBIV (предположительно), соответственно CCIFG остаётся стоять и вызывает прерывание опять.
Насколько я понял, "все время сидит в прерывании" относится к первому варианту с обработчиком вектора TIMERA0_VECTOR. Считывание TAIV при этом ни при чем, т.к. TACCR0 CCIFG, в отличие от остальных, сбрасывается автоматически при переходе на вектор TIMERA0_VECTOR. Думаю, что дело в другом. Это особенности работы дебаггера C-CPY в IAR. Я такое тоже замечал. Иногда дебаггер все время начинает вылетать в какое-то таймерное прерывание (которое у меня вызывается периодически), несмотря на то, что breakpoint стоит совсем в другом месте. Помогает либо перезапуск, либо последовательность действий: снять все breakpoint, отпустить устройство "в свободный полет" и затем снова установить breakpoint.
А насчет "не считывается TAIV" я уже написал выше
Цитата
нужно использовать TAIV внутри обработчика так, как это описано в User's Guide.
MrYuran
Цитата(rezident @ Jul 7 2009, 17:11) *
Это особенности работы дебаггера C-CPY в IAR. Я такое тоже замечал.

фтопку дебаггер...
я поигрался как-то полчасика, словил пару глюков и с тех пор житаговые ноги свободны rolleyes.gif
Left Radio
Спасибо всем за помощь.

Цитата(rezident)
Поэтому нужно использовать TAIV внутри обработчика так, как это описано в User's Guide.

Так правильно?
Код
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A (void)
{
  switch  (TAIV)      
  {
    case  2: break;                        
    case  4: break;                        
    case 10: P1OUT ^= 0x01;                
             break;                
  }

Если можно обясните почему 2,4,10 ? К чему относятся эти числа?

Цитата(MrYuran)
... не считывается TBIV (предположительно), соответственно CCIFG остаётся стоять и вызывает прерывание опять ...

Как побороть? Сбросить вручную CCIFG не получается.... IAR матерится....
rezident
Цитата(Left Radio @ Jul 7 2009, 22:35) *
Так правильно?
Вполне.
Цитата(Left Radio @ Jul 7 2009, 22:35) *
Если можно обясните почему 2,4,10 ? К чему относятся эти числа?
А вы User's Guide читать не пробовали?
Цитата(Left Radio @ Jul 7 2009, 22:35) *
Как побороть? Сбросить вручную CCIFG не получается.... IAR матерится....
"Вручную" это как? Записью в TAIV? Дык он же read-only! У вас все верно в примере написано, поэтому ничего "вручную" сбрасывать не нужно. Еще раз советую внимательно читать User's Guide. Хотя бы в раздел описания регистров Timer_A загляните.
Left Radio
Цитата(rezident @ Jul 7 2009, 19:48) *
"Вручную" это как? Записью в TAIV? Дык он же read-only! У вас все верно в примере написано, поэтому ничего "вручную" сбрасывать не нужно. Еще раз советую внимательно читать User's Guide. Хотя бы в раздел описания регистров Timer_A загляните.

Спасибо понял, все заработало smile.gif Причиной была моя невнимательность 05.gif
VAI
Цитата
В этом режиме прерывание от переполнения все равно генерируется, TAIFG устанавливается при переходе от совпадения CCR0->0. См. скриншот из User's Guide.

К моему стыду, Вы правы. Недосмотрел.... :-(
rezident
Цитата(VAI @ Jul 7 2009, 23:59) *
К моему стыду, Вы правы. Недосмотрел.... :-(
Стыдиться не нужно. Ошибаться может каждый. Порочным является не само заблуждение, а упорство в отстаивании заблуждения. wink.gif Признание же (тем более публичное) своих ошибок всегда приветствуется!
Извиняюсь за bb-offtopic.gif
MrYuran
Цитата(Left Radio @ Jul 7 2009, 20:35) *
Код
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A (void)
{
  switch  (TAIV)      
  {
    case  2: break;                        
    case  4: break;                        
    case 10: P1OUT ^= 0x01;                
             break;                
  }

Если можно обясните почему 2,4,10 ? К чему относятся эти числа?

первые 2 кейса можно было и не писать, так как они всё равно пустые.
ТАIV определяет, какой сигнал вызвал прерывание TIMERA1_VECTOR.

Очень удобно, что "проградуирован" он через 2.
Можно очень просто организовать таблицу переходов (описано в руководстве), либо в ИАРе есть такая примочка для кейса - Even_in_range(), которая оптимизирует switch/case, если аргумент чётный и входит в ограниченный диапазон. Фактически, формируется та же таблица переходов. В прерывании бывает очень актуально.
rezident
Цитата(MrYuran @ Jul 8 2009, 15:33) *
Можно очень просто организовать таблицу переходов (описано в руководстве), либо в ИАРе есть такая примочка для кейса - Even_in_range(), которая оптимизирует switch/case, если аргумент чётный и входит в ограниченный диапазон. Фактически, формируется та же таблица переходов.
В последних версиях IAR весьма хорошо оптимизирует switch даже без явного указания even_in_range.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.