| Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
MSP 430 таймер с перыванием в 10us
19.05.2012, 15:09
|
|
|
Частый гость
Регистрация: 12.01.2011
Сообщений: 14
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 10 сообщении(ях)
|
MSP 430 таймер с перыванием в 10us
Здравствуйте, есть задача срабатывания прерывания таймера раз в 10 микросекунд. После просмотра примеров и поиска в интернете накидал примерный код, однако, не работает, видать что-то не так понял...
|
Код:
|
WDTCTL = WDTPW + WDTHOLD;//watchdog stop
//дальше три строчки как я понял устанавливают частоту проца в 8МГц
SCFI0 |= FN_3; // Set DCO operating range
SCFQCTL = 121; // (121+1) x 32768 x 2 = 7.99 Mhz
FLL_CTL0 = DCOPLUS + XCAP18PF; // DCO+ set so freq = xtal x D x N+1
//Как я понял из примера, здесь мы выбираем источник тактирования для таймера и вроде в этом случае это DCO? Также выбираем режим постоянного счета вверх и нифига не делим )
TACTL = TASSEL_2 + MC_2 + TACLR+ID_0; // Timer setup: SMCLK, cont-mode, clear ID_2--divided by 1
TACCTL1 = CCIE;
//это типа предел, до которого считает таймер и потом генерит прерывание, так?
TACCR1 = 80; |
Ну и вот короче это все у меня не работает... Посмотрите опытным взглядом, где я ошибаюсь... Спасибо!
|
|
|
|
Сказали "Спасибо" kadrilo
|
|
|
19.05.2012, 23:34
|
|
|
Вид на жительство
Регистрация: 10.08.2005
Сообщений: 385
Сказал спасибо: 0
Сказали Спасибо 161 раз(а) в 140 сообщении(ях)
|
Re: MSP 430 таймер с перыванием в 10us
И где здесь прерывания?
|
|
|
|
Сказали "Спасибо" Alecsej
|
|
|
20.05.2012, 06:04
|
|
|
Частый гость
Регистрация: 12.01.2011
Сообщений: 14
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 10 сообщении(ях)
|
Re: MSP 430 таймер с перыванием в 10us
Это? TACCTL1 = CCIE;
а само прерывание код не пишу, там диод моргает просто. И моргает он очень медленно (((
|
|
|
|
Сказали "Спасибо" kadrilo
|
|
|
20.05.2012, 08:36
|
|
|
Частый гость
Регистрация: 12.01.2011
Сообщений: 14
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 10 сообщении(ях)
|
Re: MSP 430 таймер с перыванием в 10us
Итак, еще раз приведу больше кода на этот раз, и изложу свое понимание всего этого, может кто меня поправит...
Итак, конфигурирую проц работать на частоте 8 МГц. Взял из примера TI
|
Код:
|
FLL_CTL0 |= DCOPLUS + XCAP18PF; // DCO+ set, freq = xtal x D x N+1
SCFI0 |= FN_4;
SCFQCTL = 121; |
Далее настраиваю таймер чтобы он работал на частоте SMCLK то есть DCO, это правильно? Также настраиваю чтоб он постоянно считал от нуля до заданного значения(80) и генерил прерывание. Я правильно здесь все понял?
|
Код:
|
CCTL0 = CCIE; // CCR0 interrupt enabled
TACCR1 = 80;
TACTL = TASSEL_2 + MC_2; |
Далее чтобы не заморачиваться на основной цикл оставляю только обработку прерываний:
|
Код:
|
_BIS_SR(LPM0_bits + GIE); |
И вот собственно обработчик прерывания. Смысл в нем такой: каждый раз когда срабатывает прерывание, я увеличиваю переменную counter, с помощью второй переменной lastCounter имею возможность отмерить определенное количество срабатываний прерывания. И изменяю вывод порта, на котором висит светодиод.
|
Код:
|
__interrupt void Timer_A (void)
{
counter++;
if ((counter - lastCounter) › 100)
{
P4OUT ^= 0xFF;
lastCounter = counter;
}
} |
Так вот, при цифре 100, диод моргает примерно 1 раз в секунду. А по моим подсчетам, если он таймер работает на частоте 8МГц, прерывание происходит при достижении значения 80, прерывание должно сработать 8000000/80=100000 раз в секунду, ну и разделим на мои 100 - это тысяча раз в секунду! А у меня получается один раз... Где ошибка, подскажите...
Есть предположение, что после генерации прерывания таймер продолжает инкрементировать значение до какой-то своей верхней границы, а потом опять начинает с нуля. Я попробовал в обработчике прерывания записать в его значение 0, чтобы он каждый раз начинал отсчет с нуля.(TAR = 0  Вообще никакой реакции..
|
|
|
|
Сказали "Спасибо" kadrilo
|
|
|
20.05.2012, 09:14
|
|
|
Частый гость
Регистрация: 12.01.2011
Сообщений: 14
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 10 сообщении(ях)
|
Re: MSP 430 таймер с перыванием в 10us
Опа, нашел где косяки. Настройка таймера(в моем случае) должна выглядеть вот так:
|
Код:
|
TACCTL0 = CCIE;
TACCR0 = 70;
TACTL = TASSEL_2 + MC_1; |
Тепрь другой вопрос - на глаз видно что диод моргает при 100000 срабатываниях прерывания раз в 1.5-2 секунды, а не раз в секунду... Из-за чего может быть? Есть предположение что во время обработки прерывания таймер не тикает, если это так, тогда во время прерывания нужно где-то компенсировать время, которое занимает операция обработки. Это операция инкремента и сравнения. То есть 2 такта мы теряем при обработке. Следовательно, через каждые 80 тактов мы тратим два на обработку, а сколько мы тратим на обработку самого прерывания? Пусть примерно вся эта история занимает 10 тактов проца. Значит, чтобы реально получить то что хотим, пробуем предел таймера установить равным 70.
ХМ все равно расхождение есть.. Есть идеи?
|
|
|
|
Сказали "Спасибо" kadrilo
|
|
|
20.05.2012, 10:10
|
|
|
Частый гость
Регистрация: 12.01.2011
Сообщений: 14
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 10 сообщении(ях)
|
Re: MSP 430 таймер с перыванием в 10us
Методом научного тыка пришел к таким цифрам: порог оставляю тот же - 80, а вот количество прерываний меняю на 50000, то есть в два раза меньше! Почему, пока не понимаю.
|
|
|
|
Сказали "Спасибо" kadrilo
|
|
|
20.05.2012, 10:23
|
|
|
Частый гость
Регистрация: 12.01.2011
Сообщений: 14
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 10 сообщении(ях)
|
Re: MSP 430 таймер с перыванием в 10us
Ну вот, вроде более-менее понятно где утечка ) Из документации:
|
Цитата:
|
|
Время задержки вызова прерывания составляет 6 машинных циклов.... Для возврата из прерывания необходимо 5 машинных циклов
|
ну и на обработку 2
Блин, ну все равно не в два раза...
|
|
|
|
Сказали "Спасибо" kadrilo
|
|
|
20.05.2012, 15:56
|
|
|
Заблокирован
Регистрация: 27.03.2007
Сообщений: 1,327
Сказал спасибо: 12
Сказали Спасибо 576 раз(а) в 460 сообщении(ях)
|
Re: MSP 430 таймер с перыванием в 10us
Ничего компенсировать не надо. Таймер тикает ровно 10мкс вне зависимости от времени обработки прерывания.
Тут дело в следующем. Моргание в данном случае - это включили, пауза, выключили, пауза, включили, пауза и так далее. То есть две паузы на один морг. Вот и получается в два раза медленнее.
Последний раз редактировалось Yurkin2007; 20.05.2012 в 16:02.
|
|
|
|
Сказали "Спасибо" Yurkin2007
|
|
|
21.05.2012, 15:57
|
|
|
Частый гость
Регистрация: 12.01.2011
Сообщений: 14
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 10 сообщении(ях)
|
Re: MSP 430 таймер с перыванием в 10us
Сообщение от Yurkin2007
|
Ничего компенсировать не надо. Таймер тикает ровно 10мкс вне зависимости от времени обработки прерывания.
Тут дело в следующем. Моргание в данном случае - это включили, пауза, выключили, пауза, включили, пауза и так далее. То есть две паузы на один морг. Вот и получается в два раза медленнее.
|
Спасибо за ответ. Но странная вещь получается - я перенес моргание светодиода в основной цикл, то есть в прерывании оставил только инкремент перемнной counter. Так вот - ничего не изменилось, хотя моргание светодиода теперь не влияет на прерывание и изменение переменной counter...
То есть я понимаю так - таймер тикает 80 раз. Происходит прерывание. Счетчик инкрементируется. Далее основному циклу остается как минимум 65 тактов(до следующего прерывания) на проверку счетчика и моргание светодиода, по-моему этого должно за глаза хватать и никак не может влиять на скорость увеличения счетчика(читай скорость моргания диода)...
|
|
|
|
Сказали "Спасибо" kadrilo
|
|
|
21.05.2012, 17:14
|
|
|
Заблокирован
Регистрация: 27.03.2007
Сообщений: 1,327
Сказал спасибо: 12
Сказали Спасибо 576 раз(а) в 460 сообщении(ях)
|
Re: MSP 430 таймер с перыванием в 10us
И потом, почему у Вас такой странный способ использования counter ? Бесконечное инкрементирование ни к чему хорошему не приведёт: переменная не резиновая и в конце концов переполнится. Тогда counter начнёт считать с нуля и ещё долго не обгонит lastCounter ...
Я бы сделал вот так
|
Код:
|
__interrupt void Timer_A (void)
{
counter++;
if (counter › 100)
{
P4OUT ^= 0xFF;
counter = 0;
}
} |
А какова размерность переменной counter?
В 16-битную переменную нелегко засунуть 100000 ...
Последний раз редактировалось Yurkin2007; 21.05.2012 в 17:18.
|
|
|
|
Сказали "Спасибо" Yurkin2007
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 22:42.
|
|