|
Делитель на пинах прерывания? |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 19)
|
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 сделать управляемый низко потребляемый таймер. Т.е. её задача делить входной сигнал на заданное число? Тогда, может поискать просто делитель в интегральном исполнении, наверняка есть такие... тот уж точно глючить не будет, да и с потреблением наверняка будет лучше у него..
--------------------
|
|
|
|
|
Jun 6 2007, 07:25
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Цитата(GDI @ Jun 6 2007, 10:57)  при таком тактировании у вас команды выполняются за 0.5мкс, в среднем, т.е. вы должны укладываться, примерно, в 100 команд на обработку каждого изменения входного сигнала. Можно применить оптимизацию по скорости - это сократит код.
Т.е. её задача делить входной сигнал на заданное число? Тогда, может поискать просто делитель в интегральном исполнении, наверняка есть такие... тот уж точно глючить не будет, да и с потреблением наверняка будет лучше у него.. Нет, это не простой делитель. Основной МК программирует таймер на ATtiny13 (подстройка синхронизации) и «засыпает». При наступлении события от таймера ATtiny13 основной МК «просыпается», отрабатывает положенное и т.д. по циклу. С начала я хотел применить специализированный таймер, но подходящего не нашёл. Нужно работа с частотой 2 – 10 Гц с разрешением не хуже 5 мкс. и с потреблением менее 1 мА. По временам я всё понял, буду считать. Возможно на время обмена уменьшу пред\делитель генератора.
|
|
|
|
|
Jun 6 2007, 08:18
|
Профессионал
    
Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008

|
А зачем внешнее тактирование - от внутреннего генератора нельзя сделать? Т.е. зачем на Тини13 внешние счетные импульсы подавать, не проще ли использовать внутренний клок. Кстати, не знаю как в Тини, а в Мегах есть асинхронный таймер, на который можно подавать внешние счетные импульсы - все будет тогда работать аппаратно... Посмотрел даташит на Тини13 - у её таймера есть возможность внешнего тактирования. Цитата При наступлении события от таймера ATtiny13 основной МК «просыпается» если задача просто считать импульсы - зачем тогда определять прерывание по спаду или по нарастанию? Использовать INT0 по спаду или нарастанию или внешний клок таймера, или вообще внутнренний клок.
--------------------
|
|
|
|
|
Jun 6 2007, 09:39
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Цитата(GDI @ Jun 6 2007, 12:18)  А зачем внешнее тактирование - от внутреннего генератора нельзя сделать? Т.е. зачем на Тини13 внешние счетные импульсы подавать, не проще ли использовать внутренний клок. Кстати, не знаю как в Тини, а в Мегах есть асинхронный таймер, на который можно подавать внешние счетные импульсы - все будет тогда работать аппаратно...
Посмотрел даташит на Тини13 - у её таймера есть возможность внешнего тактирования.
если задача просто считать импульсы - зачем тогда определять прерывание по спаду или по нарастанию? Использовать INT0 по спаду или нарастанию или внешний клок таймера, или вообще внутнренний клок. Нет, не так. ATtiny13 работает сам по себе от внутренней RC цепи. А импульсы это 3-х проводной (или 2-х проводной) интерфейс для управления таймером, основной МК или OCR0A устанавливает или дополнительный программный делитель для увеличения периода выходного сигнала. Аппаратный предделитель таймера использовать не могу, точность снижается. С асинхронным таймером не получается по причине той же низкой точности. INT0 использую только по нарастанию, для PCINT0_vect вариантов нет.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|