У вас как минимум две ошибки.
Во-первых, вы используете режим таймера 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-и разрядный.