Форум Микро-Чип
Поиск и заказ электронных компонентов
 

Вернуться   Форум Микро-Чип > Продукция MICROCHIP

Продукция MICROCHIP Технические вопросы по всей продукции Microchip

Ответ
 
Опции темы Опции просмотра
Старый 15.08.2010, 22:30   #1
KSB31
Junior Member
 
Регистрация: 15.08.2010
Сообщений: 19
Вес репутации: 104/28
KSB31 will become famous soon enoughKSB31 will become famous soon enough
По умолчанию Вопрос по прерываниям RB7-RB4

Доброго всем времени суток,
МК изучаю не давно, так что извините если вопрос глупый...

так вот почитав немного книгу, решил что лучше всего будет начать делать какойнить девайс и по ходу дела разбираться с возникающими трудностями. Одна из функций моего девайса это подсчет общего времени импульсов подаваемых на один из входов, и вывод его на ЖК.
Делаю я это по прерыванию на выводе RB4, по спаду (с 1 на 0) я обнуляю таймер TMR0, а по фронту добавляю текущее значение таймера к огбщей сумме. т.к. таймер 8-и битный то я еще использую один регистр как старший для таймера (соотв в преррывании обрабатываю и переполнение таймера)

вот код ПП обработки прерывания
Код:
INTERUPT     movwf W_Temp         
            movf STATUS, W            
            movwf Stat_Temp 
            movf PCLATH, W
            movwf PCLATH_TEMP


            btfsc INTCON, 2            ;проверка флага прерывания по переполнению таймера TMR0 
            goto TMR0_ovflw    
    
            btfsc INTCON, 0            ;проверка флага прерывания по изменению уровня
            goto RB4_7_int             ;хотябы на одном из портов RB7-RB4

                                
;-----------------------------------------------------------------------------------
;обработка прерывания по переполнению таймера TMR0

TMR0_ovflw    bcf INTCON, 2            ;сброс флага прерывания
            incf TMR0_H, F            ;увеличение старшего разряда на еденицу                                    
            goto end_int

;-----------------------------------------------------------------------------------
;обработка прерывания по изменению уровня на RB

RB4_7_int     bcf INTCON, 0            ;сброс флага прерывания
            btfsc PORTB, 4            
            goto rise_edge            ;если 1 (т.е. был переход с 0 на 1) то переход на ПП  rise_edge
            goto fall_edge            ;если 0 (т.е. был переход с 1 на 0) то переход на ПП  fall_edge



fall_edge   clrf TMR0                ;обнуление таймера  
            clrf TMR0_H                ;TMR0 - младший разряд TMR0_H - старший разряда   

            goto endTMR0int


rise_edge    movf TMR0, W            ;добавление времени насчитаного таймером к общему времени
            addwf VPR_LL, F            ;добавляем содержимое таймера TMR0 к самому младшему регистру времени 
        
            btfss STATUS, C            ;проверяем было ли переполнение
            goto metka_1            ;если не было (С=0) то преходим далее по метке 1
            movlw 0x01                ;если было (С=1) то добавляем к младшему регистру времени еденицу
            addwf VPR_L, F            
            
            btfss STATUS, C            ;опять проверяем было ли переполнение
            goto metka_1            ;если не было (С=0) то преходим далее по метке 1
            movlw 0x01                ;если было (С=1) то добавляем к среднему регистру времени еденицу
            addwf VPR_M, F        

            btfss STATUS, C            ;опять проверяем было ли переполнение
            goto metka_1            ;если не было (С=0) то преходим далее по метке 1
            incf VPR_H, F            ;если было (С=1) то добавляем к старшему регистру времени еденицу

metka_1        movf TMR0_H, W            ;добавление времени насчитаного таймером к общему впрыска
            addwf VPR_L, F            ;добавляем содержимое таймера TMR0_H к младшему регистру впрыска 
        
            btfss STATUS, C            ;проверяем было ли переполнение
            goto endTMR0int            ;если не было (С=0) то преходим в конец обработчика прерывания
            movlw 0x01                ;если было (С=1) то добавляем к среднему регистру времени еденицу
            addwf VPR_M, F        
            
            btfss STATUS, C            ;опять проверяем было ли переполнение
            goto endTMR0int            ;если не было (С=0) то преходим  в конец обработчика прерывания
            incf VPR_H, F            ;если было (С=1) то добавляем к старшему регистру времени еденицу
            
endTMR0int goto end_int

;-----------------------------------------------------------------------------------

end_int        movf PCLATH_TEMP,W        
            movwf PCLATH            
            movf Stat_Temp, W    
            movwf STATUS        
            swapf W_Temp,F            
            swapf W_Temp,W            

            retfie
так вот насчитывает ппрога ровно в два раза больше чем должна....
для проверки поехал купил другой МК и собрал на нем простенький генератор импульсов с длительностью импульса 3,2 мс и расстоянием м/у импульсами 160 мс

Код:
;импульс 3,231 мс

impulse        bcf PORTB, 7
            
            movlw .5
            movwf delay1            
loop_1        movlw .214
            movwf delay2            
loop_2        decfsz delay2,1
            goto loop_2         
            decfsz delay1,1
            goto loop_1

    


;задержка 161,51 мс

            bsf PORTB, 7

delay        movlw .6
            movwf delay3
loop_5        movlw .35
            movwf delay2
loop_3        movlw .255
            movwf delay1        
loop_4        decfsz delay1,1
            goto loop_4         
            decfsz delay2,1
            goto loop_3
            decfsz delay3,1
            goto loop_5

            goto impulse
На осцилографе смотрел все четко.
Подключил к своему девайсу , он опять насчитывает в 2-а раза больше. И тут я вспомнил что когда баловался с симулятором использовал там такую вещь как stimulus? и частенько у меня после одного прерывания тут же приходило второе, но с тем же состоянием порта. тогда я решил доработать прогу и ввести анализ предыдущего состояния, и только после этого МК стал правильно подсчитывать время.
Код:
INTERUPT     movwf W_Temp         
            movf STATUS, W            
            movwf Stat_Temp 
            movf PCLATH, W
            movwf PCLATH_TEMP


            btfsc INTCON, 2            ;проверка флага прерывания по переполнению таймера TMR0 
            goto TMR0_ovflw    
    
            btfsc INTCON, 0            ;проверка флага прерывания по изменению уровня
            goto RB4_7_int             ;хотябы на одном из портов RB7-RB4

                                
;-----------------------------------------------------------------------------------
;обработка прерывания по переполнению таймера TMR0

TMR0_ovflw    bcf INTCON, 2            ;сброс флага прерывания
            incf TMR0_H, F            ;увеличение старшего разряда на еденицу                                    
            goto end_int

;-----------------------------------------------------------------------------------
;обработка прерывания по изменению уровня на RB

RB4_7_int     bcf INTCON, 0            ;сброс флага прерывания
            btfsc PORTB, 4            
            goto rise_edge            ;если 1 (т.е. был переход с 0 на 1) то переход на ПП  rise_edge
            goto fall_edge            ;если 0 (т.е. был переход с 1 на 0) то переход на ПП  fall_edge



fall_edge    btfsc prev_imp_flag,0    ;проверяем предыдущее состояние сигнала
            goto fall                ;если сигнал до этого был 1 то воспринимаем это как переход с 1 на 0 т.е. спад
            goto endTMR0int            ;если сингал до этого был 0 то выход из обработки

fall        clrf TMR0                ;обнуление таймера  
            clrf TMR0_H                ;TMR0 - младший разряд TMR0_H - старший разряда         
                    
            movlw 0x00
            movwf prev_imp_flag        ;записываем текущее состояние в флаг            

            goto endTMR0int


rise_edge    btfss prev_imp_flag,0    ;проверяем предыдущее состояние сигнала
            goto front                ;если сигнал до этого был 0 то воспринимаем это как переход с 0 на 1 т.е. фронт
            goto endTMR0int            ;если сингал до этого был 1 то выход из обработки

front        movlw 0x01
            movwf prev_imp_flag        ;записываем текущее состояние в флаг

        
            movf TMR0, W            ;добавление времени насчитаного таймером к общему времени
            addwf VPR_LL, F            ;добавляем содержимое таймера TMR0 к самому младшему регистру времени 
        
            btfss STATUS, C            ;проверяем было ли переполнение
            goto metka_1            ;если не было (С=0) то преходим далее по метке 1
            movlw 0x01                ;если было (С=1) то добавляем к младшему регистру времени еденицу
            addwf VPR_L, F            
            
            btfss STATUS, C            ;опять проверяем было ли переполнение
            goto metka_1            ;если не было (С=0) то преходим далее по метке 1
            movlw 0x01                ;если было (С=1) то добавляем к среднему регистру времени еденицу
            addwf VPR_M, F        

            btfss STATUS, C            ;опять проверяем было ли переполнение
            goto metka_1            ;если не было (С=0) то преходим далее по метке 1
            incf VPR_H, F            ;если было (С=1) то добавляем к старшему регистру времени еденицу

metka_1        movf TMR0_H, W            ;добавление времени насчитаного таймером к общему впрыска
            addwf VPR_L, F            ;добавляем содержимое таймера TMR0_H к младшему регистру впрыска 
        
            btfss STATUS, C            ;проверяем было ли переполнение
            goto endTMR0int            ;если не было (С=0) то преходим в конец обработчика прерывания
            movlw 0x01                ;если было (С=1) то добавляем к среднему регистру времени еденицу
            addwf VPR_M, F        
            
            btfss STATUS, C            ;опять проверяем было ли переполнение
            goto endTMR0int            ;если не было (С=0) то преходим  в конец обработчика прерывания
            incf VPR_H, F            ;если было (С=1) то добавляем к старшему регистру времени еденицу
            
endTMR0int goto end_int

;-----------------------------------------------------------------------------------

end_int        movf PCLATH_TEMP,W        
            movwf PCLATH            
            movf Stat_Temp, W    
            movwf STATUS        
            swapf W_Temp,F            
            swapf W_Temp,W            

            retfie
и я не понимаю почему это так происходит, флаг прерывания я сбрасываю, сигнал четкий никаких помех на которые мог бы среагировать МК нету....

Последний раз редактировалось KSB31; 15.08.2010 в 22:42.
KSB31 вне форума   Ответить с цитированием
Старый 15.08.2010, 22:37   #2
KSB31
Junior Member
 
Регистрация: 15.08.2010
Сообщений: 19
Вес репутации: 104/28
KSB31 will become famous soon enoughKSB31 will become famous soon enough
По умолчанию Re: Вопрос по прерываниям RB7-RB4

да, забыл сказать что по спаду обнуляю, потому что импульс отрицательный, т.е. все время висит +5 в, а во время импульса сигнал сажается на землю
KSB31 вне форума   Ответить с цитированием
Старый 15.08.2010, 22:59   #3
vitalka
Super Moderator
 
Аватар для vitalka
 
Регистрация: 19.03.2007
Адрес: Львов
Возраст: 42
Сообщений: 3,334
Вес репутации: 2341/95
vitalka has a reputation beyond reputevitalka has a reputation beyond reputevitalka has a reputation beyond reputevitalka has a reputation beyond reputevitalka has a reputation beyond reputevitalka has a reputation beyond reputevitalka has a reputation beyond reputevitalka has a reputation beyond reputevitalka has a reputation beyond reputevitalka has a reputation beyond reputevitalka has a reputation beyond repute
По умолчанию Re: Вопрос по прерываниям RB7-RB4

перед сбросом флага прерывания нужно прочитать сам порт, иначе флаг снова поднимется
см. даташит на контроллер (соотв. раздел)
vitalka вне форума   Ответить с цитированием
Старый 15.08.2010, 23:39   #4
KSB31
Junior Member
 
Регистрация: 15.08.2010
Сообщений: 19
Вес репутации: 104/28
KSB31 will become famous soon enoughKSB31 will become famous soon enough
По умолчанию Re: Вопрос по прерываниям RB7-RB4

Спасибо огромное )
KSB31 вне форума   Ответить с цитированием
Старый 15.08.2010, 23:53   #5
KSB31
Junior Member
 
Регистрация: 15.08.2010
Сообщений: 19
Вес репутации: 104/28
KSB31 will become famous soon enoughKSB31 will become famous soon enough
По умолчанию Re: Вопрос по прерываниям RB7-RB4

вот и цитата из даташита которую я пропустил
Код:
The user, in the interrupt service routine, can
clear the interrupt in the following manner:
a) Any read or write of PORTB. This will end the mismatch condition.
b) Clear flag bit RBIF.
A mismatch condition will continue to set flag bit RBIF. Reading PORTB will end the mismatch
condition, and allow flag bit RBIF to be cleared.
KSB31 вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
еще один вопрос по контроллеру опережения зажигания на pic 16f84a 4,0мгц дмитрий626 Вопросы начинающих 6 26.12.2009 09:08
Вопрос по индикации. 40grad Общетехнические вопросы 6 23.09.2008 18:44
Вопрос по Altium Designer Iptash Печатный монтаж 2 14.09.2008 14:57
вопрос по PICC EXT_INT Вопросы начинающих 13 26.08.2008 07:53
Вопрос новичка по Си ramonchik Продукция MICROCHIP 3 05.03.2007 16:28


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


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