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

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

Вся программа очень большая, привожу только функцию инициализации таймера, и часть прерывания INT7 (+)...

Отправлено bseyur 31 марта 2007 г. 19:09
В ответ на: Ничего не понял. Дай ВЕСЬ C-код, перед кодом поставь <pre>, после кода </pre>, и кратко опиши решаемую задачу отправлено =AVR= 31 марта 2007 г. 18:25

Макросы:
#define T1CompAIntEn     TIMSK,OCIE1A,H
#define T1CompAIntFlag TIFR,OCF1A,H

#define T1Init() TCCR1A=TCCR1C=0;TCNT1=0;TCCR1B=4;OCR1A=0x03AA;TIFR=0x10;_NOP();on(T1CompAIntEn)
#define T1SynhrLaunch() TCNT1=0;TIFR=0x10;_NOP();on(T1CompAIntEn)

Макросы on(xxx) устанавливают выбранный бит в 1. Например: on(T1CompAIntEn) устанавливает бит OCIE1A в регистре TIMSK в 1. Макрос off(xxx) - снимает бит (сбрасывает в 0).

Макрос T1Init() запускаю в начале программы для инициализации таймера 1. Я ранее уже писал, что сегодня заменил таймер2 на таймер1, чтобы найти причну или хотя бы попытаться устранить глюк, но функциональность таймера 1 в моем случае избыточна: требуется лишь отмерять постоянные временные интервалы.
Таймер настраивается таким образом, что через 0,06 секунд после его обнуления должно вызываться прерывание.

Макрос T1SynhrLaunch() перезапускает таймер, обнуляя его счетчик и, на всякий случай снимая флаг его прерывания.

МК принимает стабильный периодический сигнал с внешнего устройства частотой 50 Гц (период 0,02 сек.), и с этой частотой генерируются внешние прерывания INT7 по падающему фронту. Кратко обработчик:

#pragma vector=INT7_vect
__interrupt void INT7_interrupt(void)
{
T1SynhrLaunch(); // Перезапуск таймера ожидания импульса
................
}

Внешний сигнал обнуляет контролирующий таймер с периодичностью 0,02 сек. Таймер должен выдавать прерывание, если в течение 0,06 сек. внешних импульсов не поступало (то есть прерывание INT7 не генерировалось), но не раньше!! На контроллере стоит кварц/тактовый источник 4 МГц, источник тактирования прошит через FUSE-биты.

Кратко обработчик прерывания по компаратору А таймера 1:

#pragma vector=TIMER1_COMPA_vect
__interrupt void TIMER1_COMPA_interrupt(void)
{
TCNT1=0;
................
}

Суть: когда заканчивается обработчик прерывания INT7, немедленно запускается TIMER1_COMPA_interrupt (с предварительным возвратом в основную программу; прямой перескок в обход инструкции RETI исключен).
Внутри прерывания INT7 с таймерами ничего не делается, все прерывания запрещены (бит I в SREG сброшен). Пробовал вставлять обнуление таймера в конец обработчика INT7 - тот же результат.

Через симулятор вижу, что адресация к регистрам идет правильно и в правильном порядке. Флаги прерываний сбрасываю путем записи в них "1".

Вот и думаю-гадаю, в чем проблема. Есть подозрение, что содержимое обработчика INT7 влияет на возникновение прерывания, но доказать или опровергнуть это не могу. Там простые операции работы с памятью и элементарная логика, не связанная с периферией.

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

Ответы


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

Сообщение:

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

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

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

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