Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

Время реакции на прерывания в AVR

Отправлено DOOZER 02 декабря 2007 г. 13:21


Помогите разобраться!
Мега169 тактируется от 1МГц. Timer0 используется постоянно для счета времени, прерывания по T0OVF каждую 1 мс. Таймер2 используется для формирования меандра в диапазоне частот от 200 до 4000 Гц с заполенение частотой 125 кГц с переменной скважностью (фактически это однотональный синтезатор нот с ШИМ-регулировкой громкости), т.е. в обработчике T2OVF управляем работой PWM таймера1. В программе всего два обработчика - по переполнению Т0 и Т2. Вот код:

#pragma vector=TIMER0_OVF_vect
__interrupt void timer0_ovf_int(void) // 1 kHz
{
__enable_interrupt();
TCNT0 = 131;
// Разный код
}
//-------------------------------------------------------------------
#pragma vector=TIMER2_OVF_vect
__interrupt void timer2_ovf_int(void)
{
VU8 t;
do
{
t = TCNT2;
}
while (t < 0x40);
TCCR1A_COM1A1 = !TCCR1A_COM1A1;
// нога для контроля меандра
PORTB_PORTB7 = !PORTB_PORTB7;
TCNT2 = 145;
}
//-------------------------------------------------------------------
main()
{
// Всякий код ...

TCCR0A = 0x02; // Counter is clocked from OSC/8
TIMSK0 = 0x01; // Timer0 overflow interrupt enable
// Mode 14 & clkIO/1 (No prescaling)
TCCR1A |= (1< TCCR1B |= ((1< // Clear OC1A on Compare Match, set OC1A at BOTTOM
TCCR1A |= (1< // Замполнение ШИМ
OCR1A = 3;
ICR1 = 7;
// тактируем от 1 МГц
TCCR2A |= (1< // включаем прерывания
TIMSK2 |= (1< __enable_interrupt();
while (1) ;
}

Проблема в том, что не получается исключить (минимизировать) дрожание фронтов низкочастотного меандра на ноге PB7, вызванное наличием обработчика прерывания от таймера0. Если прерывание от Т0 отключить - то меандр становится идеальным. Предположительно, это дрожание вызвано задержкой входа в обработчик прерывания Т2, хотя непонятно, почему эта задержка может увеличиваться, когда вызов обработчика происходит из другого обработчика (T0). По докам время реакции равно 4 такта + 3 на переход + завершение текущей инструкции и, по-видимому, не зависит от того, находимся ли уже в другом обработчике или нет. Единственное объяснение - это когда прерывания происходят одновременно, но прерывания от Т2 имеют больший приоритет. В любом случае для перестраховки от задержки входа в обработчик Т2, уже в нем я отлавливаю определенный момент с предположительным запасом по запозданию входа с помощью этих строк:
do
{
t = TCNT2;
}
while (t < 0x40); // макс время ожидания - 64 мкс

т.е. запас по времени более чем. В таком случае момент обнаружения события (t < 0x40) определен с точность до нескольких мкс (при макс оптимизации компилятора). Однако и в этом случае джиттер не уменьшается и составляет около +/- 20 мкс, что сильно слышно на слух.



Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

если вы незарегистрированный на форуме пользователь, то
для успешного добавления сообщения заполните поле, как указано ниже:
отымите от 2 единицу:

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru