--nextPart2912043.rat7JAi7FX Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8Bit I'm trying to code a very simple LED flasher as a starter app, and I can't get the damn thing to work. (This is on PIC16F627 and simulated on MPLAB.) The timer1 rollover never fires. Code follows as attachment. Can someone tell me what I'm doing wrong? --nextPart2912043.rat7JAi7FX Content-Type: text/plain; name="FlashLed.asm" Content-Transfer-Encoding: 8Bit Content-Disposition: attachment; filename="FlashLed.asm" ;---- ; Purpose: Flash LED once per second ; Written by: Julian Morrison ; Date: 6/Sep/2005 ; Version: 0.1 ; File saved as: FlashLed.asm ; For PIC: 16F627 ; For board: Velleman K8048 ; Clock frequency: 4 megahertz ;---- ; processor p16f627 ; for gpasm processor 16f627 ;---- ; Declarations ; reset vector org 0x00 goto Start ; interrupt vector org 0x04 goto ISR ; SFRs for p16f627 ; ...shared indirect equ 0x00 ; address to indirect via FSR pcl equ 0x02 ; program counter low byte status equ 0x03 fsr equ 0x04 ; indirection pointer pclath equ 0x0A ; program counter high 5 bits intcon equ 0x0B ; ...bank 0 tmr0 equ 0x01 porta equ 0x05 portb equ 0x06 pir1 equ 0x0C tmr1_lo equ 0x0E tmr1_hi equ 0x0F t1con equ 0x10 tmr2 equ 0x11 t2con equ 0x12 ccpr1_lo equ 0x15 ; capture/compare low byte ccpr1_hi equ 0x16 ; capture/compare high byte ccp1con equ 0x17 txreg equ 0x19 ; USART transmit rcreg equ 0x1A ; USART recieve cmcon equ 0x1F user_regs_0 equ 0x20 ; ...bank 1 option_reg equ 0x01 trisa equ 0x05 trisb equ 0x06 pie1 equ 0x0C pcon equ 0x0E pr2 equ 0x12 txsta equ 0x18 spbrg equ 0x19 eedata equ 0x1A eeadr equ 0x1B eecon1 equ 0x1C eecon2 equ 0x1D vrcon equ 0x1F user_regs_1 equ 0x20 ; ...bank 2 portb equ 0x06 user_regs_2 equ 0x20 ; ...bank 3 trisb equ 0x06 ; custom registers rollover_count equ user_regs_0 + 0x00 ; constants ticks_per_10ms equ d'10000' ; 4 megahertz, 4 cycles per tick t1rollover equ d'65536' - ticks_per_10ms ;---- ; Subroutines org 0x05 Init clrf porta clrf portb bsf status,5 ; bank 1 to access tris movlw b'00001111' movwf trisa ; porta is connected to switches movlw b'00000000' movwf trisb ; portb is connected to LEDs movlw b'00001000' ; prescale 1:1 for WDT, none for tmr0 movwf option_reg bcf status,5 ; bank 0 movlw b'00000000' movwf intcon return ISR btfss pir1, 0 ; only interested in timer 1 overflow retfie bcf pir1, 0 ; reset timer 1 interrupt decfsz rollover_count, f retfie movlw b'00000001' xorwf portb, f ; flip the LED call ResetClock retfie ResetClock movlw HIGH t1rollover movwf tmr1_hi movlw LOW t1rollover movwf tmr1_lo movlw d'100' movwf rollover_count return SetClock call ResetClock bcf pir1, 0 ; reset timer 1 interrupt bsf status, 5 bsf pie1, 0 ; enable tmr1 rollover interrupt bcf status, 5 bsf intcon, 7 ; global interrupt enable movlw b'00000001' movwf t1con ; start clock with no prescaling return ;---- ; Main program Start call Init call SetClock Main clrwdt goto Main ; loop for interrupt end --nextPart2912043.rat7JAi7FX--
What am I doing wrong?
Started by ●September 16, 2005
Reply by ●September 16, 20052005-09-16
"Julian Morrison" <julian@extropy.demon.co.uk> wrote in message news:dgfkjk$j3b$1$8300dec7@news.demon.co.uk...> I'm trying to code a very simple LED flasher as a starter app, and I > can't get the damn thing to work. (This is on PIC16F627 and simulated on > MPLAB.) The timer1 rollover never fires. Code follows as attachment. > > Can someone tell me what I'm doing wrong?I don't know that CPU, but I saw this:>>; interrupt vector org 0x04 goto ISR ... ; Subroutines org 0x05 Init clrf porta << You sure you're leaving enough room for the "goto ISR"? Also, are there any other vectors that map to 0x05 etc? Steve http://www.fivetrees.com
Reply by ●September 16, 20052005-09-16
Steve at fivetrees wrote:> You sure you're leaving enough room for the "goto ISR"? Also, are there > any other vectors that map to 0x05 etc?AFAIK (could be wrong, but I think not) the program memory addresses are counted in whole-instruction increments, not in bytes. So 0x05 is the instruction after. Still, I commented the "org 0x05" out, rebuilt and reran, unfortunately with no more success. The same result: the rollover bit in PIR1 gets set as the timer runs, but the ISR is never called.
Reply by ●September 16, 20052005-09-16
On Sat, 17 Sep 2005 00:31:00 +0100, the renowned Julian Morrison <julian@extropy.demon.co.uk> wrote:>I'm trying to code a very simple LED flasher as a starter app, and I >can't get the damn thing to work. (This is on PIC16F627 and simulated on >MPLAB.) The timer1 rollover never fires. Code follows as attachment. > >Can someone tell me what I'm doing wrong?You need to set PEIE, as well as GIE for the TMR1 interrupts to work. Best regards, Spehro Pefhany -- "it's the network..." "The Journey is the reward" speff@interlog.com Info for manufacturers: http://www.trexon.com Embedded software/hardware/analog Info for designers: http://www.speff.com
Reply by ●September 16, 20052005-09-16
Spehro Pefhany wrote:> You need to set PEIE, as well as GIE for the TMR1 interrupts to work.Thanks! It works now. Damn, who writes these chip manuals anyhow? They buried that info in a boolean-gate diagram on page 103. No thought to mention "actually, timer1 needs PEIE" in the section actually about timer1! At least it wasn't any worse mistake. Again, thanks :-)
Reply by ●September 16, 20052005-09-16
On Sat, 17 Sep 2005 02:39:07 +0100, the renowned Julian Morrison <julian@extropy.demon.co.uk> wrote:>Spehro Pefhany wrote: > >> You need to set PEIE, as well as GIE for the TMR1 interrupts to work. > >Thanks! It works now. > >Damn, who writes these chip manuals anyhow? They buried that info in a >boolean-gate diagram on page 103. No thought to mention "actually, >timer1 needs PEIE" in the section actually about timer1! > >At least it wasn't any worse mistake. > >Again, thanks :-)No problem. Another hint you'll find in Microchip's datasheets is that they often summarize the various SFR bits and registers required for a given function, in the section related to the function (in this case TMR1). You'd probably have to search to find the function of that bit if you hadn't run into it before, but at least you'd know to look. I have a datasheet here with that info in Table 7-2. The relevant stuff to TMR1 is spread over 6 bytes in 2 banks. Also, the midrange reference manual provides more detail organized differently (although it may not always match newer chips exactly, it can be helpful). Best regards, Spehro Pefhany -- "it's the network..." "The Journey is the reward" speff@interlog.com Info for manufacturers: http://www.trexon.com Embedded software/hardware/analog Info for designers: http://www.speff.com
Reply by ●September 17, 20052005-09-17
On Sat, 17 Sep 2005 02:39:07 +0100, the renowned Julian Morrison <julian@extropy.demon.co.uk> wrote:>Spehro Pefhany wrote: > >> You need to set PEIE, as well as GIE for the TMR1 interrupts to work. > >Thanks! It works now.P.S. You probably know this already, but just in case, you are not saving and restoring context in the ISR. That means that most anything beyond your simple loop at Main: will fail because things will be corrupted by the ISR. Don't bother trying to figure out the save/restore stuff yourself, just look it up. It requires the use of the swapf (swap nibbles) instruction... and there are some banking issues (code and data) <ugh>. Let's not even get into nested ISRs. You have to admire an architecture that requires an application note to explain how to do a table lookup. Best regards, Spehro Pefhany -- "it's the network..." "The Journey is the reward" speff@interlog.com Info for manufacturers: http://www.trexon.com Embedded software/hardware/analog Info for designers: http://www.speff.com
Reply by ●September 17, 20052005-09-17
Spehro Pefhany wrote:> P.S. > > You probably know this already, but just in case, you are not saving > and restoring context in the ISR.D'oh! As you can see I'm still new to this.> That means that most anything beyond > your simple loop at Main: will fail because things will be corrupted > by the ISR.There's a design approach I've been using to minimize that: "either spin and poll without using interrupts, or do everything inside the ISR". This was mainly practise code at interrupt handling.> Don't bother trying to figure out the save/restore stuff > yourself, just look it up. It requires the use of the swapf (swap > nibbles) instruction... and there are some banking issues (code and > data) <ugh>.Thanks, now I know what to look for, google makes finding it easy. Banking issues? I'm guessing, switch off GIE before changing banks away from 0, then run the ISR manually after switching back so as to avoid dropping interrupts. Is that right?> Let's not even get into nested ISRs. You have to admire > an architecture that requires an application note to explain how to do > a table lookup."brought to you by the folks who did INTERCAL and Malbolge"
Reply by ●September 17, 20052005-09-17
"Julian Morrison" <julian@extropy.demon.co.uk> wrote in message news:dggcv5$gm2$1$8300dec7@news.demon.co.uk...> Spehro Pefhany wrote: > >> P.S. >> >> You probably know this already, but just in case, you are not saving >> and restoring context in the ISR. > > D'oh! As you can see I'm still new to this. > >> That means that most anything beyond >> your simple loop at Main: will fail because things will be corrupted >> by the ISR. > > There's a design approach I've been using to minimize that: "either spin > and poll without using interrupts, or do everything inside the ISR". > This was mainly practise code at interrupt handling. > >> Don't bother trying to figure out the save/restore stuff >> yourself, just look it up. It requires the use of the swapf (swap >> nibbles) instruction... and there are some banking issues (code and >> data) <ugh>. > > Thanks, now I know what to look for, google makes finding it easy. > Banking issues? I'm guessing, switch off GIE before changing banks away > from 0, then run the ISR manually after switching back so as to avoid > dropping interrupts. Is that right? > >> Let's not even get into nested ISRs. You have to admire >> an architecture that requires an application note to explain how to do >> a table lookup. >The 16Cxxx PIC architecture requires the programmer to be aware of a lot of things that are not very obvious. There are some pretty clunky things about interrupts in particular. First, the stack is used only for return address information. You cannot push data onto it. Second, the MOVFW instruction affects the ZERO flag. This means that when an ISR needs to save the context it must: Save the W register to a file register location that is allocated at the same offset in all banks. Save the status register into the W register using the SWAPF nibble instruction. The SWAPF instruction must be used because it does not affect the flags in the status register. Microchip has application notes and code examples on how to do this. ------------- You should not need to switch off the GIE from within an ISR as the interrupt system is disabled until the RETFIE instruction is executed. You need to know about this when doing nested interrupts. When using nested interrupts you really need to understand the PIC very thoroughly. ------------- But the single most important thing about ISR code: NEVER USE ALL OF THE AVAILABLE REAL TIME IN THE INTERRUPT SERVICE ROUTINES! In fact using more than 20% of the processor bandwidth in the ISRs can make debug quite a challenge. Plus the interrupt response could be quite bad.
Reply by ●September 18, 20052005-09-18
To Keyser and Julian.>.. some fullquote deleted > > This means that when an ISR needs to save the context it must: > > Save the W register to a file register location that is allocated at the > same offset in all banks. > > Save the status register into the W register using the SWAPF nibble > instruction. The SWAPF instruction must be used because it does not affect > the flags in the status register. > > Microchip has application notes and code examples on how to do this.In fact, it's even described in the manual, how to save the context during interrupt (chapter 14.7 in the PIC16F62x manual).> You should not need to switch off the GIE from within an ISR as the > interrupt system is disabled until the RETFIE instruction is executed. > > You need to know about this when doing nested interrupts. When using nested > interrupts you really need to understand the PIC very thoroughly.Nested interrupts on PIC are a very bad sugestion on a newbe.> But the single most important thing about ISR code: > > NEVER USE ALL OF THE AVAILABLE REAL TIME IN THE INTERRUPT SERVICE ROUTINES! > > In fact using more than 20% of the processor bandwidth in the ISRs can make > debug quite a challenge. Plus the interrupt response could be quite bad.This applies not only to PICs, but for most other micros. At least: It is always a more helpful, to read also about related things (here the basics about interrupt on PIC) in the manual. HTH Michael