Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с TIMERом
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
alex_tt
Помогите знающие люди, с прерываниями. Написал подпрграмму для получения задержки в микросекундах, частота 4 МГц.
Ниже привожу фрагмент программы.

void delayMks(unsigned long time)
{
TACTL = 0x00;
TACCR0 = 0x04;
TACCTL0 = CCIE;
TACTL|= MC_1;
unsigned long i;
for (i = time; i > 0; i-- )
{
while (TAIFG)
{
}
}
}

Дело в том, что программа виснет на команде while, бит TAIFG не меняет значание, где ошибка, помогите. Заранее благодарю.
rezident
В регистре TACTL у вас не выбран какой-либо внутренний источник тактирования (SMCLK или ACLK). TACTL=0x00 означает, что входной источник тактирования TACLK.
Кроме того, вы в регистре TACCTL0 разрешаете прерывание от CCR0, но не написали обработчик этого вектора прерывания (TIMERA0_VECTOR). Во-первых, программа будет "улетать" черт знает куда. Во-вторых, флаг TAIFG после первого периода счета от 0 до CCR0 установится и никогда больше не сбросится. Т.к. перехода по вектору прерывания (уже другому - TIMERA1_VECTOR) не будет (прерывание не разрешено), а самостоятельно TAIFG при простом опросе не сбрасывается.
alex_tt
А не могли бы вы выложить хотя бы образец, а то я уже окончательно запутался, как сделать задержку на n микросекунд. Уже перерыл кучу примеров, они все для icc, а для MSP430 IAR они не идут. Заранее большое спасибо.
VAI
Цитата(alex_tt @ Apr 3 2006, 15:14) *
А не могли бы вы выложить хотя бы образец, а то я уже окончательно запутался, как сделать задержку на n микросекунд. Уже перерыл кучу примеров, они все для icc, а для MSP430 IAR они не идут. Заранее большое спасибо.

Код
/* --- sw_del_us() ---------------------------------------------------------------------------------------- **
*  Задержка в us для 6 МГц. Программная. Зависит от свободных ресурсов.
* Предполагается, что идиотскую задержку в 0 мкс никто не задаст!
* -------------------------------------------------------------------------------------------------------- */
void sw_del_us( unsigned int us )
{
  do
  { _NOP(); _NOP(); _NOP();
  } while( --us );
}

/* --- ini_delay() ---------------------------------------------------------------------------------------- **
*  
* -------------------------------------------------------------------------------------------------------- */
void ini_delay( void )
{

// Настроим таймер А
  TACTL = TASSEL_2                      // тактирование от SMCLK
        + ID_0                          // входной делитель 1:1
        + MC_2;                         // Непрерывный режим: таймер считает вверх к 0ffffh
  TACCTL1 = TACCTL2 = CCIE | CCIFG;     // Старт прерывания для милисекундных тиков и клавиатуры
}

/* --- delay_us() ----------------------------------------------------------------------------------------- **
*  Задержка в us. Накладные расходы - около 30 тактов, т.е. при 6МГц - +5us
*  Используем Compare0 таймера А.
* -------------------------------------------------------------------------------------------------------- */
void delay_us( unsigned int us )
{
  if ( us < 7 )
  { sw_del_us( --us );
    return;
  }
  us = ( us * 3 ) / 2;
  for ( TACCR0 = TAR, TACCR0 += us, TACCTL0 = CCIE; TACCTL0 & CCIE; )
   ;
}

/* --- TIMERA0_isr() -------------------------------------------------------------------------------------- **
*  6 * 2  - 0xffec Timer A CC0
*  Compare0 - микросекундные задержки
* -------------------------------------------------------------------------------------------------------- */
#pragma vector=TIMERA0_VECTOR
__interrupt void TIMERA0_isr( void )
{
  TACCTL0 &= ~CCIE;
}
alex_tt
Спасибо большое.
alex_tt
Извините еще раз за мою неопытность, но хотелось бы узнать у знающих людей, как правильно настроить симулятор программы MSP430 IAR? После большой помощи уважаемого VAI, прерывания заработали, но программа не может выйти из цикла.

for ( TACCR0 = TAR, TACCR0 += us, TACCTL0 = CCIE; TACCTL0 & CCIE; )

Пожалуйста будьте любезны.
VAI
А Вы глобальные прерывания разрешили?
Из цикла выйдет, как только сработает прерывание по Compare0 и запретит само себя: TACCTL0 &= ~CCIE; .
Это в цикле и проверяется.
Я симулятором не пользуюсь, как настроить, не знаю.
rezident
В C-CPY
Simulator->Interrupts->Add->TIMERA0_VECTOR
там же выбрать Repeat Interval
Ну и галочки Enable в Simulator->Interrupts расставить.
Не забудьте установить флаг GIE а main-е. Команда _EINT(); или _BIS_SR(GIE);
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.