Разработка, производство и продажа радиоэлектронной аппаратуры
|
Требуется программист в Зеленограде - обработка данных с датчиков; ColdFire; 40 тыс.
e-mail: jobsmp@pochta.ru
|
ATmega644, глюки при просыпании по внешнему прерыванию. Продолжение пятничных экспериментов
Отправлено
Лунь 24 декабря 2008 г. 15:27
Всем привет!
Разобрался с причиной зависания мк на выходе из спячки. Повторю исходные данные:
Переделываю проект на ATmega32 под ATmega644. Проект большой, но все работает, только обратил внимание, что если коснуться чем-нибудь ножки, ответственной за внешнее прерывание по фронту (PCINT), проц не просыпается, но начинает потреблять около 8-10мА и уже не реагирует ни на какие внешние воздействия, спасает только reset. Уверенное нажатие на кнопку проц не подвешивает, глючит только когда есть помеха типа разработчика с отверткой в руке. Ножка притянута внешним резистором 3к3 к плюсу питания, 5В. Спячка глубокая, power down. Тактирование - внешний кварц 8,0.
То же самое наблюдалось если задействовать просыпание по уровню (INT0). Но это я убрал под воздействием общественности (короткий импульс - короткий импульс, говорили они :)) Сейчас нет low level, только PCINT. Глюк точно такой же.
В ходе изучения вопроса выяснил, что в ряде случаев, в результате действия помехи на ножку с прерыванием процессор как-то неверно декодирует то, что стоит в векторе соответствующего прерывания. Там у меня стоит переход на старт, все должно начаться заново. Как результат - мк переходит на команду, которая стоит после команды sleep, и продолжает выполнять то что там есть. В моем случае там встречался цикл ожидания чего-то там, чего не может быть в принципе, поэтому мк вис намертво.
Повторю главное, это видно только у ATmega644. Такого нет у ATmega32.
Для примера даю программу, которая с некоторой вероятностью виснет. На глаз - каждое второе касание ножки D,2 вызывает мертвый висяк. Если четко нажимать кнопку, происходит тоже, но значительно реже.
Для того, чтобы эта же программа работала четко, нужно убрать последнюю строку (ну или две), либо поставить jmp на START.
Добавление куда-то там nop-ов, игра с SUT-фьюзами и прочие заигрывания не дают ни какого результата. Питание чистое, уже проверено - перепроверено.
Буду рад услышать комментарии, особенно, если я все же где-то не прав, и зря грешу на ATMEL.
;--------------------------------
; fuckin'ATmega644 waking up test
;--------------------------------
.include "m644def.inc"
.org 0x000 ; reset vector
rjmp START
.org 0x00E ; PCINT3 interruption vector
rjmp START
.org 0x03E
START:
cli ; global interrupt disable
ldi r16,high(RAMEND) ; stack pointer
out SPH,r16
ldi r16,low(RAMEND)
out SPL,r16
ldi r16,0
sts PCMSK3,r16 ; disable interuption
sts PCICR,r16
ldi r17,0xF0 ; configure ports
out DDRA,r17 ;PortA
ldi r17,0x00
out PORTA,r17
ldi r17,0xA5
out DDRB,r17 ;PortB
ldi r17,0x60
out PORTB,r17
ldi r17,0xFC
out DDRC,r17 ;PortC
ldi r17,0x0B
out PORTC,r17
ldi r17,0xF0
out DDRD,r17 ;PortD
ldi r17,0x17
out PORTD,r17
sbi DDRD,1 ; turn the LED on
sbi PORTD,1
ldi r18,100 ; delay = 4*200*100*100 = 8000000 clocks = 1 second @ 8.0 MHz
L1: ldi r17,100
L2: ldi r16,200
L3: dec r16
nop
brne L3
dec r17
brne L2
dec r18
brne L1
cbi PORTD,1 ; turn the LED off
ldi r16,0 ; ports
out DDRB,r16
out DDRC,r16
out DDRA,r16
out DDRD,r16
ldi r16,0
out PORTA,r16
out PORTB,r16
out PORTC,r16
out PORTD,r16
ldi r16,0b00000100 ; PCINT26 interuption enable
sts PCMSK3,r16
ldi r16,0b00001000
sts PCICR,r16
ldi r16,0b00000100 ; sleep mode: power down
out SMCR,r16
ldi r16,0b00000101 ; enable sleep
out SMCR,r16
sei
sleep ; sleep well, my darling!
cli
LABEL: jmp LABEL ; вот тут - корень зла.
Составить ответ | Вернуться на конференцию
Ответы
- похоже при просыпании (после SLEEP) процессор успевает выполнить команду CLI. Соответственно никаких прерываний не происходит. Пара NOPов, я думаю, выручит - argus98 (24.12.2008 16:42:41 81.22.205.230, пустое)
- да, я тоже так думал, но проверил - нет. Он именно, проснувшись, туда попадает. Кстати, если убрать cli в предпоследней строке, то зависать процессор будет по-прежнему, но он из этого состояния сможет и выходить по тому же прерыванию, именно для этого я поставил cli, для большей наглядности :)) - Лунь (24.12.2008 16:45:10 86.111.22.10, пустое)
- ясен пень , в области векторов прерываний у тебя код программы . расписывать нужно всю таблицу векторов , в неиспользуемых векторах ставить переходы на reti , по крайней мере можно вычислить по какому ветору слетает программа при помехе - m16 (24.12.2008 16:05:1 78.132.150.148, пустое)
- Дык естественно! Смешали в кучу все. Помеха сшибает нормальную работу процессора, как в тысячах других случаях проблем с ESD. - Vladimir Ljaschko (24.12.2008 16:00:13 194.158.204.49, пустое)
- ну и....? один jmp и ничего не сшибает...... ESD всегда был и будет, решать-то проблему надо! - Лунь (24.12.2008 16:03:45 86.111.22.10, пустое)
- Мало Вы сталкивались с ESD. Можно подумать, Вы знаете, по каким адресам контроллер прошел после помехи до того, как уткнулся в ловушку. - Vladimir Ljaschko (24.12.2008 16:59:26 194.158.204.49, пустое)
- да может быть вообще что угодно! Вы что от меня хотите? Вы можете сказать, что сделать в этом случае более правильно? Или вы хотите мне объяснить, что я не знаю что там происходит. Так это я отдаю себе отчет. Мне проблему решить надо. И еще --> - Лунь (24.12.2008 17:18:15 86.111.22.10, 448 байт)
- ну вот именно так и есть. Если длительность воздействия очень маленькая, то просыпается нормально. Именно поэтому в пятницу и блуждали эти версии о том, что зря я использую INT по низкому уровню, ибо в pdf написано, что там необходимо некоторое время. Я не верил, но переделал. Теперь по фронту. То же самое. На данный момент проблема решена, делюсь опытом и жду комментариев, возможно я ошибаюсь в своих предположениях. - Лунь (24.12.2008 17:29:31 86.111.22.10, пустое)
- Спокойнее :-) Я цепляюсь к тому, что Вы написали "Если четко нажимать кнопку, происходит тоже, но значительно реже." - Vladimir Ljaschko (24.12.2008 17:25:47 93.84.24.169, пустое)