Обсуждаем контроллеры компании Atmel.
Ответить

attiny13 и PCINT0 в железе

Вт мар 16, 2021 19:17:33

Собственно суть проблемы. К ногам тиньки 5 и 6 (РВ0 и РВ1) подключены две кнопки. Инициализированы прерывания PCINT0 и, в качестве источника прерываний, определены две ноги:


В обработчике прерывания определяю какая кнопка нажата и выполняю нужный код

в симулятора 7 студии все отрабатывает без вопросо. Но в железе у меня получается бесконечный цикл вызова прерыания, при этом виновником является вход РВ1 (BUTTON_LUX_MEMORY). Если програмно я не определяю этот вход как источник прерывания (PCMSK |= (1<<BUTTON_SYGNAL);), то кнопка на РВ0 (BUTTON_SYGNAL) работает без нареканий. Заходим в прерывание, выполняем нужное действие, возвращаемся в основной цикл.
Осциллограмма на РВ1 в норме, напряжение питания стоит, никаких дерганий уровня не видно.
Может у кого есть идеи, в какую сторону копать?

Re: attiny13 и PCINT0 в железе

Вт мар 16, 2021 20:43:59

Код:
   GIMSK &= ~(1<<PCIE);      //запрещаем прерывания
   GIFR |= (1<<INTF0) | (1<<PCIF);         // сброс флагов прерывания

Это - лишнее. Прерывания глобально и так запрещаются при входе в ISR, а флаг прерывания сбрасывается по выходу.
Вы нигде PB1 не дергаете случаем из программы? Ну вот, например, чему равно LED_OUT_PIN?
Ну и чтение АЦП и запись в EEPROM из ISR - очень плохая идея. В прерывании просто поднимайте флаг (переменная), что надо это сделать. А сам замер + запись делайте в основном коде. Там уже предварительно перед записью в EEPROM отключив временно глобально прерывания через cli(), а потом включив через sei().

Re: attiny13 и PCINT0 в железе

Вт мар 16, 2021 20:51:34

NStorm,
Код:
#define  LED_OUT_PIN PB3         //выход на светодиоды


что прерывания глобально запрещаются, а флаги сбрасываются -- знаю. Но вряд-ли эти строки загоняют контроллер в цикл с прерываниями. Но для красоты кода -- уберу.
Т.е. вы считаете, что в цикл падаю из-за чтения adc и записи в eeprom ? Ок, как рабочую версию приму, проверю. Спасибо

Re: attiny13 и PCINT0 в железе

Вт мар 16, 2021 21:23:33

а флаг прерывания сбрасывается по выходу.

При входе в обработчик.

Re: attiny13 и PCINT0 в железе

Вт мар 16, 2021 21:25:42

Вообще-то обрабатывать прерывание одну секунду - это, имхо, явно не хорошо.

Re: attiny13 и PCINT0 в железе

Вт мар 16, 2021 21:30:00

В тиньке13 PCINT на что реагирует? На смену уровня или на уровень? Если на уровень, то так и не будете вылезать из прерывания, пока не сменится уровень на ноге.

Добавлено after 1 minute 30 seconds:
Вообще-то обрабатывать прерывание одну секунду - это, имхо, явно не хорошо.

Если прерывание одно, то по фигу. Можно из него вообще не вылезать. Да даже если и не одно. Как в MSP430...

Re: attiny13 и PCINT0 в железе

Вт мар 16, 2021 21:33:59

Вообще-то обрабатывать прерывание одну секунду - это, имхо, явно не хорошо.

аргументируйте, плз.

Добавлено after 2 minutes 24 seconds:
В тиньке13 PCINT на что реагирует? На смену уровня или на уровень? Если на уровень, то так и не будете вылезать из прерывания, пока не сменится уровень на ноге.

PCINT реагирует на любое изменение уровня на ноге.

Re: attiny13 и PCINT0 в железе

Вт мар 16, 2021 21:51:40

Land писал(а):
В тиньке13 PCINT на что реагирует? На смену уровня или на уровень?

Только на смену.


Land писал(а):аргументируйте, плз.

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

Land писал(а):Т.е. вы считаете, что в цикл падаю из-за чтения adc и записи в eeprom ? Ок, как рабочую версию приму, проверю. Спасибо

Это не может быть прямой причиной, но вот много всяких граблей бывает из-за долгой обработки прерывания. Лучше сразу привыкайте никогда так не делать, даже когда кажется, что в данном случае неважно.
Опять же в read_adc() и при работе с LUX_IN_PIN нигде не можете затрагивать скажем весь регистр PORTB? Случайно где-нибудь вместо R-M-W сделали присваивание может... Ну или приведите весь код в конце концов.

Re: attiny13 и PCINT0 в железе

Вт мар 16, 2021 22:01:37

А я вот вижу сброс вачдога, сброс флага INT0....либо это сделано со знанием дела, но сия тайна великая есть, либо это откуда-то "нахапано" кусками. Пока я склоняюсь к версии
затрагивать скажем весь регистр PORTB?


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

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

Re: attiny13 и PCINT0 в железе

Вт мар 16, 2021 22:09:27

Опять же в read_adc() и при работе с LUX_IN_PIN нигде не можете затрагивать скажем весь регистр PORTB? Случайно где-нибудь вместо R-M-W сделали присваивание может... Ну или приведите весь код в конце концов.

я же не случайно написал, что программное отключение генерации прерывания по РВ1 убирает проблему. Если бы где-то затрагивался весь регистр PORTB, то...

Добавлено after 3 minutes 53 seconds:
А я вот вижу сброс вачдога, сброс флага INT0....либо это сделано со знанием дела, но сия тайна великая есть, либо это откуда-то "нахапано" кусками. Пока я склоняюсь к версии
затрагивать скажем весь регистр PORTB?

думаете wdr зацикливает в прерывании? Или сброс флага INT0 вызывает сбой? Само-собой, как у каждого, у меня есть свои куски кода и я пользуюсь копи-пастом... пока объем памяти позволяет. Если не позволяет -- перехожу на asm.

Re: attiny13 и PCINT0 в железе

Вт мар 16, 2021 22:10:39

Глянул даташит и понял
PB1 (MISO/AIN1/OC0B/INT0/PCINT1)

По умолчанию INT0 сидит на прерывании по уровню. Если разрешить на INT0 прерывание, то, как я и говорил, из прерывания вылезать не будем при нуле на этом пине. Если обработчика вообще нет, то компилятор GCC выполнение кода по вектору уводит на ресет...

Re: attiny13 и PCINT0 в железе

Ср мар 17, 2021 00:52:13

Собственно суть проблемы. К ногам тиньки 5 и 6 (РВ0 и РВ1) подключены две кнопки. Инициализированы прерывания PCINT0 и, в качестве источника прерываний, определены две ноги:

Попробуй… прошивка для тини13… кнопки на РВ0 и РВ1… светики на РВ3 и РВ4…
Фьюзы прошивать не нужно, тактируется на заводских установках (1,2 МГц).
Test_INT.hex

Нажал кнопку – светик загорелся. Нажал повторно – потух.

Re: attiny13 и PCINT0 в железе

Ср мар 17, 2021 05:30:43

я же не случайно написал, что программное отключение генерации прерывания по РВ1 убирает проблему. Если бы где-то затрагивался весь регистр PORTB, то...

То что "то"? То нет. Вы можете остальные пины и не менять, программа по другим пинам будет как надо работать.

parovoZZ писал(а):Это кто-то придумал, а другие тупо скопипастили. Старые тиньки никак не предназначены для обработки прерывания вне его - флаги сбрасываются в прерывании, поэтому надо свои вводить, если обработчик пустой. Либо же лупом проверять флаги постоянно...Вообщем, костыльные микры...

Не совсем. Это стандартная практика. Никаких проблем нет вести свои флаги, их можно вполне расширить и не просто тупо копировать о срабатывании прерывания. Дело не в этом.

Re: attiny13 и PCINT0 в железе

Ср мар 17, 2021 07:49:49

1 - кнопки это человекоинтерфейс. Реакция человека десятки, сотни миллисекунд. Реакция микроконтроллера, если кнопка повешана на прерывание - несколько тактов. Хочется спросить, куда вы так торопитесь, все равно не успеете.
На прерывание есть смысл вешать кнопки только в случае энергосбережения, спящего режима. Ещё в случае экономии ввода вывода. И то варианты.
2 - дребезг контактов.
3 - режим внешнего прерывания, по уровню или фронту.
Как здесь уже правильно подметили, могут быть неучтенные отложенные прерывания.
Вывод, разберитесь что такое дребезг контактов. Какие режимы внешнего прерывания, как правильно инициализировать внешние прерывания. И нужно ли вешать кнопки на внешние прерывания, если нет энергосбережения.

Re: attiny13 и PCINT0 в железе

Ср мар 17, 2021 08:49:19

Разрешать прерывания логическим ИЛИ не совсем хорошо. Как вариант, простое повторение состояния кнопок с жестким разрешением прерывания PCINT

Re: attiny13 и PCINT0 в железе

Ср мар 17, 2021 09:37:58

Дело не в этом.

А в чём же?
В прерывании засыпать нельзя, иначе можешь не проснуться. Но это только в AVR. В других МК позволяется всё.

Re: attiny13 и PCINT0 в железе

Ср мар 17, 2021 11:38:09

я же не случайно написал, что программное отключение генерации прерывания по РВ1 убирает проблему. Если бы где-то затрагивался весь регистр PORTB, то...

То что "то"? То нет. Вы можете остальные пины и не менять, программа по другим пинам будет как надо работать.

то, что если бы что-то писалось в PORB тупо в лоб, то это бы вызывало в том числе и прерывание по PB0. А здесь проблема в РВ1. POTB упоминается в коде 7 раз:
Код:
PORTB |= (1<<BUTTON_LUX_MEMORY) | (1<<BUTTON_SYGNAL); //входы кнопок (инициализация)
PORTB &= ~(1<<LED_OUT_PIN);
PORTB |= (1<<LED_OUT_PIN);
PORTB &= ~(1<<LED_OUT_PIN);
PORTB |= (1<<LED_OUT_PIN);
PORTB &= ~(1<<LED_OUT_PIN);
PORTB &= ~(1<<LED_OUT_PIN);

Что самое забавное, зацикливание происходит даже при простой инициализации входа PB1 в качестве источника прерывания. В обработчике ISR можно вообще все закомментить, относящееся к обработке этого пина. Если кому не лень в чужом коде колупаться, листинг под катом. Ткните меня носом. Только, умоляю, не в wdr :)


Добавлено after 5 minutes 8 seconds:
Разрешать прерывания логическим ИЛИ не совсем хорошо. ]

вы говорите, что в регистр GINSK нельзя писать через "или"? Откровенно в первый раз об этом слышу. Ну и потом, для пина PB0 такая конструкция работает. Попробовать 6 ногу лучше пропаять?..

Re: attiny13 и PCINT0 в железе

Ср мар 17, 2021 11:53:43

вы говорите, что в регистр GINSK нельзя писать через "или"?

Ну а зачем так делать? Сразу целиком писать весь регистр без его предварительного чтения. Ведь какие прерывания необходимы, а каие нет - известно. Тоже самое и регистрами флагов. Там всего 2 флага. Ну так и пиши туда сразу 0xFF. Зачем его читать???

Re: attiny13 и PCINT0 в железе

Ср мар 17, 2021 12:16:18

Старые тиньки никак не предназначены для обработки прерывания вне его - флаги сбрасываются в прерывании, поэтому надо свои вводить, если обработчик пустой. Либо же лупом проверять флаги постоянно...Вообщем, костыльные микры...
Старые, это какие?
в 13, 2313 и прочих, с которыми я работал можно и без прерываний флаги читать, программно сбоасывать... т.е. тело прерывания и разрешение прерывания совсем необязательны чтобы работать с флагами событий.

Re: attiny13 и PCINT0 в железе

Ср мар 17, 2021 13:31:08

Старые, это какие?

Это 8-ми битки, кроме: xmega, серия DA, 0-ая и 1-ая серия. В трёх последних флаги в прерываниях не сбрасываются, либо сбрасываются после выполнения определённых условий. Появились два уровня приорита прерываний, карусель прерываний... Это некая коллаборация mega и xmega.

Добавлено after 3 minutes 16 seconds:
Старые тиньки никак не предназначены для обработки прерывания вне его - флаги сбрасываются в прерывании, поэтому надо свои вводить, если обработчик пустой. Либо же лупом проверять флаги постоянно...Вообщем, костыльные микры...

в 13, 2313 и прочих, с которыми я работал можно и без прерываний флаги читать, программно сбоасывать... т.е. тело прерывания и разрешение прерывания совсем необязательны чтобы работать с флагами событий.

Флаги можно читать в любых МК. Они абсолютно независмы и отражают наступление какого-либо события. Речь о другом: выйти из сна в AVR можно только с помощью разрешённого прерывания, а его обработчик сбросит флаги автоматом.
Ответить