Форум Микро-Чип

Форум Микро-Чип (http://www.microchip.su/index.php)
-   Продукция MICROCHIP (http://www.microchip.su/forumdisplay.php?f=6)
-   -   16f877 подскажите по прерываниям (http://www.microchip.su/showthread.php?t=12514)

alx71 16.09.2011 10:33

16f877 подскажите по прерываниям
 
Код:

org 4h
; анализ источника прерывания, сохранение регистров
;
; обработчик прерывания от входа INT
;
; тут какая-то обработка
;
; к этому моменту на входе INT опять сформировался уровень прерывания
call WRITE_EEPROM
;
movf PORTB,W
bcf  INTCON,INTF
; восстановление регистров
retfie

; запись в EEPROM
WRITE_EEPROM:
;
BCF INTCON, GIE
;
BSF INTCON, GIE
;
return

Подскажите, после BSF INTCON, GIE выполнение прервется и обработчик прерываний начнет работать по-новой, или обработка продолжится до retfie?

AlexPv 16.09.2011 11:31

Re: 16f877 подскажите по прерываниям
 
Цитата:

Сообщение от alx71 (Сообщение 143265)
Код:

org 4h
; анализ источника прерывания, сохранение регистров
;
; обработчик прерывания от входа INT
;
; тут какая-то обработка
;
; к этому моменту на входе INT опять сформировался уровень прерывания
call WRITE_EEPROM
;
movf PORTB,W
bcf  INTCON,INTF
; восстановление регистров
retfie

; запись в EEPROM
WRITE_EEPROM:
;
BCF INTCON, GIE
;
BSF INTCON, GIE
;
return

Подскажите, после BSF INTCON, GIE выполнение прервется и обработчик прерываний начнет работать по-новой, или обработка продолжится до retfie?

call в программе обработки прерывания не хорошо.
И зачем в программе обработки прерывания писать в память? Достаточно выставить флаг, а по флагу в основном цикле записать.
Что-то идея не ясна.

Interrupt flag bits are set when an interrupt
condition occurs, regardless of the state of
its corresponding enable bit or the global
enable bit, GIE (INTCON<7>). User software
should ensure the appropriate interrupt
bits are clear prior to enabling an interrupt.

2AplusA 16.09.2011 12:08

Re: 16f877 подскажите по прерываниям
 
Цитата:

Сообщение от alx71 (Сообщение 143265)
Подскажите, после BSF INTCON, GIE выполнение прервется и обработчик прерываний начнет работать по-новой, или обработка продолжится до retfie?

В 16 серии нет вложенных прерываний. Поэтому, пока не выполнится команда RETFIE, другие прерывания будут ждать.

alx71 16.09.2011 14:37

Re: 16f877 подскажите по прерываниям
 
Цитата:

Сообщение от AlexPv (Сообщение 143271)
call в программе обработки прерывания не хорошо.

Почему?
Цитата:

Сообщение от AlexPv (Сообщение 143271)
И зачем в программе обработки прерывания писать в память? Достаточно выставить флаг, а по флагу в основном цикле записать.
Что-то идея не ясна.

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

petrd 16.09.2011 15:54

Re: 16f877 подскажите по прерываниям
 
Цитата:

Сообщение от alx71 (Сообщение 143283)
Почему?
Потому что после выхода из обработчика может сразу начаться новая обработка прерывания, и до обработки флага не дойдет.
Конечно, этим флагом может быть и сам бит разрешения определенного прерывания, но как-то некрасиво это...

Судя по куску кода, задача кривовато решается.

Вы засунули в прерывание запись в EEPROM, т.е. получается Вам надо быстренько писать в EEPROM, а быстро может не получится, процесс записи в нее медленный, а отсюда вопрос - нафига тогда прерывания задействовать? И ресурс циклов записи у EEPROM не резиновый. Хотите не пропустить ни одного события, а суете в прерывание длинную запись в EEPROM - нелогично.

Что-бы не было пропусков:
- сбрасывайте флаг INTF сразу при входе в обработчик;
- делайте обработчик как можно короче и без записи в EEPROM. И в EEPROM пореже пишите, для скорости есть же RAM.

alx71 16.09.2011 16:06

Re: 16f877 подскажите по прерываниям
 
На вход прерывания заведен выход фотоприемника ДУ. Запись в EEPROM происходит не каждый раз, а только при ошибке разбора команды (этот кусок кода я опустил), для последующего анализа, что случается нечасто. Скорость тут не важна.
Проблема в том, что после выполнении этой ветки возникают странные плавающие ошибки, которые я никак локализовать не могу.

syv 16.09.2011 19:25

Re: 16f877 подскажите по прерываниям
 
Цитата:

Сообщение от alx71 (Сообщение 143290)
Проблема в том, что после выполнении этой ветки возникают странные плавающие ошибки, которые я никак локализовать не могу.

А что с прерываниями от записи в EEPROM?
Они запрещены?
Покажите код подпрограммы записи в EEPROM.

alx71 16.09.2011 19:39

Re: 16f877 подскажите по прерываниям
 
Цитата:

Сообщение от syv (Сообщение 143305)
А что с прерываниями от записи в EEPROM?
Они запрещены?

Да.

Цитата:

Сообщение от syv (Сообщение 143305)
Покажите код подпрограммы записи в EEPROM.

Код:

; запись в EEPROM
; W - адрес
; EEDATA - данные
WRITE_EEPROM:

        bsf                STATUS,RP0
        bsf                STATUS,RP1
        BTFSC        EECON1,WR
        GOTO        $-1
        BTFSC        EECON1,RD
        GOTO        $-1

        btfsc        EECON1,WRERR
        goto        err_eeprom
        bcf                STATUS,RP0
        movwf        EEADR
        bcf                STATUS,RP1
        movf        EEPROM,W
        bsf                STATUS,RP1
        MOVWF        EEDATA
        BSF                STATUS, RP0
        BCF                EECON1, EEPGD
        BSF                EECON1, WREN
        BCF                INTCON, GIE
        MOVLW        0x55
        MOVWF        EECON2
        MOVLW        0xAA
        MOVWF        EECON2
        BSF                EECON1,WR

        BTFSC        EECON1,WR
        GOTO        $-1

        BSF                INTCON, GIE
        BCF                EECON1, WREN
        bcf                STATUS,RP1
        bcf                STATUS,RP0

        return
err_eeprom:
; ошибка работы с EEPROM-отобразим EE
        bcf                EECON1,WRERR
        bcf                STATUS,RP0
        bcf                STATUS,RP1
        movlw        B'10000011'
        movwf        MSB_LED
        movwf        LSB_LED
        return


syv 16.09.2011 20:08

Re: 16f877 подскажите по прерываниям
 
Цитата:

Сообщение от alx71 (Сообщение 143306)
Да.

В Вашей программе записи в EEPROM присутствуют многочисленные циклы ожидания. Я их оставил в Вашем коде.
Код:

...
    bsf        STATUS,RP0
    bsf        STATUS,RP1
    BTFSC    EECON1,WR
    GOTO    $-1
    BTFSC    EECON1,RD
    GOTO    $-1
  ...
    BTFSC    EECON1,WR
    GOTO    $-1
....
    return
err_eeprom:
....
    return

Эти циклы, замкнутые на себя, впустую съедают процессорное время.
И при этом удлиняют по времени обработчик прерывания из которого вызывается эта функция.
Это не правильно.
Оптимальное решение лежит в использовании прерываний от записи в EEPROM.
Не понятно так же назначение первых двух циклов ожидания.

alx71 17.09.2011 06:50

Re: 16f877 подскажите по прерываниям
 
Цитата:

Сообщение от syv (Сообщение 143307)
Не понятно так же назначение первых двух циклов ожидания.

Перестраховываюсь.
Возможно ли одновременно выдавать команды на чтение и запись в EEPROM по разным адресам? А по одному и тому же адресу?

alx71 17.09.2011 18:41

Re: 16f877 подскажите по прерываниям
 
Цитата:

Сообщение от alx71 (Сообщение 143265)
Подскажите, после BSF INTCON, GIE выполнение прервется и обработчик прерываний начнет работать по-новой, или обработка продолжится до retfie?

Да, прерывается. При возникновении прерывание GIE просто сбрасывается.

Цитата:

When an interrupt is responded to, the GIE bit is
cleared to disable any further interrupt, the return
address is pushed onto the stack and the PC is loaded
with 0004h.
RETFIE его просто устанавливает.

Цитата:

RETFIE Return from Interrupt
Syntax: [ label ] RETFIE
Operands: None
Operation: TOS → PC,
1 → GIE
Status Affected: None
Если установить GIE в обработчике прерывания, то он может прерваться другим прерыванием, так что в принципе вложенность прерываний обеспечить можно (только счетчик стека придется вести).

AlexPv 19.09.2011 15:04

Re: 16f877 подскажите по прерываниям
 
Цитата:

Сообщение от alx71 (Сообщение 143283)
Почему?

Потому что 8 (не помню точно) уровней стека, а то по привыкнете, call... call... и...

Илья 19.09.2011 16:39

Re: 16f877 подскажите по прерываниям
 
Цитата:

Сообщение от alx71 (Сообщение 143290)
Проблема в том, что после выполнении этой ветки возникают странные плавающие ошибки, которые я никак локализовать не могу.

у вас сделано так:

Прерывание (GIE сброшен)
- сохранение контекста
- ...
- вызов подпрограммы записи E2PROM
-- ...
-- сброс GIE (??? зачем? вы внутри прерывания и он уже сброшен)
-- ...
-- установка GIE (??? зачем? вы внутри прерывания и еще не выходите!!!)
- ...
- восстановление контекста
выход из прерывания retfie == return + GIE = 1

как только вы установили внутри прерывания GIE, вы разрешаете прерывания - если до выхода из прерывания возникнет новое - вы получите вложенное прерывание с кривой записью контекста.

В итоге вы портите контекст (восстанавливаете не то) и есть вероятность переполнения стека

причем сбрасываете флаг запроса прерывания (bcf INTCON,INTF) после вызова записи, т.е. если произойдет вложение прерываний, то вы снова начнете обрабатывать "недоделанное" прерывание с очередной записью в EEPROM и т.п.


Часовой пояс GMT +3, время: 04:03.

Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot