Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Делитель на пинах прерывания?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Oleg_IT
ATTiny13. Начал работать с прерываниями на PCINT5..0. Создаётся впечатление, что на входе стоят делители на два. Я прав? Если да, то можно ли их выключит?
bzx
Цитата(Oleg_IT @ Jun 4 2007, 11:52) *
ATTiny13. Начал работать с прерываниями на PCINT5..0. Создаётся впечатление, что на входе стоят делители на два. Я прав? Если да, то можно ли их выключит?

Это как понимать? Т.е. обработчик внешних прерываний срабатывает через раз? Расскажи, как ты дошёл до такого вывода.
Oleg_IT
Скорей всего я чего-то не так понимаю или делаю.
На входе одного из пинов периодически подаются несколько последовательных импульсов, перед этим на другой пин подаю импульс для синхронизации осциллографа. В обработчике прерывания ставлю на третий пин единицу жду около 10 мкс и обнуляю этот пин (всё это для теста). На экране осциллографа должны быть столько импульсов, сколько на входе в пакете. А по факту проходит волна «погашенных» импульсов с четкой двоичной структурой, т.е. чем дальше импульс от синхра тем он реже и на большее время гаснет.
Александр Куличок
Теоретическии, если я не ошибаюсь, импульсов на єкране должно быть в 2 раза больше (если ширина "1" и "0" последоветельных импульсов > 10мкс), т.е. по 1-му на каждое изменеие состояния пина.
Кстати, какая частота работы МК и временные параметры импульсов?
Oleg_IT
Цитата(Александр Куличок @ Jun 4 2007, 16:04) *
Теоретическии, если я не ошибаюсь, импульсов на єкране должно быть в 2 раза больше (если ширина "1" и "0" последоветельных импульсов > 10мкс), т.е. по 1-му на каждое изменеие состояния пина.


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

PS:
- Какая тактовая частота процессора?
- Параметры входного сигнала: частота, длительность 0 и 1?
muravei
Цитата(Oleg_IT @ Jun 4 2007, 14:16) *
перед этим на другой пин подаю импульс для синхронизации осциллографа.

Что-то не очень понятно. Изнутри или снаружи?
Период входных импульсов больше времени обработки прерывания?
Александр Куличок
Цитата
Как я понимаю, прерывание возникает только один раз на один импульс (0, 1, пауза, 0). Или нет?


Прерывание позникает при каждом изменении состояния пина (т.е. и по фронту, и по спаду).
Только контроллеру нужно 4-5 тактов от момента фронта до выставления флага прерывания + еще время на вход в пррерывание и автоматический сброс этого самого флага. Поэтому, если входящие импульсы слишком узкие и частые, то возможен их пропуск контроллером.
Oleg_IT
Цитата(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 то всё нормально.
GDI
Время реакции на INT0 (по даташиту на мега32, в даташите на тини13 не нашел этого), составляет 1 такт, всё что короче не вызывает прерывание, а на PCINT - надо 4 такта - может в этом проблема?
Oleg_IT
Спасибо, нашёл в чем дело, это моя не внимательность.

Но после того как программа заработала правильно, возникли другие вопросы.
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
Параметры сигнала так и не были озвучены. Частота, периоды и т.п.
Oleg_IT
Цитата(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 обрабатывать в основном цикле, получается хуже.
GDI
Цитата
частота генератора 4.8МГц, предделитель 2

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

Т.е. её задача делить входной сигнал на заданное число? Тогда, может поискать просто делитель в интегральном исполнении, наверняка есть такие... тот уж точно глючить не будет, да и с потреблением наверняка будет лучше у него..
Oleg_IT
Цитата(GDI @ Jun 6 2007, 10:57) *
при таком тактировании у вас команды выполняются за 0.5мкс, в среднем, т.е. вы должны укладываться, примерно, в 100 команд на обработку каждого изменения входного сигнала. Можно применить оптимизацию по скорости - это сократит код.

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


Нет, это не простой делитель. Основной МК программирует таймер на ATtiny13 (подстройка синхронизации) и «засыпает». При наступлении события от таймера ATtiny13 основной МК «просыпается», отрабатывает положенное и т.д. по циклу. С начала я хотел применить специализированный таймер, но подходящего не нашёл. Нужно работа с частотой 2 – 10 Гц с разрешением не хуже 5 мкс. и с потреблением менее 1 мА.

По временам я всё понял, буду считать. Возможно на время обмена уменьшу пред\делитель генератора.
GDI
А зачем внешнее тактирование - от внутреннего генератора нельзя сделать? Т.е. зачем на Тини13 внешние счетные импульсы подавать, не проще ли использовать внутренний клок. Кстати, не знаю как в Тини, а в Мегах есть асинхронный таймер, на который можно подавать внешние счетные импульсы - все будет тогда работать аппаратно...

Посмотрел даташит на Тини13 - у её таймера есть возможность внешнего тактирования.

Цитата
При наступлении события от таймера ATtiny13 основной МК «просыпается»
если задача просто считать импульсы - зачем тогда определять прерывание по спаду или по нарастанию? Использовать INT0 по спаду или нарастанию или внешний клок таймера, или вообще внутнренний клок.
Oleg_IT
Цитата(GDI @ Jun 6 2007, 12:18) *
А зачем внешнее тактирование - от внутреннего генератора нельзя сделать? Т.е. зачем на Тини13 внешние счетные импульсы подавать, не проще ли использовать внутренний клок. Кстати, не знаю как в Тини, а в Мегах есть асинхронный таймер, на который можно подавать внешние счетные импульсы - все будет тогда работать аппаратно...

Посмотрел даташит на Тини13 - у её таймера есть возможность внешнего тактирования.

если задача просто считать импульсы - зачем тогда определять прерывание по спаду или по нарастанию? Использовать INT0 по спаду или нарастанию или внешний клок таймера, или вообще внутнренний клок.


Нет, не так. ATtiny13 работает сам по себе от внутренней RC цепи. А импульсы это 3-х проводной (или 2-х проводной) интерфейс для управления таймером, основной МК или OCR0A устанавливает или дополнительный программный делитель для увеличения периода выходного сигнала. Аппаратный предделитель таймера использовать не могу, точность снижается.
С асинхронным таймером не получается по причине той же низкой точности.

INT0 использую только по нарастанию, для PCINT0_vect вариантов нет.
GDI
У нас подобная вещь на Тини12 сделана... ватчдог для пром ПК собственной разработки... интерфейс I2C, управляемое время сброса, хранение серийника в еепроме тини, еще пра фич, прога на асме написана, правда я думаю нет таких требований по точности отсчета времени сброса... Дерзайте - всё должно получиться...
vladimir_orl
поднимаю старую ему...

сейчас работаю с прерываниями PCINT на tiny461.
смотрю в протеусе.

ставлю маску, не ставлю, прерывания идут со всех ног...

наверное глюк протеуса.
самой железки пока нет...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.