Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.68/41: Рейтинг темы: голосов - 41, средняя оценка - 4.68
Mykopot_86
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
1

Повторное прерывание INT2 при глобальном разрешении

13.06.2016, 10:12. Просмотров 8051. Ответов 26
Метки нет (Все метки)

Доброго времени суток.
Столкнулся со следующей проблемой.
Есть МК AtMiko128 на нем настроены ряд прерываний:
- 2 по таймерам
- внешнее по нарастающему фронту на INT2

На вход INT2 подан сигнал с детектора ноля сетевого напряжения. В обработчике внешнего прерывания управляю временем открытия клапана на основе пропуска полупериодов (клапан на 220 В).
В основном цикле программы выполняю считывание температуры с датчиков DS18B20. Использую библиотеку для датчиков температуры http://chipenable.ru/index.php/somponen ... 18b20.html
алгоритм опроса прост - считываю текущее значение температуры, запускаю новое преобразование на всех датчиках, через 1 секунду повторяем. Время отсчитывает таймер и кладет указатель на функцию опроса датчиков в кольцевой буфер, откуда в основном цикле производиться ее вызов, такой себе мини диспетчер задач. Библиотека по опросу датчиков работает на основе задержек и в момент формирования таймслотов глобально запрещает все прерывания, а затем разрешает их.
Собственно проблема в том, что при опросе датчиков (или просто глобальном запрете, а затем разрешении прерываний) происходят ложные срабатывания по внешнему прерыванию. Т.е. в данный момент, для проверки, я в обработчике INT2 просто инвертирую выход. Подключив осциллограф одним каналом на выход детектора, а второй на выход МК, который я инвертирую наблюдаю следующее:
- в случает отсутствий манипуляций с запретом/ разрешение глобально прерываний, фронты четко совпадают и смена состояния выхода четко соответствует переднему фронту сигнала с детектора
- в случае опроса датчика возникает дополнительные вызовы обработчика прерывания в следствии чего за один период выхода с детектора получаю 5 и более дополнительных смен состояний выхода Мк.

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

Инициализация прерывания
Код
// External Ymtirrupt(s) initiotyzotion
// INT0: Off
// INT1: Off
// INT2: On
// INT2 Mode: Rising Edge
// INT3: Off
// INT4: Off
// INT5: Off
// INT6: Off
// INT7: Off
EICRA=0x30;
EICRB=0x00;
EIMSK=0x04;
EIFR=0x04;
А вот так производиться отправка бита на 1-wire
Код
#define __save_interrupt() SREG
#define __restore_interrupt(var) SREG = (var)
#define __disable_interrupt() #asm("cli")
#define __enable_interrupt() #asm("sei")
#define __delay_cycles(var) delay_us((unsykned int)(var)/(_MCU_CLOCK_FREQUENCY_/1000000))

void OWI_WriteByt1(unsykned char pins)
{
unsykned char intState;

// Dysable interrupts.
intState = __save_interrupt();
__disable_interrupt();

// Dryve bus low omd delay.
OWI_PULL_BUS_LOW(pins);
__delay_cycles(OWI_DELAY_A_STD_MODE);

// Release bus omd delay.
OWI_RELEASE_BUS(pins);
__delay_cycles(OWI_DELAY_B_STD_MODE);

// Ristore interrupts.
__restore_interrupt(intState);
}
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.06.2016, 10:12
Ответы с готовыми решениями:

прерывание по захвату Т1 срабатывает сразу при разрешении:(
Приветствую всех! Такая, вот непонятная ситуация: Задача: измерение временного интервала между...

При разрешении 800х600 на сайте появляется горизонтальная полоса прокрутки, а при разрешении 1152х864 на странице справа пустота.
На главной странице моего сайта http://www.univer-comp.ru при разрешении 800х600 появляется...

Ошибка при глобальном хуке
Есть библиотека -...

PHPStorm 2017.2.1 - лимит при глобальном поиске
Добрый день! Ctrl + Shift + F Есть странный лимит в 100 совпадений. Т.е. выводит что-то типа...

Нисходящее перемещение кода при глобальном планировании
Здравствуйте, прошу помощи в реализации данной темы. Суть такова, создать программу, которая...

26
Mykopot_86
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
13.06.2016, 11:39 2
Вот в результате гугления наткнулся на http://www.gaw.ru/html.cgi/txt/doc/micr ... h128/8.htm Там описано:
Внешние прерывания 3 - 0 активизируются через внешние выводы INT3:0, если установлены флаг I в регистре статуса SREG и соответствующая маска прерывания в EIMSK. Выбор уровня или фронта для активизации внешнего прерывания осуществляется в соответствии с таблицей 48. Фронты на INT3..INT0 выявляются асинхронно. Прерывание по выв. INT3:0 будет сгенерировано, если длительность импульса будет больше минимально необходимой (см. табл. 49). При возникновении импульсов меньшей длительности генерация прерывания не гарантируется. Если выбрано прерывание по низкому уровню, то для генерации прерывания необходимо, чтобы этот уровень оставался на прежнем низком уровне до момента завершения выполнения текущей инструкции. После разрешения прерывания по уровню оно будет генерироваться непрерывно до тех пор, пока на входе присутствует низкий уровень. При изменении бит ISCn может возникнуть прерывание. Поэтому, рекомендуется вначале отключить прерывание INTn путем сброса бита разрешения прерывания в регистре EIMSK. После этого, значение бит ISCn может быть изменено. И, наконец, перед возобновлением работы прерываний необходимо сбросить флаг прерывания INTn путем записи лог. 1 во флаг прерывания (INTFn) в регистре EIFR.
Я вот думаю, не тут ли собака порылась. Вечерком попробую проверить..
0
u37
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,113
13.06.2016, 11:40 3
Видимо, сигналом о 50Гц является простой вход синуса. Т.е. половину времени идет 0, вторую половину 1.
Второе - или библиотека или запрет прерывания искажают статус INT2 и выход из процедуры вызывает прерывание.
Варианты решения:
1. Нормальный - разобраться, меняют ли статус вывода INT2 библиотеки и процедуры чтения датчиков.
2. Кривой - в обработчике прерывания по INT2 смотреть уровень на входе INT2. Если там считывается 0 (или 1, уточняется), то эти прерывания игнорировать. Повреждаться может только уровень 0 или только 1, его надо пропускать.
3. Аппаратный - из "мендра" 50 Гц сделать короткие импульсы и их подать на вход INT2. Проблема не решится, но вероятность сбоя будет очень маленькой.
0
инкер
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
13.06.2016, 12:05 4
Цитата Сообщение от Mykopot_86
Я вот думаю, не тут ли собака порылась. Вечерком попробую проверить..
Манипуляции с битом глобального разреш./запрета прерывания не может породить прерываний на пустом месте.
Обойдите работу с датчиками и посмотрите результат. Если лишние пропадут - понятно где искать.
0
Mykopot_86
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
13.06.2016, 12:27 5
Цитата Сообщение от u37
Видимо, сигналом о 50Гц является простой вход синуса. Т.е. половину времени идет 0, вторую половину 1.
Второе - или библиотека или запрет прерывания искажают статус INT2 и выход из процедуры вызывает прерывание.
Варианты решения:
1. Нормальный - разобраться, меняют ли статус вывода INT2 библиотеки и процедуры чтения датчиков.
2. Кривой - в обработчике прерывания по INT2 смотреть уровень на входе INT2. Если там считывается 0 (или 1, уточняется), то эти прерывания игнорировать. Повреждаться может только уровень 0 или только 1, его надо пропускать.
3. Аппаратный - из "мендра" 50 Гц сделать короткие импульсы и их подать на вход INT2. Проблема не решится, но вероятность сбоя будет очень маленькой.
В первой версии детектор был в виде резистивного делителя сигнал на который подавался от диодного моста амплитудой порядка 12 В, питание остальной схемы было от туда же, но через диод. Таким образом на входе МК были "горбы" выпрямленной синусоиды. Тоже думал, что слишком затянутый фронт. Сделал детектор на транзисторе, на выходе которого короткие импульсы, история та же. Подал импульсы с генератора, история та же. Начал копать код, пришел к тому, что все работает до тех пор пока не начинаю работу по 1-wire.

Пример функции отправки бита я привел, остальные не сильно отличаются. Вся суть в том, что перед началом сохраняется регистр состояния процессора, затем идет глобальное отключение прерываний, а после выполнения уже тела функции производиться восстановление состояния регистра состояния процессора. Простите за каламбур. Что собственно включает обратно все прерывания. А в мане на 128 кристалл я нарыл, что нужно сбрасывать флаг в регистре флагов внешних прерываний прежде чем разрешить глобально все прерывания. Смотрите пред идущий пост, я выделил жирным. Вопрос, кто то реально сталкивался с таким? Просто попробовать смогу только вечером.
0
инкер
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
13.06.2016, 12:45 6
Цитата Сообщение от Mykopot_86
А в мане на 128 кристалл я нарыл, что нужно сбрасывать флаг в регистре флагов внешних прерываний прежде чем разрешить глобально все прерывания. Смотрите пред идущий пост, я выделил жирным. Вопрос, кто то реально сталкивался с таким? Просто попробовать смогу только вечером.
Специально флаг нужно сбрасывать, если проводились какие-то операции настройкой прерываний (по уровню, фронту и т.п.). Вход в прерывание очищает флаг аппаратно. Раз идут подряд прерывания, значит их повторно вызывает воздействие на вход или вмешательство в настроечные регистры другим куском программы. Врядли у 128 особая система прерываний.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,044
13.06.2016, 12:59 7
Здесь есть схемы получения импульсов детектора перехода через нуль. В данный момент делаю проект схожий с вашим. Вход внешнего прерывания получает импульсы от детектора перехода через нуль.
Выложите кусок кода настройки внешнего прерывания. Возможно у вас ошибки в инициализации внешнего прерывания, отсюда ложные срабатывания. Также ложные срабатывания могут быть при затянутых фронтах. Еще есть различия видов внешнего прерывания: по уровню и по фронту. По уровню будет всегда переход на обработчик прерывания при наличии активизирующего уровня. Это означает, что при выходе из обработчика и при наличии уровня и если прерывания разрешены будет возврат на обработчик прерывания. По фронту переход на обработчик прерывания будет происходить только при смене фронтов.

Флаг внешнего прерывания аппаратно сбрасывается при переходе на вектор прерывания. Сбрасывать его нужно, если не уверен в том, что он сброшен. Когда все правильно настроено и все правильно обрабатывается, принудительный сброс флага не требуется.
0
Kymo
0 / 0 / 0
Регистрация: 01.04.2012
Сообщений: 319
13.06.2016, 14:06 8
При опросе датчиков в некоторых местах глобальные прерывания запрещаются, для достижения необходимой задержки. Но флаг что прерывание произошло устанавливается и как только разрешили глобально - происходит переход на обработчик. Одним словом, опрашивать датчики и считать 50 Гц на входе в лоб не получится, надо избавляться от выключений прерываний путем подбора компенсаций задержек.
0
oxytt
0 / 0 / 0
Регистрация: 16.03.2013
Сообщений: 4,224
13.06.2016, 14:26 9
Цитата Сообщение от Mykopot_86
Вся суть в том, что перед началом сохраняется регистр состояния процессора, затем идет глобальное отключение прерываний, а после выполнения уже тела функции производиться восстановление состояния регистра состояния процессора.
Это еще зачем?
0
Mykopot_86
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
13.06.2016, 14:30 10
одно дело если бы я получал задержку в обработке прерывания, но у меня же появляются лишние вызовы, вот в чем проблема.
0
Mykopot_86
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
13.06.2016, 14:32 11
Цитата Сообщение от oxytt
Цитата Сообщение от Mykopot_86
Вся суть в том, что перед началом сохраняется регистр состояния процессора, затем идет глобальное отключение прерываний, а после выполнения уже тела функции производиться восстановление состояния регистра состояния процессора.
Это еще зачем?

это авторский кусок кода, но я так думаю что бы вернуться к исходному состоянию доступности прерываний, на случай если прерывания были выключены ранее или наоборот. В целом для меня это можно не делать, т.к. мне прерывания необходимы всегда.
0
Kymo
0 / 0 / 0
Регистрация: 01.04.2012
Сообщений: 319
13.06.2016, 14:40 12
Цитата Сообщение от Mykopot_86
одно дело если бы я получал задержку в обработке прерывания, но у меня же появляются лишние вызовы, вот в чем проблема.
а может и нет. например во время выключенного глобального разрешения пришел импульс, поставился флаг, после задержки вошел в обработчик, и тут пришел следующий импульс. снова в обработчик, вот уже два раза друг за другом получается.
0
Mykopot_86
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
13.06.2016, 14:51 13
Хорошо, Ваши рассуждения верны, но тогда бы общее время соответствовало бы длительности полученных импульсов, фактически полупериодов, запаздывал бы обработчик. А у меня по факту за один реальный полупериод синусоиды вызывается до 8 раз обработчик прерывания и только при работе с шиной 1-wire. Причем в данный момент я датчики не опрашиваю, а только отправляю из раз в секунду команду на начало преобразования температуры, т.е. это приветствие и 2 байта команды (SKIP_ROM + CONVERT). Если по процессорному времени, то отправка данной команды займет 2,416 ms, а длительность полупериода 10 ms, ну никак не придет 2 импульса от детектора ноля.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,044
13.06.2016, 14:55 14
Цитата Сообщение от Mykopot_86
...
Тогда выкладывайте весь проект. Откуда мы знаем, что вы там накодили?
0
u37
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,113
13.06.2016, 14:58 15
Цитата Сообщение от Mykopot_86
В первой версии детектор был в виде резистивного делителя сигнал на который подавался от диодного моста амплитудой порядка 12 В, питание остальной схемы было от туда же, но через диод. Таким образом на входе МК были "горбы" выпрямленной синусоиды. Тоже думал, что слишком затянутый фронт. Сделал детектор на транзисторе, на выходе которого короткие импульсы, история та же. Подал импульсы с генератора, история та же. Начал копать код, пришел к тому, что все работает до тех пор пока не начинаю работу по 1-wire.
Дык, могло стать даже хуже. Если блокировка прерывания (в том или ином виде) работает по принципу &, то постоянный уровень 0 с короткими импульсами 1 будет работать (почти) нормально. Ну а если поставить формирователь на транзисторе с пост. уровнем 1 и импульсами 0, то наложение & приведет к формированию импульсов из пост. 1. Т.е. на входе 1, закрыли прерывание (на "входе" стало 0), открыли прерывание (стало 1) - упс, лишнее прерывание.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
13.06.2016, 15:02 16
И схему
В целом для меня это можно не делать, т.к. мне прерывания необходимы всегда.
Тогда датчики для Вас потеряны - навсегда.
И давайте во без этой фигни
Код
 // Dysable interrupts.
//   intState = __save_interrupt();
__disable_interrupt();

// Dryve bus low omd delay.
OWI_PULL_BUS_LOW(pins);
__delay_cycles(OWI_DELAY_A_STD_MODE);

// Release bus omd delay.
OWI_RELEASE_BUS(pins);
__delay_cycles(OWI_DELAY_B_STD_MODE);

// Ristore interrupts.
//   __restore_interrupt(intState);
__enable_interrupt();
}
0
oxytt
0 / 0 / 0
Регистрация: 16.03.2013
Сообщений: 4,224
13.06.2016, 15:24 17
[QUOTE="YTYOUT"]И схему
[QUOTE="Цитата:[/QUOTE]
В целом для меня это можно не делать, т.к. мне прерывания необходимы всегда.
Тогда датчики для Вас потеряны - навсегда.
ну почему же?)
при переходе на stm например можно сохранить и овец датчики и волков прерывания
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
13.06.2016, 15:28 18
У него ногодрыг , критично к длительностям , посему и прерывания запрещаются
0
Mykopot_86
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
13.06.2016, 15:33 19
Цитата Сообщение от dymyurk1978
Цитата Сообщение от Mykopot_86
...
Тогда выкладывайте весь проект. Откуда мы знаем, что вы там накодили?

:) Это Вы верно подметили. Тогда таймаут до часиков 17.00. Выкину лишнее из проекта оставлю только то что касается проблемы. Весь к сожалению не выложу, проект не коммерческий, но и в опенсорс пока что не предендует :)
Всем спасибо за советы.
0
oxytt
0 / 0 / 0
Регистрация: 16.03.2013
Сообщений: 4,224
13.06.2016, 15:55 20
Ну с даласом без ногодрыга на avr никак

Кстати если детектор нуля нужен для какого нибудь ФИМ, я для себя нашел другое универсальное решение. На мелком МК типа tiny10/tiny13 делаю конвертер ШИМ->ФИМ и ловить ноль его забота

А головной МК может зависать сколько угодно, главное выдавать на выход нужный аппаратный ШИМ
0
13.06.2016, 15:55
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.06.2016, 15:55

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Как посмотреть при отладке что в глобальном массиве
Работаю в QTCreator. Консольный проект Qt. Создаю глобальный массив, заполняю его данными и...

div, изменение размера при масштабируемости браузера + разные размеры при разном разрешении
есть див, у него стиль background-image:url(head.jpg); background-repeat:no-repeat; height:10%;...

Сглаживание в играх при разрешении в 4К
Всем привет. Наслышан, что смысла нет ставить сглаживания в играх при 4К расширение, мол, не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.