problems with timer0/interrupts

View: New views
4 Messages — Rating Filter:   Alert me  

problems with timer0/interrupts

by Lope Vega :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi guys,

Thanks so much Robert, first of all. Both your code about table reads worked out of the box, and were also right about my missunderstanding of the variables' thing.

I didn't think of trying to declare it as global and then try to use it in other modules.

I'm having a problem now with interrupts/timer0.

As petter suggested, I've started scanning 3 seven segment displays on my app's main function, while using interrupts to update a counter upon a switch's press/debounce.

Then, what did was to setup interrupts for RB4:7 pins' state change, and within it's processing function, try to use timer0 to debounce the switch.

However, when I program the device and place it on it's side of the breadboard, it seems the pic falls into the interrupt, and that the timer0 polling causes it to recurse into it undefinetely.

I'm gonna paste the relevant part of the code for if anyone want to give me some explanation.

this is my main file:

        ;;                                                                                  
        ;; variables                                                                        
        ;;                                                                                  
main_vars       udata
        ;; main counter                                                                    
counter         res     1
        ;; temp variables                                                                  
digit           res     1
aux             res     1

        ;;                                                                                  
        ;; imported symbols                                                                
        ;;                                                                                  
        extern  hp_interrupt
        ;; a table read function, with a `movwf segments_port'
        ;; at the end of it
        extern  display  

        ;;                                                                                  
        ;; exported symbols                                                                
        ;;                                                                                  
        global  counter
        global  digit

        ;;                                                                                  
        ;; reset vector                                                                    
        ;;                                                                                  
reset_vector    code    0x0
        goto    main

        ;;                                                                                  
        ;; high-priority interrupt vector                                                  
        ;;                                                                                  
_hp_interrupt   code    0x8
        goto    hp_interrupt

        ;;                                                                                  
        ;; app's entry point                                                                
        ;;                                                                                  
main:
        ;;                                                                                  
        ;; ports' setup                                                                    
        ;;                                                                                  

        ;; porta                                                                            
        clrf    porta
        clrf    trisa

        ;; portb, here I'm supossed to have a switch which is
        ;; active-low, thus, when pressed goes low, and this
        ;; ports' setup seems to be giving me problems also
        clrf    latb
        movlw   0xff
        movwf   trisb

        ;; portc                                                                            
        clrf    latc
        clrf    trisc

        ;; portd                                                                            
        clrf    latd
        clrf    trisd


        ;; porte                                                                            
        clrf    late
        clrf    trise

        ;;                                                                                  
        ;; interrupts                                                                      
        ;;                                                                                  

        ;; enable rb pins change interrupt, and it's pullups                                                  
        bsf     intcon, rbie
        bcf     intcon2, rbpu

        ;; clear it's flag bit                                                              
        bcf     intcon, rbif

        ;; disable tmr0 interrupt                                                          
        bcf     intcon, tmr0ie

        ;; setup timer0: internal clock, 8 bits, prescale 1:64                              
        movlw   b'01000101'
        movwf   t0con

        ;; globally enable interrupts                                                      
        bsf     intcon, gie

start:
        ;; just loop, I acutally have code here for decomposing
        ;; `counter' so I can display it on the segment leds
        ;; (leading 0's not being displayed)
        goto start


and this is my `interrupts.s' file:


        ;;                                                                                  
        ;; variables                                                                        
        ;;                                                                                  
int_vars        udata
        ;; these for high-priority interrupts                                              
hp_w            res     1
hp_bsr          res     1
hp_status       res     1

        ;;                                                                                  
        ;; imported symbols                                                                
        ;;                                                                                  
        extern  counter

        ;;                                                                                  
        ;; exported symbols                                                                
        ;;                                                                                  
        global  hp_interrupt


        ;;                                                                                  
        ;; rb* interrupt-handler                                                            
        ;;
_handle_rb_interrupt    code
handle_rb_interrupt:
        ;; clear it's flag bit                                                              
        bcf     intcon, rbif

        ;; clear tmr0 and it's flag bit within `intcon',
        ;; and turn it on                    
        clrf    tmr0l
        bcf     intcon, tmr0if
        bsf     t0con, tmr0on

loop:
        ;; check for the flag bit being set as a result of an
        ;; overflow on the timer
        btfss   intcon, tmr0if
        goto    loop

        ;; then increment `counter' (should wait and debounce
        ;; the switch's release also)                                                              
        banksel counter
        incf    counter, f

        ;; toggle on a led used as feedback @ rc0
        btg     latc, rc0

        ;; turn off the timer
        bcf     t0con, tmr0on

        ;; and return
        retlw   0

        ;;
        ;; high-priority interrupt vector                                                  
        ;;
__hp_interrupt  code
hp_interrupt:
        ;; save registers' status. I don't know if I'd be using
        ;; also low priorities, so better to go this way just in
        ;; case (datasheet says `retfie fast' could be
        ;; unreliable if so)
        movwf   hp_w
        movff   bsr, hp_bsr
        movff   status, hp_status

        ;; if the interrupt was caused by a change on rb4:7, go
        ;; to it's processing function
        btfsc   intcon, rbif
        call    handle_rb_interrupt

exit_hp_interrupt:
        movff   hp_bsr, bsr
        movf    hp_w, w
        movff   hp_status, status
        retfie  0x0
        end

I tried with another led on ra0 and a `btfsc intcon, tmr0if btg lata, ra0' above, so what is happening that tmr0 is causing the chip to vector to 0x8 even when I explictly disabled it.

Shouldn't be `tmr0if' just set, and not cause the chip to vector?

Regards,







---------------------------------------------------------------------
To unsubscribe, e-mail: gnupic-unsubscribe@...
For additional commands, e-mail: gnupic-help@...


Re: problems with timer0/interrupts

by George M. Gallant, Jr. :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Lope,

Just a some observations:
  1. If you evr do get to hp_interrupt and it is not the change on rb,
      you will be stuck here.
  2. The time is enabled with setting a value.
  3. Perhaps you could recode to use the timer interrupt.
  4. Have you tried a simulator?

George


Lope Vega wrote:

> Hi guys,
>
> Thanks so much Robert, first of all. Both your code about table reads worked out of the box, and were also right about my missunderstanding of the variables' thing.
>
> I didn't think of trying to declare it as global and then try to use it in other modules.
>
> I'm having a problem now with interrupts/timer0.
>
> As petter suggested, I've started scanning 3 seven segment displays on my app's main function, while using interrupts to update a counter upon a switch's press/debounce.
>
> Then, what did was to setup interrupts for RB4:7 pins' state change, and within it's processing function, try to use timer0 to debounce the switch.
>
> However, when I program the device and place it on it's side of the breadboard, it seems the pic falls into the interrupt, and that the timer0 polling causes it to recurse into it undefinetely.
>
> I'm gonna paste the relevant part of the code for if anyone want to give me some explanation.
>
> this is my main file:
>
>         ;;                                                                                  
>         ;; variables                                                                        
>         ;;                                                                                  
> main_vars       udata
>         ;; main counter                                                                    
> counter         res     1
>         ;; temp variables                                                                  
> digit           res     1
> aux             res     1
>
>         ;;                                                                                  
>         ;; imported symbols                                                                
>         ;;                                                                                  
>         extern  hp_interrupt
>         ;; a table read function, with a `movwf segments_port'
>         ;; at the end of it
>         extern  display  
>
>         ;;                                                                                  
>         ;; exported symbols                                                                
>         ;;                                                                                  
>         global  counter
>         global  digit
>
>         ;;                                                                                  
>         ;; reset vector                                                                    
>         ;;                                                                                  
> reset_vector    code    0x0
>         goto    main
>
>         ;;                                                                                  
>         ;; high-priority interrupt vector                                                  
>         ;;                                                                                  
> _hp_interrupt   code    0x8
>         goto    hp_interrupt
>
>         ;;                                                                                  
>         ;; app's entry point                                                                
>         ;;                                                                                  
> main:
>         ;;                                                                                  
>         ;; ports' setup                                                                    
>         ;;                                                                                  
>
>         ;; porta                                                                            
>         clrf    porta
>         clrf    trisa
>
>         ;; portb, here I'm supossed to have a switch which is
>         ;; active-low, thus, when pressed goes low, and this
>         ;; ports' setup seems to be giving me problems also
>         clrf    latb
>         movlw   0xff
>         movwf   trisb
>
>         ;; portc                                                                            
>         clrf    latc
>         clrf    trisc
>
>         ;; portd                                                                            
>         clrf    latd
>         clrf    trisd
>
>
>         ;; porte                                                                            
>         clrf    late
>         clrf    trise
>
>         ;;                                                                                  
>         ;; interrupts                                                                      
>         ;;                                                                                  
>
>         ;; enable rb pins change interrupt, and it's pullups                                                  
>         bsf     intcon, rbie
>         bcf     intcon2, rbpu
>
>         ;; clear it's flag bit                                                              
>         bcf     intcon, rbif
>
>         ;; disable tmr0 interrupt                                                          
>         bcf     intcon, tmr0ie
>
>         ;; setup timer0: internal clock, 8 bits, prescale 1:64                              
>         movlw   b'01000101'
>         movwf   t0con
>
>         ;; globally enable interrupts                                                      
>         bsf     intcon, gie
>
> start:
>         ;; just loop, I acutally have code here for decomposing
>         ;; `counter' so I can display it on the segment leds
>         ;; (leading 0's not being displayed)
>         goto start
>
>
> and this is my `interrupts.s' file:
>
>
>         ;;                                                                                  
>         ;; variables                                                                        
>         ;;                                                                                  
> int_vars        udata
>         ;; these for high-priority interrupts                                              
> hp_w            res     1
> hp_bsr          res     1
> hp_status       res     1
>
>         ;;                                                                                  
>         ;; imported symbols                                                                
>         ;;                                                                                  
>         extern  counter
>
>         ;;                                                                                  
>         ;; exported symbols                                                                
>         ;;                                                                                  
>         global  hp_interrupt
>
>
>         ;;                                                                                  
>         ;; rb* interrupt-handler                                                            
>         ;;
> _handle_rb_interrupt    code
> handle_rb_interrupt:
>         ;; clear it's flag bit                                                              
>         bcf     intcon, rbif
>
>         ;; clear tmr0 and it's flag bit within `intcon',
>         ;; and turn it on                    
>         clrf    tmr0l
>         bcf     intcon, tmr0if
>         bsf     t0con, tmr0on
>
> loop:
>         ;; check for the flag bit being set as a result of an
>         ;; overflow on the timer
>         btfss   intcon, tmr0if
>         goto    loop
>
>         ;; then increment `counter' (should wait and debounce
>         ;; the switch's release also)                                                              
>         banksel counter
>         incf    counter, f
>
>         ;; toggle on a led used as feedback @ rc0
>         btg     latc, rc0
>
>         ;; turn off the timer
>         bcf     t0con, tmr0on
>
>         ;; and return
>         retlw   0
>
>         ;;
>         ;; high-priority interrupt vector                                                  
>         ;;
> __hp_interrupt  code
> hp_interrupt:
>         ;; save registers' status. I don't know if I'd be using
>         ;; also low priorities, so better to go this way just in
>         ;; case (datasheet says `retfie fast' could be
>         ;; unreliable if so)
>         movwf   hp_w
>         movff   bsr, hp_bsr
>         movff   status, hp_status
>
>         ;; if the interrupt was caused by a change on rb4:7, go
>         ;; to it's processing function
>         btfsc   intcon, rbif
>         call    handle_rb_interrupt
>
> exit_hp_interrupt:
>         movff   hp_bsr, bsr
>         movf    hp_w, w
>         movff   hp_status, status
>         retfie  0x0
>         end
>
> I tried with another led on ra0 and a `btfsc intcon, tmr0if btg lata, ra0' above, so what is happening that tmr0 is causing the chip to vector to 0x8 even when I explictly disabled it.
>
> Shouldn't be `tmr0if' just set, and not cause the chip to vector?
>
> Regards,
>
>
>
>
>      
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: gnupic-unsubscribe@...
> For additional commands, e-mail: gnupic-help@...
>
>
>  

---------------------------------------------------------------------
To unsubscribe, e-mail: gnupic-unsubscribe@...
For additional commands, e-mail: gnupic-help@...


Re: problems with timer0/interrupts

by Lope Vega :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

--- El mié, 3/9/08, George M. Gallant <ggallant571@...> escribió:

> De: George M. Gallant <ggallant571@...>
> Asunto: Re: [gnupic] problems with timer0/interrupts
> Para: gnupic@...
> Fecha: miércoles, 3 septiembre, 2008 2:16
> Lope,
>
> Just a some observations:
>   1. If you evr do get to hp_interrupt and it is not the
> change on rb,
>       you will be stuck here.

Yes I know it should be done safiest, but by now I'm just trying with it (unit-testing), so it should be ok.

>   2. The time is enabled with setting a value.

Am, I didn't know that, I thought it would always go from whatever the value of tmr0 to it's overflow value, while raising an interrupt (if enabled) on overflow.

>   3. Perhaps you could recode to use the timer interrupt.
>   4. Have you tried a simulator?

Yes, I'm using gpsim with a pic18f452 as processor, which is quite similar to the pic18f4550.

Gpsim has a bug though, and I have to test with the timer in 16 bit mode, cose the 8bit one seems to be broken, but it's ok.

Thanks I'll look at the timer thing more indeep.

>
> George
>
>
> Lope Vega wrote:
> > Hi guys,
> >
> > Thanks so much Robert, first of all. Both your code
> about table reads worked out of the box, and were also right
> about my missunderstanding of the variables' thing.
> >
> > I didn't think of trying to declare it as global
> and then try to use it in other modules.
> >
> > I'm having a problem now with interrupts/timer0.
> >
> > As petter suggested, I've started scanning 3 seven
> segment displays on my app's main function, while using
> interrupts to update a counter upon a switch's
> press/debounce.
> >
> > Then, what did was to setup interrupts for RB4:7
> pins' state change, and within it's processing
> function, try to use timer0 to debounce the switch.
> >
> > However, when I program the device and place it on
> it's side of the breadboard, it seems the pic falls into
> the interrupt, and that the timer0 polling causes it to
> recurse into it undefinetely.
> >
> > I'm gonna paste the relevant part of the code for
> if anyone want to give me some explanation.
> >
> > this is my main file:
> >
> >         ;;                                            
>                                      
> >         ;; variables                                  
>                                      
> >         ;;                                            
>                                      
> > main_vars       udata
> >         ;; main counter                              
>                                      
> > counter         res     1
> >         ;; temp variables                            
>                                      
> > digit           res     1
> > aux             res     1
> >
> >         ;;                                            
>                                      
> >         ;; imported symbols                          
>                                      
> >         ;;                                            
>                                      
> >         extern  hp_interrupt
> >         ;; a table read function, with a `movwf
> segments_port'
> >         ;; at the end of it
> >         extern  display  
> >
> >         ;;                                            
>                                      
> >         ;; exported symbols                          
>                                      
> >         ;;                                            
>                                      
> >         global  counter
> >         global  digit
> >
> >         ;;                                            
>                                      
> >         ;; reset vector                              
>                                      
> >         ;;                                            
>                                      
> > reset_vector    code    0x0
> >         goto    main
> >
> >         ;;                                            
>                                      
> >         ;; high-priority interrupt vector            
>                                      
> >         ;;                                            
>                                      
> > _hp_interrupt   code    0x8
> >         goto    hp_interrupt
> >
> >         ;;                                            
>                                      
> >         ;; app's entry point                      
>                                          
> >         ;;                                            
>                                      
> > main:
> >         ;;                                            
>                                      
> >         ;; ports' setup                          
>                                          
> >         ;;                                            
>                                      
> >
> >         ;; porta                                      
>                                      
> >         clrf    porta
> >         clrf    trisa
> >
> >         ;; portb, here I'm supossed to have a
> switch which is
> >         ;; active-low, thus, when pressed goes low,
> and this
> >         ;; ports' setup seems to be giving me
> problems also
> >         clrf    latb
> >         movlw   0xff
> >         movwf   trisb
> >
> >         ;; portc                                      
>                                      
> >         clrf    latc
> >         clrf    trisc
> >
> >         ;; portd                                      
>                                      
> >         clrf    latd
> >         clrf    trisd
> >
> >
> >         ;; porte                                      
>                                      
> >         clrf    late
> >         clrf    trise
> >
> >         ;;                                            
>                                      
> >         ;; interrupts                                
>                                      
> >         ;;                                            
>                                      
> >
> >         ;; enable rb pins change interrupt, and
> it's pullups                                            
>      
> >         bsf     intcon, rbie
> >         bcf     intcon2, rbpu
> >
> >         ;; clear it's flag bit                    
>                                          
> >         bcf     intcon, rbif
> >
> >         ;; disable tmr0 interrupt                    
>                                      
> >         bcf     intcon, tmr0ie
> >
> >         ;; setup timer0: internal clock, 8 bits,
> prescale 1:64                              
> >         movlw   b'01000101'
> >         movwf   t0con
> >
> >         ;; globally enable interrupts                
>                                      
> >         bsf     intcon, gie
> >
> > start:
> >         ;; just loop, I acutally have code here for
> decomposing
> >         ;; `counter' so I can display it on the
> segment leds
> >         ;; (leading 0's not being displayed)
> >         goto start
> >
> >
> > and this is my `interrupts.s' file:
> >
> >
> >         ;;                                            
>                                      
> >         ;; variables                                  
>                                      
> >         ;;                                            
>                                      
> > int_vars        udata
> >         ;; these for high-priority interrupts        
>                                      
> > hp_w            res     1
> > hp_bsr          res     1
> > hp_status       res     1
> >
> >         ;;                                            
>                                      
> >         ;; imported symbols                          
>                                      
> >         ;;                                            
>                                      
> >         extern  counter
> >
> >         ;;                                            
>                                      
> >         ;; exported symbols                          
>                                      
> >         ;;                                            
>                                      
> >         global  hp_interrupt
> >
> >
> >         ;;                                            
>                                      
> >         ;; rb* interrupt-handler                      
>                                      
> >         ;;
> > _handle_rb_interrupt    code
> > handle_rb_interrupt:
> >         ;; clear it's flag bit                    
>                                          
> >         bcf     intcon, rbif
> >
> >         ;; clear tmr0 and it's flag bit within
> `intcon',
> >         ;; and turn it on                    
> >         clrf    tmr0l
> >         bcf     intcon, tmr0if
> >         bsf     t0con, tmr0on
> >
> > loop:
> >         ;; check for the flag bit being set as a
> result of an
> >         ;; overflow on the timer
> >         btfss   intcon, tmr0if
> >         goto    loop
> >
> >         ;; then increment `counter' (should wait
> and debounce
> >         ;; the switch's release also)            
>                                                
> >         banksel counter
> >         incf    counter, f
> >
> >         ;; toggle on a led used as feedback @ rc0
> >         btg     latc, rc0
> >
> >         ;; turn off the timer
> >         bcf     t0con, tmr0on
> >
> >         ;; and return
> >         retlw   0
> >
> >         ;;
> >         ;; high-priority interrupt vector            
>                                    
> >         ;;
> > __hp_interrupt  code
> > hp_interrupt:
> >         ;; save registers' status. I don't
> know if I'd be using
> >         ;; also low priorities, so better to go this
> way just in
> >         ;; case (datasheet says `retfie fast'
> could be
> >         ;; unreliable if so)
> >         movwf   hp_w
> >         movff   bsr, hp_bsr
> >         movff   status, hp_status
> >
> >         ;; if the interrupt was caused by a change on
> rb4:7, go
> >         ;; to it's processing function
> >         btfsc   intcon, rbif
> >         call    handle_rb_interrupt
> >
> > exit_hp_interrupt:
> >         movff   hp_bsr, bsr
> >         movf    hp_w, w
> >         movff   hp_status, status
> >         retfie  0x0
> >         end
> >
> > I tried with another led on ra0 and a `btfsc intcon,
> tmr0if btg lata, ra0' above, so what is happening that
> tmr0 is causing the chip to vector to 0x8 even when I
> explictly disabled it.
> >
> > Shouldn't be `tmr0if' just set, and not cause
> the chip to vector?
> >
> > Regards,
> >
> >
> >
> >
> >      
> >
> >
> >
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail:
> gnupic-unsubscribe@...
> > For additional commands, e-mail:
> gnupic-help@...
> >
> >
> >  
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: gnupic-unsubscribe@...
> For additional commands, e-mail:
> gnupic-help@...





---------------------------------------------------------------------
To unsubscribe, e-mail: gnupic-unsubscribe@...
For additional commands, e-mail: gnupic-help@...


Re: problems with timer0/interrupts

by Robert Pearce-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 3 Sep 2008, Lope Vega <vega_lope@...> wrote :
>
>Then, what did was to setup interrupts for RB4:7 pins' state change,
>and within it's processing function, try to use timer0 to debounce the
>switch.
>
>However, when I program the device and place it on it's side of the
>breadboard, it seems the pic falls into the interrupt, and that the
>timer0 polling causes it to recurse into it undefinetely.

>        ;;
>        ;; rb* interrupt-handler
>        ;;
>_handle_rb_interrupt    code
>handle_rb_interrupt:
--- you need to add
        movf    portb,w
    here ---
>        ;; clear it's flag bit
>        bcf     intcon, rbif
>

If I remember rightly, the portb interrupt on change function continues
to see the change until you read portb. You are not reading portb in
your ISR, so clearing the rbif bit is not doing any good.
--
Rob Pearce                       http://www.bdt-home.demon.co.uk

The contents of this | Windows NT crashed.
message are purely   | I am the Blue Screen of Death.
my opinion. Don't    | No one hears your screams.
believe a word.      |

---------------------------------------------------------------------
To unsubscribe, e-mail: gnupic-unsubscribe@...
For additional commands, e-mail: gnupic-help@...