Цитата(keks9357 @ Oct 27 2011, 10:57)

Реализовать при 12МГц задержку в 3 секунды возможно? если можно пример

Да хоть на 300 секунд.

Примерно так.
CODE
#include <msp430x24x.h>
#include <stdint.h>
#define FREQ_TACLK 12000000UL //TimerA clock frequency
#define LED_OUT (1U<<0) //P1.0 - LED output
#define PULSE_IN (1U<<2) //P1.2 - Pulse Input (CCI1A)
#define DELAY_LEDOUT (FREQ_TACLK*3UL) //Value ticks of TimerA = 3s*12MHz
int main(void)
{ WDTCTL = WDTPW | WDTHOLD;
/* Basic Clock module */
BCSCTL3 = LFXT1S_3;
DCOCTL = CALDCO_12MHZ;
BCSCTL1 = CALBC1_12MHZ | XT2OF;
BCSCTL2 = 0;
/* Port1 input/output */
P1DIR = LED_OUT;
P1SEL = PULSE_IN;
P1OUT = 0;
/* TimerA */
TACTL = TASSEL_2 | TACLR | TAIE;
TACCTL0 = 0;
TACCTL1 = CM_3 | CCIS_0 | SCS | CAP | CCIE;
TACCTL2 = 0;
TACTL |= MC_2;
__enable_interrupt();
for (;;)
{
__bic_SR_register(LPM0_bits);
__no_operation();
}
}
#pragma vector=TIMERA1_VECTOR
#pragma type_attribute=__interrupt
void TIMERA_ISR(void)
{ static uint32_t timeCntr, timeDly;
static uint16_t flag;
uint16_t CCRVal;
switch(TAIV)
{ case 0x02: //TACCR1 vector, capture P1.2
CCRVal=TACCR1;
timeDly=timeCntr + DELAY_LEDOUT + CCRVal;
flag = 1;
TACCTL1 &= ~CCIE;
break;
case 0x04: //TACCR2 vector, compare
P1OUT ^= LED_OUT;
TACCTL2 &= ~CCIE;
TACCTL1 |= CCIE;
break;
case 0x0A: //TAR overflow vector, overflow counter
timeCntr += 1UL<<16;
if (flag != 0)
{ if ((timeDly - timeCntr) < (1UL<<16))
{ CCRVal=(uint16_t)(timeDly - timeCntr);
TACCR2 = CCRVal;
TACCTL2 |= CCIE;
flag = 0;
}
}
break;
default:
break;
}
}
P1.0 - выход, к которому подключен светодиод.
P1.2 - вход управления.
По любому перепаду уровня (1->0 или 0->1) на входе P1.2 через установленное время (в примере - 3 сек) светодиод на выходе P1.0 переключится в противоположное состояние. В это время вход P1.2 нечувствителен к перепадам уровня.
Весь функционал реализован на аппаратуре таймера A.
Используется вход захвата CCI1A (P1.2 для MSP430F24x), перепад на котором вызывает захват (capture) значения TAR и запись его в CCR1. При этом в преывании вычисляется величина временной отметки timeDly, отстоящая от данного события на установленное время задержки (3 сек в отсчетах таймера на частоте 12МГц).
CCR2 используется в режиме сравнения (compare) для более точного задания времени задержки.
Прерывание от переполнения используется для расширения разрядности таймера. По переполнению 32-х разрядный счетчик timeCntr инкрементируется на величину разрядности таймера (65536). При установленном флаге flag текущее значение timeDly сравнивается с временной отметкой timeCntr. Если разница укладывается в разрядность таймера (меньше, чем 65536), то остаток разности заносится в CCR2 и разрешается прерывание при событии совпадения TAR и CCR2.
Далее при наступлении события совпадения TAR и CCR2 в прерывании переключается состояние светодиода на пине P1.0 и вновь активируется вход управления.
Точность установки задержки примерно в 20 тактов, которые можно учесть при ее вычислении.
В этом примере есть один нюанс, влияющий на точность задержки, про который я пока умолчу. Если (тщательно изучая мануал) поймете и правильно сформулируете вопрос, то поясню как эту багу можно обойти.

P.S. в железе не проверялось