Перейти к содержанию

Делитель на пинах прерывания?

ATTiny13. Начал работать с прерываниями на PCINT5..0. Создаётся впечатление, что на входе стоят делители на два. Я прав? Если да, то можно ли их выключит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Oleg_IT @ Jun 4 2007, 11:52) <{POST_SNAPBACK}>
ATTiny13. Начал работать с прерываниями на PCINT5..0. Создаётся впечатление, что на входе стоят делители на два. Я прав? Если да, то можно ли их выключит?

Это как понимать? Т.е. обработчик внешних прерываний срабатывает через раз? Расскажи, как ты дошёл до такого вывода.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Скорей всего я чего-то не так понимаю или делаю.
На входе одного из пинов периодически подаются несколько последовательных импульсов, перед этим на другой пин подаю импульс для синхронизации осциллографа. В обработчике прерывания ставлю на третий пин единицу жду около 10 мкс и обнуляю этот пин (всё это для теста). На экране осциллографа должны быть столько импульсов, сколько на входе в пакете. А по факту проходит волна «погашенных» импульсов с четкой двоичной структурой, т.е. чем дальше импульс от синхра тем он реже и на большее время гаснет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Теоретическии, если я не ошибаюсь, импульсов на єкране должно быть в 2 раза больше (если ширина "1" и "0" последоветельных импульсов > 10мкс), т.е. по 1-му на каждое изменеие состояния пина.
Кстати, какая частота работы МК и временные параметры импульсов?
Изменено пользователем Александр Куличок

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Александр Куличок @ Jun 4 2007, 16:04) <{POST_SNAPBACK}>
Теоретическии, если я не ошибаюсь, импульсов на єкране должно быть в 2 раза больше (если ширина "1" и "0" последоветельных импульсов > 10мкс), т.е. по 1-му на каждое изменеие состояния пина.


Почему??? Один выходной импульс на один входной. При входе в обработчик прерывания ставлю 1 (нарастающий фронт импульса), перед выходом их него снимаю 1 (спадающий фронт импульса). Как я понимаю, прерывание возникает только один раз на один импульс (0, 1, пауза, 0). Или нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
2 Oleg_IT
Если это тестовая программа, то приведи её.

PS:
- Какая тактовая частота процессора?
- Параметры входного сигнала: частота, длительность 0 и 1?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Oleg_IT @ Jun 4 2007, 14:16) <{POST_SNAPBACK}>
перед этим на другой пин подаю импульс для синхронизации осциллографа.

Что-то не очень понятно. Изнутри или снаружи?
Период входных импульсов больше времени обработки прерывания?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата
Как я понимаю, прерывание возникает только один раз на один импульс (0, 1, пауза, 0). Или нет?


Прерывание позникает при каждом изменении состояния пина (т.е. и по фронту, и по спаду).
Только контроллеру нужно 4-5 тактов от момента фронта до выставления флага прерывания + еще время на вход в пррерывание и автоматический сброс этого самого флага. Поэтому, если входящие импульсы слишком узкие и частые, то возможен их пропуск контроллером.
Изменено пользователем Александр Куличок

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(bzx @ Jun 4 2007, 16:17) <{POST_SNAPBACK}>
2 Oleg_IT
Если это тестовая программа, то приведи её.

PS:
- Какая тактовая частота процессора?
- Параметры входного сигнала: частота, длительность 0 и 1?

Программу дам завтра, сейчас увы, не получится.
Частота 4.8 MHz с предделителем на 16 (может уменьшу до 8)
Все длительности устанавливаю сам, менял в широких пределах.


Цитата(muravei @ Jun 4 2007, 16:25) <{POST_SNAPBACK}>
Что-то не очень понятно. Изнутри или снаружи?
Период входных импульсов больше времени обработки прерывания?


Согласен, не точно сказал. Синхроимпульс идёт вместе со штатными импульсами из другого МК (ATMega32).

Цитата(Александр Куличок @ Jun 4 2007, 16:35) <{POST_SNAPBACK}>
Прерывание позникает при каждом изменении состояния пина (т.е. и по фронту, и по спаду).
Только контроллеру нужно 4-5 тактов от момента фронта до выставления флага прерывания + еще время на вход в пррерывание и автоматический сброс этого самого флага. Поэтому, если входящие импульсы слишком узкие и частые, то возможен их пропуск контроллером.


Но даже если это и так, то наблюдаемый эффект (скорей дефект) не понятен.


Ещё одно обстоятельство не отметил, если работаю с INT0 то всё нормально.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Время реакции на INT0 (по даташиту на мега32, в даташите на тини13 не нашел этого), составляет 1 такт, всё что короче не вызывает прерывание, а на PCINT - надо 4 такта - может в этом проблема?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Спасибо, нашёл в чем дело, это моя не внимательность.

Но после того как программа заработала правильно, возникли другие вопросы.
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)
{
}
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата
1. При уменьшении времен характеризующих импульсы происходит не прореживание, а уменьшение их количества.

Контроллер и Ваша программа просто не успевает среагировать на все переходы. Если импульс, например, 0>1>0 достаточно короткий, и второй переход 1>0 возникает до того, как начнется прерывание по обработке 1-го перехода 0>1 (т.е., будет сброшен "старый" флаг прерывания), то он просто "проглотится" контроллером. (Что, в принципе, справедливо для всех типов прерываний).

Цитата
2. Как понять по фронту или спаду возникло прерывание на PCINT? Чтением значения соответствующего пина? Соответственно, если задействовано несколько PCINT, как понять с какого пина пришло прерывание? Так же?

Да. Для нескольких PCINT нужно будет сохранять предыдущее состояние и анализировать все PCINT-пины, так как одновременное или близкое во времени изменения состояния разных пинов даст только 1 прерывание.

Цитата
3. Для того, что бы обработчик срабатывал не два раза на один импульс, а один делаю программный фильтр
....
Деление должно быть на два, а по факту делится на 4, без этого фрагмента на выходе 16 импульсов, с ним 4 (на входе всегда 8).

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

З.Ы. Желательно, чтобы Вы описали цель вашей задачи. Вероятнее всего, PCINT - это не то, что Вам нужно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Параметры сигнала так и не были озвучены. Частота, периоды и т.п.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(GDI @ Jun 5 2007, 17:55) <{POST_SNAPBACK}>
Параметры сигнала так и не были озвучены. Частота, периоды и т.п.


На стороне приёмника импульсов (ATtiny13), частота генератора 4.8МГц, предделитель 2. На стороне источника импульсов (ATMega32) так: установка 1, задержка 50 мкс, установка 0, задержка 50 мкс, … Работает.

Цитата(Александр Куличок @ Jun 5 2007, 17:28) <{POST_SNAPBACK}>
Контроллер и Ваша программа просто не успевает среагировать на все переходы. Если импульс, например, 0>1>0 достаточно короткий, и второй переход 1>0 возникает до того, как начнется прерывание по обработке 1-го перехода 0>1 (т.е., будет сброшен "старый" флаг прерывания), то он просто "проглотится" контроллером. (Что, в принципе, справедливо для всех типов прерываний).


Да. Для нескольких PCINT нужно будет сохранять предыдущее состояние и анализировать все PCINT-пины, так как одновременное или близкое во времени изменения состояния разных пинов даст только 1 прерывание.


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

З.Ы. Желательно, чтобы Вы описали цель вашей задачи. Вероятнее всего, PCINT - это не то, что Вам нужно.


Я понял, что МК не успевает обрабатывать запросы, но мне казалось, что на выходе ATtiny13 частота должна уменьшаться, а она остаётся той же.

Задача из ATtiny13 сделать управляемый низко потребляемый таймер. В общем получилось. Но есть некоторые сбои. Я думаю, что это идёт наложение прерываний от таймера и от пинов.
INT0_vect соединён с CS, PCINT0_vect с CLOCK. Пробовал CS или CLOCK обрабатывать в основном цикле, получается хуже.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата
частота генератора 4.8МГц, предделитель 2

при таком тактировании у вас команды выполняются за 0.5мкс, в среднем, т.е. вы должны укладываться, примерно, в 100 команд на обработку каждого изменения входного сигнала. Можно применить оптимизацию по скорости - это сократит код.
Цитата
Задача из ATtiny13 сделать управляемый низко потребляемый таймер.

Т.е. её задача делить входной сигнал на заданное число? Тогда, может поискать просто делитель в интегральном исполнении, наверняка есть такие... тот уж точно глючить не будет, да и с потреблением наверняка будет лучше у него..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация