реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Обработка двух прерываний ?, ATMEGA162
zombi
сообщение Jan 27 2009, 12:09
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Столкнулся с проблемой.
Долго мучался и ветаки поборол, но как-то странно!

Опишу кратко.
Используется два прерывания:

1:0x01A Timer/Counter1 Compare Match A - режим CLC (частота 44100 Hz)
2:0x020 Timer/Counter0 Compare Match - режим CLC ( частота 500 Hz)

У второго прерывания приоритет ниже и первая команда его обработчика SEI.
Все регистры и флаги сохраняются в каждом обработчике.
Проблема в том что во втором прерывании необходимо читать состояние PIND.4
Состояние пина иногда считывается 0-м в то время как он в 1-це.

В таком виде глючило:

CBI PORTB,7
SBI PORTB,7
ROL RTMP
SBIC PIND.4
ANDI RTMP,$01

добавил запрет и разрешение прерываний и глюк ПОЛНОСТЬЮ пропал:

CLI
CBI PORTB,7
SBI PORTB,7
ROL RTMP
SBIC PIND.4
ANDI RTMP,$01
SEI

Что это, глюк меги или я чегото не понимаю?
Ктонибудь сталкивался с подобным?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 27 2009, 12:30
Сообщение #2


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zombi @ Jan 27 2009, 16:09) *
CLI
CBI PORTB,7
SBI PORTB,7
ROL RTMP
SBIC PIND.4
ANDI RTMP,$01
SEI
Что это, глюк меги или я чегото не понимаю?

Это глюк автора программы, вероятно, забывшего о необходимости сохранять SREG. smile.gif
Впрочем - это чистая телепатия, потому что из того, что Вы написали, вообще понять ничего невозможно. Дайте больше информации.
Go to the top of the page
 
+Quote Post
zombi
сообщение Jan 27 2009, 12:39
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Я ж написал что "Все регистры и флаги сохраняются в каждом обработчике.
"
Цитата
Дайте больше информации.

Попробую.
Вся проблема в том что если во время приведенных мою 5-ти команд 2-го обработчика выполняется другое прерывание то состояние 4-го пина порта D командой CBIC интерпретируется не верно.

Сообщение отредактировал zombi - Jan 27 2009, 12:48
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 27 2009, 12:50
Сообщение #4


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zombi @ Jan 27 2009, 16:09) *
У второго прерывания приоритет ниже и первая команда его обработчика SEI.
Все регистры и флаги сохраняются в каждом обработчике.
В стеке? Код полностью огласите плз.
Go to the top of the page
 
+Quote Post
zombi
сообщение Jan 27 2009, 13:23
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата
В стеке? Код полностью огласите плз.

Полность очень много!
Попробую частями.
Настройка и разрешение прерываний:
Код
;-- TIMER1 - SOUND --------------
    LDI    RTMP,$09
    OUT    TCCR1B,RTMP
    LDI    RTMP,HIGH(362)
    OUT    OCR1AH,RTMP
    LDI    RTMP,LOW(362)
    OUT    OCR1AL,RTMP

;-- TIMER0 - KEY --------------
    LDI    RTMP,$0E
    OUT    TCCR2,RTMP
    LDI    RTMP,124
    OUT    OCR2,RTMP
;-----------------
    LDI    RTMP,$50
    OUT    TIMSK,RTMP

Обработчик timer1:
Код
TIM1:
    PUSH    RTMPA
    IN    RTMPA,$3F
    PUSH    RTMPA
.
.
.
    POP    RTMPA
    OUT    $3F,RTMPA
    POP    RTMPA
    RETI

Обработчик timer0:
Код
TIM0:
    SEI
    PUSH    RTMPA
    IN    RTMPA,$3F
    PUSH    RTMPA
.
.
.
    CLI      <----------------------
    CBI    PORTB,7
    SBI    PORTB,7
    LSL    RTMPA
    SBIC    PIND,4
    ORI    RTMPA,$01
    SEI     <----------------------
.
.
.
    STS    $8000,RTMPA
    RET


Проблема в том что даже если на PIND.4 тупо VCC подать, то младший бит в ячейке $8000 не всегда =1 если в обработчике TIM0 нету CLI/SEI во время его опроса.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 27 2009, 13:39
Сообщение #6


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Опускаю Ваши небрежности (код выхода из TIM0, код инициализации TIM0) - я так понял, что в реале там все нормально ?
Несогласен раз:
Код
TIM0:

;*************
    CBI    PORTB,7
    SBI    PORTB,7
    LSL    RTMPA
    CLI      <----------------------
   SBIC    PIND,4
    ORI    RTMPA,$01
    SEI     <----------------------
;*****

Несогласен, часть вторая: пожертвуйте регистром 
Код
in RTMPC,PIND
bst RTMPC,4
bld RTMPA,0

ЗЫ марш несогласных smile.gif
Раньше была проблема такая с sbrc/sbic sbrs/sbis но это было давно.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 27 2009, 14:20
Сообщение #7


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(zombi @ Jan 27 2009, 15:23) *
Попробую частями.
Код
TIM0:
    SEI
    PUSH    RTMPA
    IN    RTMPA,$3F
    PUSH    RTMPA


Может происходит повторный вызов TIM0? Вы же не запрещаете "ЭТО" прерывание.

Пропробуйте так:
Код
TIM0:
    cbi     TIMSK, OCIE0
    sei
....
    sbi   TIMSK, OCIE0
    reti
Go to the top of the page
 
+Quote Post
zombi
сообщение Jan 27 2009, 15:16
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Спасибо всем ответившим.
Цитата
пожертвуйте регистром но это было давно

Через рег тоже пробывал, не помогло.
Цитата
Опускаю Ваши небрежности (код выхода из TIM0, код инициализации TIM0) - я так понял, что в реале там все нормально ?

А что с выходом из TIM0? Если вы имеете ввиду RET а не RETI то я же прерывания разрешаю в теле обратотчика.

Ув. _Pasha подскажите что не правильно в инициализации TIM0?
Просто я всегда так инициализирую, подскажите где ошибка.

Цитата
Может происходит повторный вызов TIM0? Вы же не запрещаете "ЭТО" прерывание

Незнаю. Надо попробывать . Спасибо defunct.
Но думаю что прерывание должно срабатывать по фронту?
Но даже еслиб вход выполнялся несколько раз то в мл.бите регистра RTMPA всеравно должна быть единица ведь состояние PIND.4 стабильно.

Цитата(defunct @ Jan 27 2009, 18:20) *
Может происходит повторный вызов TIM0? Вы же не запрещаете "ЭТО" прерывание.

Пропробуйте так:
Код
TIM0:
    cbi     TIMSK, OCIE0
    sei
....
    sbi   TIMSK, OCIE0
    reti

Попробывал. Результат отрицательный. Глюки продолжаются.


Цитата(_Pasha)
Код
TIM0:

;*************
    CBI    PORTB,7
    SBI    PORTB,7
    LSL    RTMPA
    CLI      <----------------------
   SBIC    PIND,4
    ORI    RTMPA,$01
    SEI     <----------------------
;*****

И так пробывал но тоже глючит.
Глюки исчезают только если CLI находится перед LSL или еще раньше, но никак не перед SBIC:
Код
;*************
    CBI    PORTB,7
    SBI    PORTB,7
    CLI      <----------------------
    LSL    RTMPA
   SBIC    PIND,4
    ORI    RTMPA,$01
    SEI     <----------------------
;*****


Сообщение отредактировал zombi - Jan 27 2009, 14:49
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 27 2009, 16:06
Сообщение #9


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zombi @ Jan 27 2009, 18:16) *
А что с выходом из TIM0? Ув. _Pasha подскажите что не правильно в инициализации TIM0?

1.Инициализация
Код
;-- TIMER0 - KEY --------------
    LDI    RTMP,$0E
    OUT    TCCR2,RTMP
    LDI    RTMP,124
    OUT    OCR2,RTMP


Мы говорим о прерывании таймера 0, а здесь и далее у Вас инициализация таймера 2. Если эта небрежность все-же имеет отношение  к проблеме, то проверьте таблицу векторов прерываний - вполне возможно, что там бардак.

2. Код входа и выхода 
Код
   
SEI
PUSH    RTMPA
IN        RTMPA,SREG
PUSH        RTMPA
; *******

STS  $8000,RTMPA

pop   RTMPA
out    SREG,RTMPA
pop   RTMPA 
reti
Go to the top of the page
 
+Quote Post
zombi
сообщение Jan 27 2009, 16:18
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата
то проверьте таблицу векторов прерываний - вполне возможно, что там бардак.

Конечно с таблицей векторов и POPами PUSHами все впорядке.
Это просто апычатки laughing.gif sorry.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 27 2009, 16:30
Сообщение #11


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Значит где-то чистят Ваш RTMPA без сохранения/восстановления. Поставьте условный брекпоинт на запись в регистр и дебажьте до победы.
Go to the top of the page
 
+Quote Post
zombi
сообщение Jan 27 2009, 16:42
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(_Pasha @ Jan 27 2009, 19:30) *
Значит где-то чистят Ваш RTMPA без сохранения/восстановления. Поставьте условный брекпоинт на запись в регистр и дебажьте до победы.

Не думаю что я гдето порчу RTMPA ведь с CLI/SEI нечего не портится!!!
Всетаки мне кажется проблема с входом в прерывание в момент выполнения SBIC/S возможно даже именно с PIND.4.
В любом случае экспериментировать надоело , запрет/разрешение прерываний спасает и пару лишних тактов не жмет, работает и бог с ним. rolleyes.gif
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 27 2009, 18:12
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Интересно.
Я не сталкивался, но в первых моделях указывали про ошибки возникающие именно при прерывании и именно при исполнении комад sbic/sbis. Правда, если команда следующая за этими командами - двухсловная.
При этом про команды BLD/BST никогда ничего не было.

Всётаки я думаю, что вам надо исходить из постулата, что это ваша ошибка. И, соответственно, искать её корни. Иначе она вылезет в другом месте и в другом виде. А заплатки ставить - не пацанский метод.
Go to the top of the page
 
+Quote Post
uau
сообщение Jan 28 2009, 10:46
Сообщение #14





Группа: Участник
Сообщений: 6
Регистрация: 8-02-05
Пользователь №: 2 511



Цитата(zombi @ Jan 27 2009, 18:16) *
А что с выходом из TIM0? Если вы имеете ввиду RET а не RETI то я же прерывания разрешаю в теле обратотчика.


А из стека, кто байт флагов будет вычищать?

Сообщение отредактировал uau - Jan 28 2009, 10:50
Go to the top of the page
 
+Quote Post
zombi
сообщение Jan 28 2009, 14:48
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Прошу прощения за поднятую бучу!
Все оказалось гораздо проще.
Ко входу D.4 подключен выход сдвигового регистра 74hc157.
Опрос пина был сразу после строба SCK и регистр просто не успевал переключится.
Частота процессора 16MHz а у регистра время установления выхода большое вот от он то успевал то нет.
А команда CLI просто добавляла необходимую задержку laughing.gif

Но благодаря defunct возможно сразу избежал следующего косяка с прерываниями:
Если время выполнения прерывания TIM1 окажется больше чем период TIM2 то возможен повторный вход в в TIM2.
Устранил эту ситуацию запретом прерывания по TIM2 путем записи в TIMSK на старте и последующим разрешением на выходе.
Код
TIM2:    PUSH    RTMPA
    LDI    RTMPA,$40
    OUT    TIMSK,RTMPA
    SEI
    IN    RTMPA,SREG
    PUSH    RTMPA
    .
    .
    .
    POP    RTMPA
    OUT    SREG,RTMPA
    LDI    RTMPA,$50
    CLI
    OUT    TIMSK,RTMPA
    POP    RTMPA
    RETI
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th July 2025 - 16:52
Рейтинг@Mail.ru


Страница сгенерированна за 0.01517 секунд с 7
ELECTRONIX ©2004-2016