Перейти к содержанию
    

Обработка двух прерываний ?

Столкнулся с проблемой.

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

 

Опишу кратко.

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

 

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

 

Что это, глюк меги или я чегото не понимаю?

Ктонибудь сталкивался с подобным?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

CLI

CBI PORTB,7

SBI PORTB,7

ROL RTMP

SBIC PIND.4

ANDI RTMP,$01

SEI

Что это, глюк меги или я чегото не понимаю?

Это глюк автора программы, вероятно, забывшего о необходимости сохранять SREG. :)

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

"

Дайте больше информации.

Попробую.

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

Изменено пользователем zombi

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У второго прерывания приоритет ниже и первая команда его обработчика SEI.

Все регистры и флаги сохраняются в каждом обработчике.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Полность очень много!

Попробую частями.

Настройка и разрешение прерываний:

;-- 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 во время его опроса.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Опускаю Ваши небрежности (код выхода из 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

ЗЫ марш несогласных :)

Раньше была проблема такая с sbrc/sbic sbrs/sbis но это было давно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробую частями.

TIM0:
    SEI
    PUSH    RTMPA
    IN    RTMPA,$3F
    PUSH    RTMPA

 

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

 

Пропробуйте так:

TIM0:
    cbi     TIMSK, OCIE0
    sei 
....
    sbi   TIMSK, OCIE0
    reti

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо всем ответившим.

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

Через рег тоже пробывал, не помогло.

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

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

 

Ув. _Pasha подскажите что не правильно в инициализации TIM0?

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

 

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

Незнаю. Надо попробывать . Спасибо defunct.

Но думаю что прерывание должно срабатывать по фронту?

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

 

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

 

Пропробуйте так:

TIM0:
    cbi     TIMSK, OCIE0
    sei 
....
    sbi   TIMSK, OCIE0
    reti

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

 

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что с выходом из 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Конечно с таблицей векторов и POPами PUSHами все впорядке.

Это просто апычатки :laughing: sorry.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Значит где-то чистят Ваш RTMPA без сохранения/восстановления. Поставьте условный брекпоинт на запись в регистр и дебажьте до победы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Значит где-то чистят Ваш RTMPA без сохранения/восстановления. Поставьте условный брекпоинт на запись в регистр и дебажьте до победы.

Не думаю что я гдето порчу RTMPA ведь с CLI/SEI нечего не портится!!!

Всетаки мне кажется проблема с входом в прерывание в момент выполнения SBIC/S возможно даже именно с PIND.4.

В любом случае экспериментировать надоело , запрет/разрешение прерываний спасает и пару лишних тактов не жмет, работает и бог с ним. :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Интересно.

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

При этом про команды BLD/BST никогда ничего не было.

 

Всётаки я думаю, что вам надо исходить из постулата, что это ваша ошибка. И, соответственно, искать её корни. Иначе она вылезет в другом месте и в другом виде. А заплатки ставить - не пацанский метод.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Изменено пользователем uau

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прошу прощения за поднятую бучу!

Все оказалось гораздо проще.

Ко входу D.4 подключен выход сдвигового регистра 74hc157.

Опрос пина был сразу после строба SCK и регистр просто не успевал переключится.

Частота процессора 16MHz а у регистра время установления выхода большое вот от он то успевал то нет.

А команда CLI просто добавляла необходимую задержку :laughing:

 

Но благодаря 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...