|
Делитель на пинах прерывания? |
|
|
|
Jun 4 2007, 08:07
|

Местный
  
Группа: Свой
Сообщений: 482
Регистрация: 5-07-05
Из: Санкт-Петербург
Пользователь №: 6 528

|
Цитата(Oleg_IT @ Jun 4 2007, 11:52)  ATTiny13. Начал работать с прерываниями на PCINT5..0. Создаётся впечатление, что на входе стоят делители на два. Я прав? Если да, то можно ли их выключит? Это как понимать? Т.е. обработчик внешних прерываний срабатывает через раз? Расскажи, как ты дошёл до такого вывода.
--------------------
Для связи email: info собака qbit.su
|
|
|
|
|
Jun 4 2007, 12:13
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Цитата(Александр Куличок @ Jun 4 2007, 16:04)  Теоретическии, если я не ошибаюсь, импульсов на єкране должно быть в 2 раза больше (если ширина "1" и "0" последоветельных импульсов > 10мкс), т.е. по 1-му на каждое изменеие состояния пина. Почему??? Один выходной импульс на один входной. При входе в обработчик прерывания ставлю 1 (нарастающий фронт импульса), перед выходом их него снимаю 1 (спадающий фронт импульса). Как я понимаю, прерывание возникает только один раз на один импульс (0, 1, пауза, 0). Или нет?
|
|
|
|
|
Jun 4 2007, 12:35
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Цитата Как я понимаю, прерывание возникает только один раз на один импульс (0, 1, пауза, 0). Или нет? Прерывание позникает при каждом изменении состояния пина (т.е. и по фронту, и по спаду). Только контроллеру нужно 4-5 тактов от момента фронта до выставления флага прерывания + еще время на вход в пррерывание и автоматический сброс этого самого флага. Поэтому, если входящие импульсы слишком узкие и частые, то возможен их пропуск контроллером.
Сообщение отредактировал Александр Куличок - Jun 4 2007, 12:41
|
|
|
|
|
Jun 4 2007, 12:41
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Цитата(bzx @ Jun 4 2007, 16:17)  2 Oleg_IT Если это тестовая программа, то приведи её.
PS: - Какая тактовая частота процессора? - Параметры входного сигнала: частота, длительность 0 и 1? Программу дам завтра, сейчас увы, не получится. Частота 4.8 MHz с предделителем на 16 (может уменьшу до 8) Все длительности устанавливаю сам, менял в широких пределах. Цитата(muravei @ Jun 4 2007, 16:25)  Что-то не очень понятно. Изнутри или снаружи? Период входных импульсов больше времени обработки прерывания? Согласен, не точно сказал. Синхроимпульс идёт вместе со штатными импульсами из другого МК (ATMega32). Цитата(Александр Куличок @ Jun 4 2007, 16:35)  Прерывание позникает при каждом изменении состояния пина (т.е. и по фронту, и по спаду). Только контроллеру нужно 4-5 тактов от момента фронта до выставления флага прерывания + еще время на вход в пррерывание и автоматический сброс этого самого флага. Поэтому, если входящие импульсы слишком узкие и частые, то возможен их пропуск контроллером. Но даже если это и так, то наблюдаемый эффект (скорей дефект) не понятен. Ещё одно обстоятельство не отметил, если работаю с INT0 то всё нормально.
|
|
|
|
|
Jun 5 2007, 05:01
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Спасибо, нашёл в чем дело, это моя не внимательность.
Но после того как программа заработала правильно, возникли другие вопросы. 1. При уменьшении времен характеризующих импульсы происходит не прореживание, а уменьшение их количества. 2. Как понять по фронту или спаду возникло прерывание на PCINT? Чтением значения соответствующего пина? Соответственно, если задействовано несколько PCINT, как понять с какого пина пришло прерывание? Так же? 3. Для того, что бы обработчик срабатывал не два раза на один импульс, а один делаю программный фильтр BitN++; if (BitN & 1) return; или BitN ^= 1; if (BitN & 1) return; Деление должно быть на два, а по факту делится на 4, без этого фрагмента на выходе 16 импульсов, с ним 4 (на входе всегда 8).
Код тестовой программы
#include <ioavr.h> #include <inavr.h>
#define CS PINB_Bit1 #define CLOCK PINB_Bit2 #define DATA PINB_Bit3 #define OUT_TIM PORTB_Bit0
unsigned char Nbit = 0; struct { unsigned SetBit : 1; unsigned WriteData : 1; unsigned ResetData : 1; };
#pragma vector = PCINT0_vect __interrupt void PCINT0_(void) { BitN++; if (BitN & 1) return; OUT_TIM = 1; OUT_TIM = 0; }
#pragma vector = INT0_vect __interrupt void INT0_(void) { BitN = 0; }
void main( void ) { CLKPR = (1 << CLKPCE); CLKPR = (1 << CLKPS2);
SetBit = 1; WriteData = 0; ResetData = 1;
GIMSK |= (1 << INT0) | (1 << PCIE); PCMSK |= (1 << PCINT2); MCUCR |= (1 << ISC00) | (1 << ISC01);
DDRB = 0x11; // 01 0001 PORTB = 0x2E; // 10 1110 __enable_interrupt();
OUT_TIM = 1; while (1) { } }
|
|
|
|
|
Jun 5 2007, 13:28
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Цитата 1. При уменьшении времен характеризующих импульсы происходит не прореживание, а уменьшение их количества. Контроллер и Ваша программа просто не успевает среагировать на все переходы. Если импульс, например, 0>1>0 достаточно короткий, и второй переход 1>0 возникает до того, как начнется прерывание по обработке 1-го перехода 0>1 (т.е., будет сброшен "старый" флаг прерывания), то он просто "проглотится" контроллером. (Что, в принципе, справедливо для всех типов прерываний). Цитата 2. Как понять по фронту или спаду возникло прерывание на PCINT? Чтением значения соответствующего пина? Соответственно, если задействовано несколько PCINT, как понять с какого пина пришло прерывание? Так же? Да. Для нескольких PCINT нужно будет сохранять предыдущее состояние и анализировать все PCINT-пины, так как одновременное или близкое во времени изменения состояния разных пинов даст только 1 прерывание. Цитата 3. Для того, что бы обработчик срабатывал не два раза на один импульс, а один делаю программный фильтр .... Деление должно быть на два, а по факту делится на 4, без этого фрагмента на выходе 16 импульсов, с ним 4 (на входе всегда 8). Видимо, это опять же связано с тем, что контроллер не успевает отработать код прерывания из-за увеличения времени обработки прерывания и частого чередования импульсов. З.Ы. Желательно, чтобы Вы описали цель вашей задачи. Вероятнее всего, PCINT - это не то, что Вам нужно.
|
|
|
|
|
Jun 6 2007, 04:44
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Цитата(GDI @ Jun 5 2007, 17:55)  Параметры сигнала так и не были озвучены. Частота, периоды и т.п. На стороне приёмника импульсов (ATtiny13), частота генератора 4.8МГц, предделитель 2. На стороне источника импульсов (ATMega32) так: установка 1, задержка 50 мкс, установка 0, задержка 50 мкс, … Работает. Цитата(Александр Куличок @ Jun 5 2007, 17:28)  Контроллер и Ваша программа просто не успевает среагировать на все переходы. Если импульс, например, 0>1>0 достаточно короткий, и второй переход 1>0 возникает до того, как начнется прерывание по обработке 1-го перехода 0>1 (т.е., будет сброшен "старый" флаг прерывания), то он просто "проглотится" контроллером. (Что, в принципе, справедливо для всех типов прерываний).
Да. Для нескольких PCINT нужно будет сохранять предыдущее состояние и анализировать все PCINT-пины, так как одновременное или близкое во времени изменения состояния разных пинов даст только 1 прерывание.
Видимо, это опять же связано с тем, что контроллер не успевает отработать код прерывания из-за увеличения времени обработки прерывания и частого чередования импульсов.
З.Ы. Желательно, чтобы Вы описали цель вашей задачи. Вероятнее всего, PCINT - это не то, что Вам нужно. Я понял, что МК не успевает обрабатывать запросы, но мне казалось, что на выходе ATtiny13 частота должна уменьшаться, а она остаётся той же. Задача из ATtiny13 сделать управляемый низко потребляемый таймер. В общем получилось. Но есть некоторые сбои. Я думаю, что это идёт наложение прерываний от таймера и от пинов. INT0_vect соединён с CS, PCINT0_vect с CLOCK. Пробовал CS или CLOCK обрабатывать в основном цикле, получается хуже.
|
|
|
|
|
Jun 6 2007, 06:57
|
Профессионал
    
Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008

|
Цитата частота генератора 4.8МГц, предделитель 2 при таком тактировании у вас команды выполняются за 0.5мкс, в среднем, т.е. вы должны укладываться, примерно, в 100 команд на обработку каждого изменения входного сигнала. Можно применить оптимизацию по скорости - это сократит код. Цитата Задача из ATtiny13 сделать управляемый низко потребляемый таймер. Т.е. её задача делить входной сигнал на заданное число? Тогда, может поискать просто делитель в интегральном исполнении, наверняка есть такие... тот уж точно глючить не будет, да и с потреблением наверняка будет лучше у него..
--------------------
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|