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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Помогите разобраться с таймером, TA работает непредсказуемо
keks9357
сообщение Oct 27 2011, 05:57
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 27-04-10
Пользователь №: 56 933



Реализовать при 12МГц задержку в 3 секунды возможно? если можно пример laugh.gif
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 27 2011, 21:55
Сообщение #17


Гуру
******

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



Цитата(keks9357 @ Oct 27 2011, 10:57) *
Реализовать при 12МГц задержку в 3 секунды возможно? если можно пример laugh.gif
Да хоть на 300 секунд. wink.gif Примерно так.
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 тактов, которые можно учесть при ее вычислении.
В этом примере есть один нюанс, влияющий на точность задержки, про который я пока умолчу. Если (тщательно изучая мануал) поймете и правильно сформулируете вопрос, то поясню как эту багу можно обойти. sm.gif
P.S. в железе не проверялось laughing.gif
Go to the top of the page
 
+Quote Post
keks9357
сообщение Oct 28 2011, 04:55
Сообщение #18


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 27-04-10
Пользователь №: 56 933



excl.gif rezident - гуру excl.gif
Go to the top of the page
 
+Quote Post
Nathan Stark
сообщение Dec 19 2011, 15:22
Сообщение #19





Группа: Новичок
Сообщений: 6
Регистрация: 25-02-11
Пользователь №: 63 244



Скажите, какой минимальный набор команд нужен, чтобы Таймер А считал в инкрементальном режиме до определенного числа?

Исходя из документации делаю так:
TACCR0 = 0x100; //Задаем модуль счета таймера
TACTL = 0x110; //Задаем MC0 = 1, то есть запускаем счетчик в режиме "вверх",
//Задаем TASSEL0 = 1, то есть задаем источник импульсов.

Но в итоге регистр TAR никак не меняется. Кажется я чего-то не понимаю
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 19 2011, 15:47
Сообщение #20


Гуру
******

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



Цитата(Nathan Stark @ Dec 19 2011, 20:22) *
Исходя из документации делаю так:
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

Цитата(Nathan Stark @ Dec 19 2011, 20:22) *
Но в итоге регистр TAR никак не меняется. Кажется я чего-то не понимаю
В железе или в симуляторе? В симуляторе IAR периферия не симулируется!
Go to the top of the page
 
+Quote Post
Nathan Stark
сообщение Dec 19 2011, 15:58
Сообщение #21





Группа: Новичок
Сообщений: 6
Регистрация: 25-02-11
Пользователь №: 63 244



Цитата
В железе или в симуляторе? В симуляторе IAR периферия не симулируется!


Оу! А как же тогда проверить работу алгоритма на логику если нет железа?
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Dec 19 2011, 16:11
Сообщение #22


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(Nathan Stark @ Dec 19 2011, 19:58) *
Оу! А как же тогда проверить работу алгоритма на логику если нет железа?


Спаять макетку и проверять


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Nathan Stark
сообщение Dec 19 2011, 16:15
Сообщение #23





Группа: Новичок
Сообщений: 6
Регистрация: 25-02-11
Пользователь №: 63 244



Ага, понятно) Спасибо за помощь)
Еще такой вопрос, а в прерывания по таймеру программа тоже заходить не будет?
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 19 2011, 19:42
Сообщение #24


Гуру
******

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



Цитата(Nathan Stark @ Dec 19 2011, 21:15) *
Еще такой вопрос, а в прерывания по таймеру программа тоже заходить не будет?
В симуляторе можно "вручную" имитировать вызов прерываний Simulator -> Forced Interrupt или настроить макрос для симуляции вызова Simulator -> Interrupt Setup.
Go to the top of the page
 
+Quote Post

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

 


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


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