Цитата(FREEKER @ Sep 13 2007, 01:25)

Но с таймером мне тоже не всё понятно. Разъясните. Как сделать следующее. Допустим тикает таймер. Нужно остановить его и замерить время по приходу на порт P2.2 логической "1", т.е. по перепаду с 0 на 1. или наоборот.
Ну для этого таймер останавливать не обязательно. Используйте функцию захвата таймера.
Код
#define CAP_TICKOVFCNTR 0x00010000
volatile unsigned long smplTime, smplOvfCntr;
//================================================//
// Инициализация таймера захвата входной частоты //
//------------------------------------------------//
//аргументы :нет //
//возвращает:нет //
//================================================//
void initTimerCAP(void)
{ TACTL=TASSEL_2|ID_0|TAIE|TACLR; //TACLK=SMCLK/1, прерыв. от переполнения
//разрешено
TACCR0=0; //результат захвата
TACCTL0=CM_1|CCIS_1|CAP; //режим захвата по нараст. фронту
//вход захвата CCI0B (P2.2)
P2SEL|=BIT2; //P2.2 - CCI0B
P2DIR&=~BIT2; //P2.2 - вход
TACTL|=MC_2; //пуск в режиме Continous
}
//================================================//
// Запуск таймера сэмплирования //
//------------------------------------------------//
//аргументы :нет //
//возвращает:текущую метку времени //
//================================================//
unsigned long fStartTimerCap(void)
{ unsigned int buf;
TACCTL0=CM_3|CCIS_3|CAP; //режим захвата по любому фронту
//вход захвата=VCC
TACCTL0^=CCIS0; //формируем программно перепад
buf=TACCR0; //получаем текущее значение TAR
TACCTL0=CM_1|CCIS_1|CAP; //режим захвата по нараст. фронту
smplTime=smplOvfCntr+buf; //получим текущую временную метку
TACCTL0|=CCIE; //разрешим прерывание при захвате
return(smplTime);
}
//================================================//
// Обработчик прерывания таймера сэмплирования //
//------------------------------------------------//
//аргументы :нет //
//возвращает:нет //
//================================================//
#pragma vector=TIMERA0_VECTOR
#pragma type_attribute=__interrupt
void TimerA0_ISR(void)
{ unsigned int buf;
buf=TACCTL0; //временная метка захвата
smplTime=smplOvfCntr+buf; //просуммирует с таймером переполнений
TACCTL0&=~CCIE; //сбросим разреш. прерывания захвата
}
//================================================//
// Обработчик прерывания переполнений таймера //
//------------------------------------------------//
//аргументы :нет //
//возвращает:нет //
//================================================//
#pragma vector=TIMERA1_VECTOR
#pragma type_attribute=__interrupt
void TimerA1_ISR(void)
{ switch(TAIV)
{ default:
case 0x02:
case 0x04:
break;
case 0x0A:
smplOvfCntr+=CAP_TICKOVFCNTR; //инкремент счетчика переполнений
break;
}
}
Таймер в моем примере считает постоянно на максимальной частоте SMCLK c переполнением (от 0 до 0xFFFF и дальше). Чтобы расширить измеряемый временной интервал введена 32-битная переменная
smplTime, которая суммируется с 32-битным счетчиком переполнений
smplOvfCntr. Максимальный временной интервал измеряемый при этом может быть вычислен как число 0xFFFFFFFF деленное на значение частоты SMCLK. Для SMCLK=8MHz этот интервал составляет почти 9 минут.
initTimerCAP - функция начальной инициализации ТаймераА
fStartTimerCap - функция запуска периода ожидания срабатывания ловушки перехода 0->1 на входе P2.2. Она возвращает начальную метку времени. После ее запуска нужно ожидать сброса бита разрешения прерывания CCIE в регистре TACCTL0. Сброс бита будет означать, что ловушка сработала и в переменной smplTime мы имеет соответствующую метку времени. Разница между текущим значением smplTime и значением которая вернула функция fStartTimerCap будет искомым интервалом ожидания от момента запуска до срабатывания ловушки. Для пересчета этой величины в привычные секунды smplTime нужно поделить на значение тактирующей частоты SMCLK.
P.S. еще пояснение. "Хитрая" манипуляция в функции fStartTimerCap
Код
TACCTL0=CM_3|CCIS_3|CAP;
TACCTL0^=CCIS0;
обсуловлена тем, что в общем случае MCLK и SMCLK могут быть асинхронными. Например, MCLK от DCO тактируется, а SMCLK от кварцевого генератора. Если при таких условиях попытаться впрямую считать значение TAR без останова таймера, то можно получить неверное значение.