Searching \ for '[PIC] 30 seconds Time out' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/time.htm?key=time
Search entire site for: '30 seconds Time out'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] 30 seconds Time out'
2007\08\27@222507 by Carolina Dieguez

picon face
Hi all!
       A month ago I've written to you about this issue. Jinx had given a
great explanation to me but I was not able to try the alternatives he has
mentioned untill now...

       In this simple case I'm just trying to turn a led on for 30 seconds
and then turn it off caused y a timer interruption.

       This is my code and it is wrong but I'm just a rookie, I do not know
why:o)

LIST P=16F873A, R=DEC    ; Use the PIC16F873 and decimal system
#include "P16F873A.INC"  ; Include header file
__config  _CP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF & _BODEN_ON

CBLOCK 0x20             ; Declare variable addresses
         Loop1,Loop2,Count
         w_temp,status_temp
ENDC

GOTO    Main
; ------------------------
; INTERRUPCIONES DE TIMER1
; ------------------------

                   ORG     0x004

                   movwf    w_temp                ; save off current W
register contents
                   swapf    STATUS,W           ; move status register into
W register
                   clrf        STATUS               ; select Bank 0
                   movwf   status_temp          ; save off contents of
STATUS register

                   BANKSEL    PIR1
                   BTFSS         PIR1,TMR1IF
                   GOTO          EXIT

RELOAD
                   DECFSZ    Count            ; If Count reach 000h then
almost 30 seconds have already passed
                   GOTO        $+4

                   BCF     PORTA,0
                   call      delay
                   GOTO  EXIT

                   CLRF    TMR1L        ; I do not know if it is necessary
to clear register TIMER1 once interruption is serviced (I guess it is done
automatically)
                   CLRF    TMR1H
EXIT
                   MOVF      status_temp,w
                   MOVWF   STATUS
                   SWAPF    w_temp,f
                   SWAPF    w_temp,w
                   RETFIE

; ------------------------
; INICIALIZACION
; ------------------------

INIT    CLRF   PORTA           ; Initialize port A
        CLRF   PORTB           ; Initialize port B
        CLRF   PORTC           ; Initialize port C

        BSF    STATUS,RP0      ; RAM bank 1

       CLRF   TRISA           ; All pins port A output
       CLRF   TRISB           ; All pins port B output
       CLRF   TRISC           ; All pins port C output

       CLRF    PIE1                       ; Mask all peripheral interrupts
except
       bsf        PIE1,TMR1IE           ; the timer 1 interrupts.
       BCF      STATUS, RP0          ; Bank0
       CLRF     PIR1                       ; Clear peripheral interrupts
Flags
       movlw    B'00110001'              ; Valor de Prescale = 8, Timer 1
Habilitado
       movwf    T1CON
       bsf         INTCON,GIE             ; Global interrupt enable.

       MOVLW   d'57'
       MOVWF   Count

       GOTO    Loop
; ------------------------
; FUNCTION OF PORT A PINS
; ------------------------
       MOVLW    6
       MOVWF    ADCON1           ; All pins digital I/O
       BCF          STATUS,RP0    ; RAM bank 0
; ----------
; MAIN LOOP
; ----------

Main    org         h'80'
          GOTO    INIT
Loop    BSF       PORTA,0        ; Turn on LED connected to RA0
          CALL      delay
          GOTO     Loop
; ---------------
; DELAY 250 MSEC
; ---------------
delay   MOVLW   250
          MOVWF   Loop1
Outer   MOVLW   200
          MOVWF   Loop2
Inner    NOP
          NOP
          DECFSZ  Loop2,F
          GOTO    Inner          ; Inner loop = 5 usec.
          DECFSZ  Loop1,F
          GOTO    Outer
          RETURN

          END

I hope you can help me!

Thanks,
          Carol.

2007\08\27@233400 by Jinx

face picon face
Hi Carol, some general comments here, and specific comments in code.
Good start, just needs some tidying up

First, try to be consistent. For example, you use a mix of banksel and
setting status bits directly. Either work but not quite so easy to read
(for you, most importantly). Better to stick with banksel throughout

Also the mixed cases and variables. For example you've set radix to
decimal but use d'57' and then just 6

Secondly, I personally prefer to assign code locations with org. I think
yours should compile correctly into memory though from 0x0005

Do you use tabs ? The line alignment is very staggered. Spaces are better.
Tabs are the devil's work

>                     GOTO        $+4

This would be much safer jumping to a label, although what it jumps to
(clear TMR1) is not necessary

>                     CLRF    TMR1L        ; I do not know if it is
necessary
> to clear register TIMER1 once interruption is serviced (I guess it is done
> automatically)
>                     CLRF    TMR1H

True. TMR1 = 0000 is the cause of the interrupt. By resetting TMR1
you've lost time, as it had already advance past 0000

> ; ------------------------
> ; FUNCTION OF PORT A PINS
> ; ------------------------
>         MOVLW    6
>         MOVWF    ADCON1           ; All pins digital I/O
>         BCF          STATUS,RP0    ; RAM bank 0

This bit of code is never accessed because of the goto right before it

2007\08\28@091750 by Howard Winter

face
flavicon
picon face
Carol,

I agree with Jinx on all points... starting with the beginning of the program, put ORG 0 before the first instruction (GOTO Main) - I don't know where it
would put it if you don't specify, and it may well be 0, but everyone puts it in so why not keep to that?  :-)

It's unusual to use a GOTO to a routine (INIT) and then at the end GOTO the instruction after it - you may as well use CALL and RETURN.  It's not
wrong, but it does look very much what a rookie would do!  :-)  Why have you put ORG h'80' at Main, by the way?

For a more conventional structure, you may want to consider:

ORG 0
 CALL INIT
 GOTO MAIN
ORG 4
 - interrupt processing...
 RETFIE
INIT
- initialisation...
 RETURN
MAIN
- main loop...
 GOTO MAIN
DELAY
- etc...

I don't see anywhere that you initialise Timer1's counter registers - it may well start at 0, but it's good practice to make sure by setting it yourself.

You move 57 into your Count variable during initialisation, but you don't reload it after an interrupt, so it will only do the loop 57 times, once!  :-)  
After that it will do it 256 times, since Count would start at 0 and count down.

You say it doesn't work, but you don't say how - how does it behave?

Cheers,


Howard Winter
St.Albans, England


2007\08\28@223827 by Carolina Dieguez

picon face
I appreaciate you both your help.

Thanks Jinx an of course, you are right. I'm trying to improve my code
writing:o)

Anyway, my code is still not working:o) The led turns on and never turns
off...

CBLOCK 0x20             ; Declare variable addresses
     LOOP1,LOOP2,CONTADOR
     W_TEMP,STATUS_TEMP
 ENDC

 ORG     00h
 CALL    INIT
 GOTO   MAIN

; ------------------------
; TIMER1 INTERRUPTION
; ------------------------

                   ORG        0x004

                   MOVWF  W_TEMP                  ; save off current W
register contents
                   SWAPF   STATUS,W               ; move status register
into W register
                   CLRF       STATUS                   ; select Bank 0
                   MOVWF   STATUS_TEMP        ; save off contents of STATUS
register

                   BANKSEL  PIR1
                   BTFSS       PIR1,TMR1IF
                   GOTO        EXIT

RELOAD
                   BCF          PIR1, TMR1IF
                   DECFSZ    CONTADOR        ; Si el Contador es cero, ya
pasaron los 30 segundos
                   GOTO        EXIT

                   BCF          PORTA,0
                   CALL        DELAY
                   MOVLW    d'25'                 ; Deberia ir un valor de
57
                   MOVWF    CONTADOR
EXIT
                   MOVF       STATUS_TEMP,W
                   MOVWF    STATUS
                   SWAPF     W_TEMP,F
                   SWAPF     W_TEMP,W
                   RETFIE

; ------------------------
; INICIALIZACION
; ------------------------

INIT               BCF    STATUS,RP1
                   BCF    STATUS,RP0

                   CLRF   PORTA               ; Initialize port A
                   CLRF   PORTB               ; Initialize port B
                   CLRF   PORTC               ; Initialize port C

                   BSF    STATUS,RP0      ; RAM bank 1

                   CLRF   TRISA                 ; All pins port A output
                   CLRF   TRISB                 ; All pins port B output
                   CLRF   TRISC                 ; All pins port C output

                   CLRF        PIE1                  ; Mask all peripheral
interrupts except
                   BSF          PIE1,TMR1IE     ; the timer 1 interrupts.
                   BCF          STATUS, RP0    ; Bank0
                   CLRF        PIR1                  ; Clear peripheral
interrupts Flags
                   MOVLW    B'00110001'        ; Valor de Prescale = 8,
Timer 1 Habilitado
                   MOVWF    T1CON
                   bsf             INTCON,GIE       ; Global interrupt
enable.

                   CLRF         TMR1L
                   CLRF         TMR1H

                   MOVLW     d'57'
                   MOVWF     CONTADOR

; ------------------------
; FUNCTION OF PORT A PINS
; ------------------------
                   BSF          STATUS,RP0

                   MOVLW    d'6'
                   MOVWF    ADCON1         ; All pins digital I/O

                   BCF          STATUS,RP0    ; RAM bank 0

                   RETURN
; ----------
; MAIN LOOP
; ----------
MAIN            BSF       PORTA,0        ; Turn on LED connected to RA0
                   CALL     DELAY
                   GOTO    MAIN

; ---------------
; DELAY 250 MSEC
; ---------------
DELAY             MOVLW   250
                       MOVWF   LOOP1
OUTER             MOVLW   200
                       MOVWF   LOOP2
INNER              NOP
                       NOP
                       DECFSZ  LOOP2,F
                       GOTO    INNER          ; Inner loop = 5 usec.
                       DECFSZ  LOOP1,F
                       GOTO    OUTER
                       RETURN

                       END
;***************************************************************************************


Cheers (I like that!)

                         Caro.

P.S.: I know it may be difficult to read my code and I'm sorry. It's
impossible to use tabs within gmail...


On 8/28/07, Howard Winter <spam_OUTHDRWTakeThisOuTspamh2org.demon.co.uk> wrote:
{Quote hidden}

> -

2007\08\28@235143 by Jinx

face picon face
Hi Carol, I'm wondering about this in the ISR

                    BCF          PORTA,0
                    CALL        DELAY

The TMR1 period is 524ms (8 * 65.536ms), which is longer than
the 250ms delay, and GIE is off, so TMR1 isn't interrupting at this
point, but it is still running. If you want to keep the delay in there,
perhaps turn TMR1 off before CALL DELAY and back on after
it

MAIN            BSF       PORTA,0        ; Turn on LED
                   CALL     DELAY
                   GOTO    MAIN

Here the delay isn't really necessary, and is IMVHO a complication
that doesn't do anything. It's likely that the interrupt will occur during
DELAY, then the ISR calls it too. Context is being saved, which is
good, but it just seems 'messy'. I'd suggest removing both CALL
DELAYs and see what happens. TMR1 will provide both the on
(57 * 0.5s) and off (1 * 0.5s) times. It's possible you have a race
condition, where you have hardware (TMR1) and s/w (DELAY)
competing and messing up the stack as a result. Possibly. I haven't
tracked it right through

The initialisation looks OK. As far as I can tell, what you should be
seeing is the LED on for quite a while and then off for 0.75s, but I
think there's a timing management issue going on preventing that

2007\08\29@120236 by Howard Winter

face
flavicon
picon face
Carol,

I've forgotten which processor you're using, but this in the ISR:

{Quote hidden}

Makes me wonder: are PIR1, CONTADOR, and PORTA all in the same Bank?  If not, there's a definite bug there!

I suspect you need BANKSELs in at least two places here, and possibly at the start of EXIT too, otherwise you're leaving the ISR with an indeterminate
Bank selected.

Cheers,


Howard Winter
St.Albans, England


2007\08\29@181724 by Jinx

face picon face
> Makes me wonder: are PIR1, CONTADOR, and PORTA all in
> the same Bank?  If not, there's a definite bug there!

Howard, I've done so much with 18F for a couple of years that I
really, well almost, struggled to get my head back into 16F banking.
It's such a PITA

2007\08\29@185544 by Howard Winter

face
flavicon
picon face
Carol,

I've been having a bit of a play with your program, simplifying and rearranging it a bit, and I have it working on a 16F690 (I happened to have one
handy!).  I've added quite a few BANKSELs just in case - careful investigation could reveal that some of them are removeable.

What it does is turn the LED on at the start, then every 30 seconds it flashes OFF for 1 DELAY time.  I had to change to using Port C as that's where
the LEDs are on the board I was using.  I've removed the call to DELAY in the Main loop - it doesn't achieve anything.  All the work is done in the ISR,
which isn't ideal, but it does work!  The potential problem is that calling DELAY in the ISR means that there could be a further interrupt while it's in
the delay loop, although with the current timing this won't happen.

Oh, and I don't think you were setting the Peripheral Interrupt Enable (PEIE) - this may have been the problem!  :-)

This is what I ended up with:

; ***  PROCESSOR   PIC16F873A
; ***  INCLUDE     P16F873A.inc
 
PROCESSOR PIC16F690
INCLUDE     "P16F690.inc"

 errorlevel    -306
 __config    _XT_OSC & _WDT_OFF & _PWRTE_ON

 RADIX       Dec         ; Numbers are Decimal unless otherwise specified
 
 CBLOCK 0x20             ; Declare variable addresses
     LOOP1
     LOOP2
     CONTADOR
     W_TEMP
     STATUS_TEMP
 ENDC

; ================
 ORG     000
         CALL    INIT
         GOTO    MAIN

; ------------------------
; TIMER1 INTERRUPTION
; ------------------------
 ORG 004
         MOVWF   W_TEMP           ; save off current W register contents
         SWAPF   STATUS,W         ; move status register into W register
         CLRF    STATUS              ; select Bank 0
         MOVWF   STATUS_TEMP   ; save off contents of STATUS register

         BANKSEL PIR1
         BTFSS   PIR1,TMR1IF      ; Was it a Timer1 Interrupt?
          GOTO   EXIT             ;  No, skip out

RELOAD                             ;  Yes, process it
         BCF     PIR1, TMR1IF     ; Clear the interrupt indication
         BANKSEL CONTADOR
         DECFSZ  CONTADOR         ; Si el Contador es cero, ya pasaron los 30 segundos
          GOTO   EXIT

         BANKSEL PORTC
         BCF     PORTC,0         ; Turn LED OFF
         CALL    DELAY           ; Wait a bit
         BSF     PORTC,0         ; Turn LED ON
         MOVLW   57              ; Deberia ir un valor de 57
         MOVWF   CONTADOR        ; Reset the counter for 30 secs
EXIT
         MOVF    STATUS_TEMP,W   ; Restore the environment
         MOVWF   STATUS
         SWAPF   W_TEMP,F
         SWAPF   W_TEMP,W
         RETFIE

; ------------------------
; INICIALIZACION
; ------------------------
INIT
         BANKSEL PORTA
         CLRF    PORTA           ; Initialize port A
         CLRF    PORTB           ; Initialize port B
         CLRF    PORTC           ; Initialize port C

         BANKSEL TRISA

         CLRF    TRISA           ; All pins port A output
         CLRF    TRISB           ; All pins port B output
         CLRF    TRISC           ; All pins port C output

         CLRF    PIE1            ; Mask all peripheral interrupts except
         BSF     PIE1,TMR1IE     ;  the timer 1 interrupt
         BANKSEL TMR1L
         CLRF    TMR1L           ; Clear the initial timer count
         CLRF    TMR1H

         BANKSEL PIR1
         CLRF    PIR1            ; Clear peripheral interrupts Flags
         MOVLW   B'00110001'     ; Valor de Prescale = 8, Timer 1 Habilitado
         MOVWF   T1CON
         BSF     INTCON,PEIE     ; Peripheral Interrupt Enable
         BSF     INTCON,GIE      ; Global interrupt enable.

         BANKSEL  CONTADOR
         MOVLW    57             ; Load the Interrupt Counter for 30 seconds
         MOVWF    CONTADOR

; ------------------------
; FUNCTION OF PORT A PINS
; ------------------------
         BANKSEL  ADCON1
         MOVLW    6
         MOVWF    ADCON1         ; All pins digital I/O
         BANKSEL  PORTC
         BSF      PORTC,0        ; Turn on LED connected to RC0
         RETURN

; ----------
; MAIN LOOP
; ----------
MAIN
         GOTO    MAIN

; ---------------
; DELAY 250 mSec
; ---------------
DELAY     MOVLW   250
             MOVWF   LOOP1
OUTER     MOVLW   200
             MOVWF   LOOP2
INNER      NOP
             NOP
             DECFSZ  LOOP2,F
              GOTO   INNER           ; Inner loop = 5 usec.
             DECFSZ  LOOP1,F
              GOTO   OUTER
             RETURN
END

I hope this is useful!

Cheers,


Howard Winter
St.Albans, England


2007\08\29@200856 by Carolina Dieguez

picon face
Hey, Jinx!

Thanks a lot for your explanation, it was perfect. In fact, the moment I've
read you e-mail I thought of myself as a fool!

The first thing I've done was changed that, once at home... But it did not
work either:o)

I'm using a PIC 16F873A. I do not know whether this has to do or not but the
fact is that I was not setting bit PEIE. Once it was done, it worked! This
shows more about my rookie situation:o((((

I'm glad I can count on you.

Many thanks to you BOTH!!!!!

                                          Caro.

P.S.: As it says "Peripheral Interrupt Enable" I thought it wouldn't be
necessary.

On 8/29/07, Howard Winter <.....HDRWKILLspamspam@spam@h2org.demon.co.uk> wrote:
{Quote hidden}

> -

2007\08\29@202041 by Carolina Dieguez

picon face
Howard,
          One more thing...
          Do you say "All the work is done in the ISR, which isn't ideal,
but it does work". Please, why do you think that?

          Many thanks for takig your time to help me.

          Caro.


On 8/29/07, Howard Winter <HDRWspamKILLspamh2org.demon.co.uk> wrote:
{Quote hidden}

> -

2007\08\29@220325 by Jinx

face picon face
> Oh, and I don't think you were setting the Peripheral Interrupt
> Enable (PEIE) - this may have been the problem!  :-)

Good catch, didn't even see that missing

2007\08\29@222315 by Jinx

face picon face
> setting bit PEIE. Once it was done, it worked ! This
> shows more about my rookie situation:o((((

That's great news. Although it can be frustrating, I think it does
more good than harm to have to work it out, rather than just
type in a program that works. You learn by doing, not copying
(no offense intended)

And now you're not a rookie !

If you're able to program them I'd recommend you sample
some 18F (http://www.sample.microchip.com I think) and use
those too in the future. Perhaps a couple of 18F1320 and a
couple of 18F2520 (like a super-16F873) or 18F4520

2007\08\30@061921 by Howard Winter

face
flavicon
picon face
Carol,

On Wed, 29 Aug 2007 21:20:39 -0300, Carolina Dieguez wrote:

> Howard,
>            One more thing...
>            Do you say "All the work is done in the ISR, which isn't ideal,
> but it does work". Please, why do you think that?

Well in this case it's not a problem because it's such a simple problem, but usually the main loop would be doing something - maybe a lot of things! -
and having the interrupt routine take a lot of time is bad because it may delay something important in the main loop.  As a general rule, you want to
spend as little time as possible in the ISR.

To turn this into a more generally useful solution, the ISR would just set an indicator to say that the 30 seconds is up and then return.  Then within
the main loop you'd check the indicator at a point where nothing critical is about to happen, and do the time-consuming part if the indicator is set.

As I say, in this case there is nothing else happening, so it's not a problem.

>            Many thanks for takig your time to help me.

No problem - I like to dabble in other peoples' programs from time to time - ask my former programming team and I'm sure they'd say I did it far too
much!  :-)

Incidentally, doing this I discovered a new way of working, using PICkit2 and MPLAB.  The latest software for PICkit2 has a button "Auto import Hex
and write device", which when active will watch a .HEX file that you specify, and when it changes it programs the PIC with it.  So I left this running,
connected to the PICkit2 and its development board with the "Target power" on, and edited the program in MPLAB.  When I did a Build that had no
errors and resulted in a new .HEX file being created, it was seen by the PICkit2 software and immediately programmed into the PIC, which then ran
the new version, so instead of a edit-compile-program-test cycle, it was just edit-compile and the rest happened automatically.  Neat!  :-)

Cheers,


Howard Winter
St.Albans, England


2007\08\30@095600 by Jamesp

picon face

We interrupt this PICLIST for this important message.....

My 2 cents worth.   I have heard many people on this list and elsewhere
stating that the banking scheme on the PIC parts is so much of a pain.
My take on the matter is it's a pain if you wnat it to be or if you let
it be.  I don't have that much difficulty with it.  I consider it a part
of the programming process.  If it didn't have to be done, that would be
great.  But it does have to be done, and if you constantly keep thinking
it's going to be a PITA, then it will be.

And if it's always that much of a pain, move to a processor that doesn't
use it, whether that be a different chip from Microchip, or a completely
different vendor.

I just don't see what all the fuss is about regarding banking.

Now back to your regularly scheduled PICLIST traffic.


                                               Regards,

                                                 Jim




>> Makes me wonder: are PIR1, CONTADOR, and PORTA all in
>> the same Bank?  If not, there's a definite bug there!
>
> Howard, I've done so much with 18F for a couple of years that I
> really, well almost, struggled to get my head back into 16F banking.
> It's such a PITA
>
> --

2007\08\30@103835 by Alan B. Pearce

face picon face
>And if it's always that much of a pain, move to a processor
>that doesn't use it, whether that be a different chip from
>Microchip, or a completely different vendor.
>
>I just don't see what all the fuss is about regarding banking.

I don't either - I just use Olins development environment macros and that
gives conditional assembly of the banking and paging instructions. If the
instruction is not needed then it doesn't get assembled.

Does create the occasional gotcha still though, but reduces the headache
factor to a minor annoyance.

2007\08\30@181452 by Jinx

face picon face
>  I just don't see what all the fuss is about regarding banking.

Hi Jim, have you ever used an 18F ?

Don't misunderstand - I use PICs from every range. They all
have their advantages, technically and commercially. I've used
PICs for a very long time and am quite comfortable dealing with
banking when I have to. I just prefer not to have to these days
if there's an alternative

> I consider it a part of the programming process

Banking caused me to drop a 16F part and move to an 18F for
a product. Why ? Because having to switch banks really messed
up the top speed of a transfer routine. So it's not always about
the "nuisance" value, bank switching does slow routines down

> move to a processor that doesn't use it, whether that be a
> different chip from Microchip, or a completely different vendor

There are many micros, some historic, that have NEVER used
banking. Whether you can say banking was a poor initial design
decision by Microchip is debatable. I'm sure they had their reasons

2007\08\30@183754 by PAUL James

picon face


-----Original Message-----
From: .....piclist-bouncesKILLspamspam.....mit.edu [EraseMEpiclist-bouncesspam_OUTspamTakeThisOuTmit.edu] On Behalf
Of Jinx
Sent: Thursday, August 30, 2007 5:14 PM
To: Microcontroller discussion list - Public.
Subject: Re: [PIC] 30 seconds Time out

>  I just don't see what all the fuss is about regarding banking.

Hi Jim, have you ever used an 18F ?

***** Yes

Don't misunderstand - I use PICs from every range. They all have their
advantages, technically and commercially. I've used PICs for a very long
time and am quite comfortable dealing with banking when I have to. I
just prefer not to have to these days if there's an alternative

> I consider it a part of the programming process

Banking caused me to drop a 16F part and move to an 18F for a product.
Why ? Because having to switch banks really messed up the top speed of a
transfer routine. So it's not always about the "nuisance" value, bank
switching does slow routines down.


***** I'm sure this is true.  I've never had it slow my routines down
though.  Of course, I've never
     Programmed anything that needed to be so quick that this was a
bottleneck.



> move to a processor that doesn't use it, whether that be a different
> chip from Microchip, or a completely different vendor

There are many micros, some historic, that have NEVER used banking.
Whether you can say banking was a poor initial design decision by
Microchip is debatable. I'm sure they had their reasons.

***** Whatever Microchip's design philosophy regarding the banking
scheme, and for the others as well,
     I don't know that is was a poor design decision, or a good design
decision.  I'm sure it was made
     allow the parts to work, and that was the method that made the
most sense at the time.  




       
Regards,

       
Jim

2007\08\30@214133 by Carolina Dieguez

picon face
Howard,
          You've also asked me some days before about writing "org  80h". I
guess I did not even consider that seriously, I've used "org 00h" times
before and now I wanted to know what happened.

          I think this has to do with the fact I'm still not so sure about
PIC memory and where or in which order set the ISR, inicialisation part,
main program and then the subrrutines.

          I've followed your scheme:

          ORG 0
          CALL INIT
          GOTO MAIN
          ORG 4
          - interrupt processing...
          RETFIE
          INIT
          - initialisation...
          RETURN
          MAIN
          - main loop...
         GOTO MAIN
         DELAY
         - etc...

         However, in other examples,  I  try to do it this way -subrrutines
at the last part of the whole code- and compiler do not make its job saying
I'm  "Overwriting previous address contents (0000)"

        May be you know some tutorial I can read about this issue.

        Bye!
               Carol.

On 8/30/07, Howard Winter <HDRWspamspam_OUTh2org.demon.co.uk> wrote:
{Quote hidden}

> -

2007\08\30@230219 by Jinx

face picon face
Hi Carol,

> I think this has to do with the fact I'm still not so sure about PIC
> memory

Each datasheet has a memory map. In your editor (MPLAB ?) you
can see where instructions are put after compilation. Select View /
Program Memory

> and where or in which order set the ISR, inicialisation part,
> main program and then the subrrutines.

At the bottom of memory are the jump vectors. For the F87x there
are just two ; Reset, at location 00 and Interrupt, at location 04.
Memory for the user's program starts at 05

Say you have this (it's not how you might normally do it but just
as an example)

org 0x000
goto main

og 0x004
goto isr

org 0x080 ; interrupt service routine starts at location 0x080
isr code

org 0x100 ; main body starts at location 0x100
main code

After compilation of the above you'll see in memory

000 2900 GOTO MAIN ; jump to MAIN after a reset
(blank, 3FFFs)
004 2880 GOTO ISR ; jump to ISR on an interupt
(blank, 3FFFs)
080 ISR code

100 MAIN code

Say you didn't include orgs, and had just a Reset jump and some ISR
code before MAIN

GOTO MAIN
irq movwf    w_temp
   swapf    STATUS,W
   clrf        STATUS
   movwf   status_temp
   retfie
main GOTO    INIT
Loop BSF       PORTA,0
    CALL      delay
    GOTO     Loop

Would compile as

000 GOTO MAIN
001 MOVWF W_TEMP ; IRQ
002 SWAPF STATUS,W
003 CLRF STATUS
004 MOVWF STATUS_TEMP
005 RETFIE
006 GOTO INIT ; MAIN
007 BSF PORTA,0
008 CALL DELAY
009 GOTO 007

Program code is in the 0x004 vector. Which will do no harm if
interrupts are not being used

With (the recommended) orgs

org 0x000
goto main
org 0x004
goto irq

actual code would compile into memory directly after the vectors (at 0x005)

000 GOTO MAIN
001 3FFF
002 3FFF
003 3FFF
004 GOTO IRQ
005 MOVWF W_TEMP ; IRQ
006 SWAPF STATUS,W
007 CLRF STATUS
008 MOVWF STATUS_TEMP
009 RETFIE
00A GOTO INIT ; MAIN
00B BSF PORTA,0
00C CALL DELAY
00D GOTO 00B

As for where routines can go, that's largely a matter of personal
taste. Some people put the ISR at the bottom of memory, mine
are usually in the body of the code. 'Library' routines such as delays
or display drivers are at the end of code, out of the (my) way. It
can sometimes be helpful to put data in the same page as the calling
routine so you don't need to worry about PCLATH. Mostly issues
like that are a minor inconvenience though

> However, in other examples,  I  try to do it this way -subrrutines
> at the last part of the whole code- and compiler do not make its job
> saying I'm  "Overwriting previous address contents (0000)"

Possibly you're putting an org too high in memory for the size of the
routines and the code is wrapping around to the start address

> May be you know some tutorial I can read about this issue.

You could try MPLAB's Help / Topics / MPASM Assembler. For
example the differences between absolute and relocatable code, org,
memory useage, RAM bank access, interrupt handling etc

2007\08\31@064947 by Howard Winter

face
flavicon
picon face
Carol,

Jinx has answered this comprehensively...

On Thu, 30 Aug 2007 22:41:31 -0300, Carolina Dieguez wrote:

{Quote hidden}

This is a wrap-round of the program counter - either the whole program is too big to fit the chip (upgrade to a bigger chip) or you used ORG and left
too big a gap.  Make the gap smaller (or remove it completely) in this case.

My example is just that - an example, not a rule.  I just used your original layout and changed it a little, it's not necessarily what I would always use,
although it is close!  You can organise your code in memory as you like, with the only fixed items being the two vectors (0 and 4) as Jinx mentioned.  
As long as you have something appropriate at these two addresses (or, if you never activate GIE, only the first one), the rest is up to you.

Personally I like to have the ISR starting at 4, because I don't like having a GOTO that's not necessary, then the initialisation, then the Main code, then
the subroutines.  This is probably because the first language I used commercially (COBOL) tends to encourage this.  Other people have the Main at the
end and subroutines in front, others have the subroutines interleaved through the Main loop so they're close to the code that calls them.  This can be
easier to navigate when you're reading the program, but can end up with a lot of GOTOs to step over the subroutines, and it can obscure the main
logic flow.

Then there's the question of where to put the various pieces of code.  At one end of the scale you can have a Main Loop with no subroutines at all,
all the code is "in line".  At the other extreme the Main Loop does nothing but call subroutines (or in the case we're discussing, nothing at all except
wait for an Interrupt).  I try to have the program structure mimic the problem.  If the problem is a simple sequence of events, I tend to have the
sequence progress through the Main Loop.  If a lot of things happen that aren't in a sequence (responding to external events, including timers) then I
tend to have the Main Loop doing nothing but calling subroutines as they are needed.  Of course, the Main "loop" doesn't have to be looping all the
time, it can go to sleep if there's nothing happening and rely on interrupts to wake it up.

My advice is to go for the simplest structure that works, and that seems logical to you.  If you are the only one who has to understand it, that's the
most important thing - it's only when you start posting it here that others will see it, so at that point it needs to be "obvious" so that we can
understand it too!

But to sum up: Find a structure that you like!  :-)

Cheers,


Howard Winter
St.Albans, England


2007\08\31@075628 by Jinx

face picon face
> Personally I like to have the ISR starting at 4, because I don't
> like having a GOTO that's not necessary

That's a good point Howard. Never thought of that. I've always
treated and used the ISR as a separate routine in or after main
code. Losing a goto will be quicker. Micros with fast-execution
Zero Page indexing (8-bit address) need the source at 00-FF, but
I think all PIC fetch/store operations (short range at least) are 1
cycle anyway

2007\08\31@092446 by Dario Greggio

face picon face
Howard Winter wrote:

> Personally I like to have the ISR starting at 4, because I don't like having a GOTO that's not necessary, then the initialisation, then the Main code, then
> the subroutines.  

Hi Howard, actually placing a GOTO at ISR beginning, can cause problems
on those parts (16F and lower I mean) having more than one page of code,
since this could trash PCLATH *before* you save it.

--
Ciao, Dario

2007\08\31@170414 by Robert Rolf

picon face


Dario Greggio wrote:

{Quote hidden}

No, WILL cause problems if he has code in other than the first page.
Been there. Done that. Have the bruises on the forehead to prove it.

You MUST save W, STATUS & PLATH state, and point to your GOTO page before jumping
anywhere, or you'll be very sorry.

Robert


'[PIC] 30 seconds Time out'
2007\09\01@113651 by Carolina Dieguez
picon face
Jinx,
     Soon after sending my question I've realized I have to play with MPLAB
and its memory map view. Anyway, your detailed explanation is revealing:o)
     Thank you very much.


On 8/31/07, Jinx <@spam@joecolquittKILLspamspamclear.net.nz> wrote:
{Quote hidden}

> -

2007\09\01@113812 by Carolina Dieguez

picon face
"Jinx has answered this comprehensively..."

No doubt about it!

... You too, thanks!


On 8/31/07, Howard Winter <KILLspamHDRWKILLspamspamh2org.demon.co.uk> wrote:
{Quote hidden}

> -

2007\09\01@183823 by Carolina Dieguez

picon face
Hey, guys!

Is there any precaution that I have to have when I try to use Timer1
interrupt and USART receive interrupt in the same code?

On 8/31/07, Jinx <RemoveMEjoecolquittTakeThisOuTspamclear.net.nz> wrote:
{Quote hidden}

> -

2007\09\01@192835 by Jinx

face picon face
> Is there any precaution that I have to have when I try to use Timer1
> interrupt and USART receive interrupt in the same code?

Hi Carol,

Say for example TMR1 is 524ms and the baud rate is 9600. This is
a bit time of 1000000/9600 = 104us, and there are 10 bits to receive
for each byte (Start, Data, Stop) before the USART interrupt goes
off, => 1.042ms between RCIF interrupts, which is a long time in
which to process the last received byte. And also process TMR1
interrupts that might happen during reception. Given the difference
between their timing, only occassionally will they coincide, so it's
quite manageable. But you do have to write the code to cope with
the worst-case

So at the start of your ISR you'd first test which interrupt flag has
been set, ie the one that caused this interrupt. Clear that flag and
do what's required. For TMR1 that might be incrementing a counter
of setting a flag to be used outside of the ISR by the main code. For
the USART it might be storing the data

When RETFIE turns GIE back on, if the other interrupt source had
its IF set (ie the timer had rolled over or another byte had been
received during the ISR) then the ISR will be immediately re-entered,
and you do the above paragraph

The thing to remember is that an interrupt flag (IF) is retained in
hardware, and you can respond to it as and when you like. If your
s/w is busy processing one interrupt, you can delay processing
the other one

Your interrupt sources are fairly slow and you won't have any
problem processing either. Howard mentioned that it's generally
a good idea to keep the ISR short. Say your USART baud rate
was a lot higher, perhaps 115kB. That's only 87us for a 10-bit
frame, and you'd not want to spend anywhere that time in the
ISR or interrupts will be missed

2007\09\07@205548 by Carolina Dieguez

picon face
Thanks a lot, Jinx. I couldn't try this out yet...

However, I was trying to solve something else first with no success:o((

The thing is as follows:


ORG 0
>            CALL INIT
>            GOTO MAIN
>            ORG 4
>
              ...
              DECFSZ Counter
              GOTO   Loop
             ...

>            RETFIE

>            INIT
>            - initialisation...
>            RETURN
>
             MAIN
>                - Loop
>                          ...
                           GOTO Loop
             END

Something happens at the ISR and subrrutine called Loop has to be executed,
which is within MAIN. If this loop is entered, microcontroller never gets
out of this interrupt rutine. Am I right??

Then, I'm supposed to have this code completely changed or can I make some
amendments just in order to test if this work??

Bye!


On 9/1/07, Jinx <spamBeGonejoecolquittspamBeGonespamclear.net.nz > wrote:
{Quote hidden}

> -

2007\09\07@215215 by Jinx

face picon face
> Something happens at the ISR and subrrutine called Loop has
> to be executed, which is within MAIN. If this loop is entered,
> microcontroller never gets out of this interrupt rutine

Hi Carol,

You can call any routine from within the ISR and as long as it's
terminated with a return it should work. The stack stores the
return/retfie addresses in LOFO (last on, first off) fashion. So
the most recent call (the call from within the ISR) will be completed
by PC going back into the ISR, then the retfie at the end of the ISR,
returning PC to the main loop

The ISR is basically a called routine, terminated with a return (plus
GIE is automatically re-enabled), although it's generally h/w driven

Where it's easy to come unstuck is using a branch or goto instead
of a return or not clearing an IF

2007\09\07@222416 by Carolina Dieguez

picon face
Jinx,
      I know it is not OK but what could it happen if within ISR there's a
GOTO to a Loop that makes microcontroller never goes back to the ISR so as
to get to the RETFIE???

      And if I enter a ISR, can that ISR be interrupted by a second ISR
before former ISR gets to the RETFIE???

      I think I've messed it up!!

:o)

On 9/7/07, Jinx <TakeThisOuTjoecolquittEraseMEspamspam_OUTclear.net.nz> wrote:
{Quote hidden}

> -

2007\09\07@225258 by Jinx

face picon face

> I know it is not OK but what could it happen if within ISR there's
> a GOTO to a Loop that makes microcontroller never goes back
> to the ISR so as to get to the RETFIE???

Well, if the RETFIE is never executed then GIE won't be turned
back on (similarly if you exit the ISR with RETURN instead of
RETFIE). It might not mean that the rest of the program will stop
working. It just means that there is an orphaned return address
left on the stack. The whole program then has, in some way,
become part of the ISR because of that unresolved h/w call

> And if I enter a ISR, can that ISR be interrupted by a second
> ISR before former ISR gets to the RETFIE???

No, because GIE is turned off. IFs can be set though and the ISR
will be re-entered (if the corresponding IE is also set) as soon as
GIE is turned on by you or the RETFIE

>        I think I've messed it up!!
>
> :o)

Haha, realising that is half the solution ;-) I think we all appreciate
your persistence and stick-to-itiveness

Maybe it would help you if you drew a flow chart. Itemise what
happens when you enter a box, what you need to do inside the
box, what happens when you leave the box, etc. The program
flow is ultimately what you tell the micro it is, not the other way
around. The micro has no power over your decisions, it just
does what it's told to

2007\09\07@230948 by Carolina Dieguez

picon face
"IFs can be set though and the ISR
will be re-entered (if the corresponding IE is also set) as soon as
GIE is turned on by you or the RETFIE"

I've done that and it works when I have just one ISR.

Thanks, Jinx! I think I'm not goog at this but anyway, it seems I began
enjoying it so I'll keep trying:o)

Have a nice weekend you all!

On 9/7/07, Jinx <RemoveMEjoecolquittspamTakeThisOuTclear.net.nz> wrote:
{Quote hidden}

> -

2007\09\07@232048 by Jinx

face picon face
> Thanks, Jinx! I think I'm not good at this but anyway, it seems I
> began enjoying it so I'll keep trying:o)

That's a very important thing to remember. You seem to be becoming
clearer about what works and what doesn't, and soon you'll be able
to program more confidently. Interrupts can be tricky, but if you follow
the basic rules and be careful and methodical, they can be easy too

2007\09\10@145947 by Howard Winter

face
flavicon
picon face
Carol,

On Sat, 8 Sep 2007 00:09:08 -0300, Carolina Dieguez wrote:

> "IFs can be set though and the ISR
> will be re-entered (if the corresponding IE is also set) as soon as
> GIE is turned on by you or the RETFIE"
>
> I've done that and it works when I have just one ISR.

I may be being picky here (no change there, then! :-) but I'd say that there should only be one ISR, but that it may handle any number of different interrupts.

What I mean by this is that there is only one entry point  (address 4 - this is a design feature you can't change) and there should be only one exit point.  By doing
this you avoid the confusion of multiple interrupts happening and you not being sure what it's going to do.  You can do this in a number of ways, but here are a
couple.  First, a single pass through the ISR may handle one of each type of interrupt:

ISRentry:
IF Interrupt1 happened
 Process Interrupt 1

IF Interrupt2 happened
 Process Interrupt2

If Interrupt3 happened
 Process Interrupt3
...
RETFIE

This tends to work best when none of the interrupts are partucularly urgent in relation to the others, and/or they are all quick enough to handle that they won't
cause a problem if, say, Interrupt1 happens again after being processed, while 2 or 3 are being processed.

Another way is to process only one interrupt per pass through the ISR:

ISRentry:
IF Interrupt1 happened
 Process Interrupt 1
 GOTO ISRexit

IF Interrupt2 happened
 Process Interrupt2
 GOTO ISRexit

If Interrupt3 happened
 Process Interrupt3
 GOTO ISRexit
...

ISRexit
RETFIE

This means that the first interrupt which is found will be handled, then the ISR is exited.  If another interrupt has happened, the RETFIE will allow another
interruption and the ISR will be re-entered immediately.  This is best when there is a definite priority in the interrupts, with the most urgent handled first.  
Time-critical events such as fast timers and communications fit this, with things like button-press detection being less urgent.  You could replace each "GOTO
ISRexit" with RETFIE, but I prefer to have only one exit point - this is more of a style thing than anything more technical - and it does "waste" a GOTO which goes
against something I said in an earlier message, but I'm only human! :-)

A third alternative would be to have "GOTO ISRentry" instead of "GOTO ISRexit" at the end of each processing routine, and this is probably the fastest way to
re-process the highest priority interrupt.  It does look like: "if Interrupt1 keeps happening, we'll never get out of the ISR" but that's the nature of interrupts - they
demand to be handled straight away, and if one of them happens so often that processing it takes all the time in between its happenings, then you have a problem
that can't be solved in software - the PIC isn't fast enough for the job!

Whichever way you do it, remember to clear the appropriate IF early in the routine processing it.  Don't be tempted to clear them all at ISRexit, because you could
be losing one you haven't processed!

Cheers,



Cheers,



Howard Winter
St.Albans, England


More... (looser matching)
- Last day of these posts
- In 2007 , 2008 only
- Today
- New search...