реклама на сайте
подробности

 
 
> Помогите разобраться с таймером, TA работает непредсказуемо
LCD
сообщение Sep 10 2008, 16:31
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 92
Регистрация: 1-06-08
Пользователь №: 37 959



Использую А0 для формирования задержек, а А1 для часов.
Вот так я инициализирую таймер:
Код
  TACCTL0=CCIE;
  TACCTL1=CCIE;
  TACCR1=32767;
  TACTL=TASSEL0+TAIE+MC0;
  //IAR показывает, что TACCTL0=0x418, TACCTL1=0x10

А0 работает так, как от него требуется.
Код
void sleep(unsigned short tacts)
{
  __enable_interrupt();
  TACCR0=tacts;
  __low_power_mode_3();
  TACCR0=0;
}

#pragma vector=TIMERA0_VECTOR
__interrupt void TimerA0_ISR(void)
{
  __low_power_mode_off_on_exit ();
};

А что происходит с А1, я понять не могу: он перестает генерировать прерывания в LPM3. Вроде, все делаю, как написано в исходниках-примерах.
Код
#pragma vector=TIMERA1_VECTOR
__interrupt void TimerA1_ISR(void)
{
  if(TAIV==2)
  {
    (здесь увеличиваем время на секунду)
  }
  P2OUT ^= 0x40; //мигаем светодиодом
}

Помогите разобраться, где здесь ошибка.

Сообщение отредактировал LCD - Sep 10 2008, 17:00
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
rezident
сообщение Sep 10 2008, 18:52
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



У вас как минимум две ошибки.
Во-первых, вы используете режим таймера CountUp (MC0=1, MC1=0) при котором таймер считает вверх (инкрементируется содержимое счетчика TAR) лишь до значения, установленного в TACCR0. После совпадения TAR и TACCR0 счетчик TAR сбрасывается в нуль. Поэтому в режиме CountUp запись в TACCR1 какого либо значения меньшего, чем записано в TACCR0 не дает никакого эффекта. Потому, что при таких условиях (TACCR1>TACCR0) прерывание от совпадения TAR и TACCR1 никогда не наступит.
Во-вторых, в этом режиме запись в TACCT0 нуля дает останов таймера.
В-третьих, у вас присутствует прерывание от переполнения (установлен бит TAIE в TACTL), которое вы не обрабатываете.
Для функций которые вы желаете реализовать таймер должен работать в режиме Continuous - режим счета с переполнением. Поскольку таймер тактируется от часового кварца 32768Гц, то прерывание дважды за период переполнения может вызываться 1) при совпадении какого-либо из CCR и 2) прерыванием от переполнения. Так получем два прерывания за 65536 тактов или период 1 секунду.
Обработчик прерывания выглядит так
Код
#pragma vector=TIMERA1_VECTOR
__interrupt void TimerA1_ISR(void)
{ unsigned int TAIVstate=TAIV;
  switch(TAIVstate)
  { case 0x02:  //прерывания при совпадении TAR и TACCR1
    case 0x0A:  //прерывания при переполнении TAR
      //вызывается дважды за период переполнения (2 с), т.е. с периодом 1 секунда
      //(здесь увеличиваем время на секунду)
      break;
    default:
      break;
  }
  P2OUT ^= 0x40; //мигаем светодиодом
}

Инициализацию таймера делаем так
Код
TACTL=TASSEL0 | TAIE | TACLR;  //здесь разрешаем первый источник прерываний за период
TACCR1=32767;
TACCTL0=0;
TACCTL1=CCIE; //здесь разрешаем второй источник прерываний
TACCTL2=0;
TACTL|=MC1;

Для реализации функции интервальных отсчетов используем TACCR0 как это у вас и задумано. Только не нужно его сбрасывать. Когда вы запускаете интервальный отсчет, то просто возмите текущее значение TAR, добавьте к нему требуемое значение интервала в периодах частоты часового кварца, запишите получившееся число в TACCR0 и разрешите прерывание от совпадения TAR и TACCR0 установкой бита CCIE в TACCTL0, предварительно очистив флаг CCIFG.
Код
void sleep(unsigned int tacts)
{
  TACCTL0=CM0 | CMIS1 | CAP;
  TACCTL0|=CMIS0;
  TACCR0+=tacts;
  TACCTL0=CCIE;
  __bis_SR_register(__SR_CPU_OFF | __SR_SCG0 | __SR_SCG1 | GIE);
  TACCTL0=0;
}

#pragma vector=TIMERA0_VECTOR
__interrupt void TimerA0_ISR(void)
{
  __bic_SR_register_on_exit(__SR_CPU_OFF | __SR_SCG0 | __SR_SCG1);
};

Обращаю особо внимание на три первые строчки функции sleep. Предполагаю, что для MCLK у вас используется DCO, так? Тогда поскольку частоты MCLK=DCO и ACLK=LFXT (используемая для тактирования таймера A) асинхронные, то впрямую считывать TAR нельзя. Прямое чтение TAR может дать неверное значение. Чтобы этого избежать используем режим захвата, сымитировав перепад уровня для его срабатывания. Вот это и реализовано в первых двух строчках. В третьей строке "захваченное" в регистр TACCR0 текущее значение TAR увеличивается на интервал времени, соответствующий требуемому. Естественно интервал не может превышать периода 2 сек или 65536 тактов таймера или увеличению на 0x10000=0x0000, т.к. регистр 16-и разрядный.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- LCD   Помогите разобраться с таймером   Sep 10 2008, 16:31
- - LCD   Спасибо за подробнейшее разъяснение. Вставил ваш к...   Sep 11 2008, 11:47
- - keks9357   вот такой вопрос. нужно что бы каждые 2 секунды б...   Oct 7 2011, 11:04
|- - MrYuran   Цитата(keks9357 @ Oct 7 2011, 15:04) А в ...   Oct 7 2011, 11:58
|- - rezident   Цитата(keks9357 @ Oct 7 2011, 16:04) в че...   Oct 7 2011, 14:28
- - Psych   А после void main() открывающей скобки { точно нет...   Oct 7 2011, 13:14
- - keks9357   1. volatile int n; 2. поменял вектор прерывания TI...   Oct 10 2011, 08:50
- - rezident   А часовой кварц у вас вообще генерит? То бишь ACLK...   Oct 10 2011, 19:19
- - keks9357   спасибо всем заработало. подскажите идейку как с...   Oct 12 2011, 04:57
|- - rezident   Цитата(keks9357 @ Oct 12 2011, 09:57) под...   Oct 12 2011, 13:06
|- - FREEKER   Цитата(rezident @ Oct 12 2011, 17:06) Исп...   Oct 18 2011, 07:18
|- - rezident   Цитата(FREEKER @ Oct 18 2011, 12:18) Я не...   Oct 18 2011, 11:32
- - keks9357   какие вычисления делаете? и зачем прибавлять к сче...   Oct 25 2011, 10:03
|- - rezident   Цитата(keks9357 @ Oct 25 2011, 15:03) зач...   Oct 25 2011, 10:44
- - keks9357   Реализовать при 12МГц задержку в 3 секунды возможн...   Oct 27 2011, 05:57
|- - rezident   Цитата(keks9357 @ Oct 27 2011, 10:57) Реа...   Oct 27 2011, 21:55
- - keks9357   rezident - гуру   Oct 28 2011, 04:55
- - Nathan Stark   Скажите, какой минимальный набор команд нужен, что...   Dec 19 2011, 15:22
|- - rezident   Цитата(Nathan Stark @ Dec 19 2011, 20:22)...   Dec 19 2011, 15:47
- - Nathan Stark   ЦитатаВ железе или в симуляторе? В симуляторе IAR ...   Dec 19 2011, 15:58
|- - ILYAUL   Цитата(Nathan Stark @ Dec 19 2011, 19:58)...   Dec 19 2011, 16:11
- - Nathan Stark   Ага, понятно) Спасибо за помощь) Еще такой вопрос,...   Dec 19 2011, 16:15
- - rezident   Цитата(Nathan Stark @ Dec 19 2011, 21:15)...   Dec 19 2011, 19:42


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th August 2025 - 18:16
Рейтинг@Mail.ru


Страница сгенерированна за 0.01403 секунд с 7
ELECTRONIX ©2004-2016