keks9357 0 27 октября, 2011 Опубликовано 27 октября, 2011 · Жалоба Реализовать при 12МГц задержку в 3 секунды возможно? если можно пример :laugh: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 27 октября, 2011 Опубликовано 27 октября, 2011 · Жалоба Реализовать при 12МГц задержку в 3 секунды возможно? если можно пример :laugh:Да хоть на 300 секунд. ;) Примерно так. #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. в железе не проверялось :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
keks9357 0 28 октября, 2011 Опубликовано 28 октября, 2011 · Жалоба :excl: rezident - гуру :excl: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nathan Stark 0 19 декабря, 2011 Опубликовано 19 декабря, 2011 · Жалоба Скажите, какой минимальный набор команд нужен, чтобы Таймер А считал в инкрементальном режиме до определенного числа? Исходя из документации делаю так: TACCR0 = 0x100; //Задаем модуль счета таймера TACTL = 0x110; //Задаем MC0 = 1, то есть запускаем счетчик в режиме "вверх", //Задаем TASSEL0 = 1, то есть задаем источник импульсов. Но в итоге регистр TAR никак не меняется. Кажется я чего-то не понимаю Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 19 декабря, 2011 Опубликовано 19 декабря, 2011 · Жалоба Исходя из документации делаю так: TACCR0 = 0x100; //Задаем модуль счета таймера TACTL = 0x110; //Задаем MC0 = 1, то есть запускаем счетчик в режиме "вверх", //Задаем TASSEL0 = 1, то есть задаем источник импульсов. Неправильно. Сначала следует проинициализировать регистры таймера (TASSEL и TACCR0) и только потом запускать счет, установив бит MC0 в TACTL. Т.е. минимально три команды. Хотя я предпочитаю все значащие регистры проинициализировать так, чтобы исключить "случайно возникающие" прерывания (от CCR0, CCR1, CCR2), которые программой не предусмотрены. TACTL = TASSEL0 | TACLR; // ACLK/1 в качестве входного клока, сброс TAR, прерывание от переполнения запрещено TACCR0 = 0x100 - 1; //без единицы, т.к. состояние 0x0000 тоже считается TACCTL0 = 0; //режим сравнения, запрет прерывания от CCR0 TACCTL1 = 0; //режим сравнения, запрет прерывания от CCR1 TACCTL2 = 0; //режим сравнения, запрет прерывания от CCR2 TACTL |= MC0; //запуск счета, режим CountUp Но в итоге регистр TAR никак не меняется. Кажется я чего-то не понимаюВ железе или в симуляторе? В симуляторе IAR периферия не симулируется! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nathan Stark 0 19 декабря, 2011 Опубликовано 19 декабря, 2011 · Жалоба В железе или в симуляторе? В симуляторе IAR периферия не симулируется! Оу! А как же тогда проверить работу алгоритма на логику если нет железа? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 19 декабря, 2011 Опубликовано 19 декабря, 2011 · Жалоба Оу! А как же тогда проверить работу алгоритма на логику если нет железа? Спаять макетку и проверять Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nathan Stark 0 19 декабря, 2011 Опубликовано 19 декабря, 2011 · Жалоба Ага, понятно) Спасибо за помощь) Еще такой вопрос, а в прерывания по таймеру программа тоже заходить не будет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 19 декабря, 2011 Опубликовано 19 декабря, 2011 · Жалоба Еще такой вопрос, а в прерывания по таймеру программа тоже заходить не будет?В симуляторе можно "вручную" имитировать вызов прерываний Simulator -> Forced Interrupt или настроить макрос для симуляции вызова Simulator -> Interrupt Setup. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться