Electronics > Microcontrollers

Need help with PIC16F88, assembly and Timer0 interrupts

(1/2) > >>

elliot42:
I've been mucking about with PICs lately, with the intention to make a VCO using wavetable synthesis on the PIC.
I've never used PICs or assembly before and I'm having trouble getting the Timer0 interrupt to work how I expect it to work.
In the code below I'm setting the prescaler to be assigned to Timer0 and to have a ratio of 1:128, so I expected to get an interrupt event every 16.384ms (I think **), but the interrupt just seems to be running as fast as it possibly can.
I've taken images from my DSO showing on channel 1 the CLKOUT (Fosc / 4 = 8Mhz / 4 = 2Mhz), and on channel 2 the output of PORTA,1 that I'm setting high and low in the interrupt routine.

Interestingly, when I add 2 nop instructions between the bsf/bcf in the interrupt routine, the frequency at which the interrupt occurs decreases.
Also, when the Timer0 interrupt is enabled (bsf INTCON,TMR0IE) I get no output on PORTA,0 which I set in the loop; when I disable the interrupt I get output there.

** 8Mhz (clock) / 4 (4 clocks per instruction cycle) = 2Mhz
1 / 2Mhz (freq -> time) * 256 (8-bit Timer0 counter) * 128 (prescaler ratio) = 16,384us

Can anyone explain this to me? Am I doing something wrong or do I not understand how this is meant to work?


--- Code: ---        LIST        P=16F88
        #INCLUDE    "p16F88.inc"

        __CONFIG    _CONFIG1, _CPD_OFF & _CP_OFF & _DEBUG_OFF & _LVP_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _WRT_PROTECT_OFF & _INTRC_CLKOUT & _BODEN_OFF

        org         0x00
        goto        main

        org         0x04
        bsf         PORTA,1
        bcf         PORTA,1
        retfie

main:
        clrf        STATUS
        clrf        PORTA
        clrf        PORTB

        movlw       0x00
        banksel     TRISA
        movwf       TRISA
        banksel     TRISB
        movwf       TRISB

        banksel     ANSEL
        clrf        ANSEL

        banksel     OSCCON
        bsf         OSCCON,IRCF2
        bsf         OSCCON,IRCF1
        bsf         OSCCON,IRCF0
        bcf         OSCCON,SCS0
        bcf         OSCCON,SCS1

        banksel     PORTA
        clrf        PORTA
        clrf        PORTB

        banksel     OPTION_REG
        bcf         OPTION_REG,T0CS
        bcf         OPTION_REG,PSA
        bsf         OPTION_REG,PS2
        bsf         OPTION_REG,PS1
        bcf         OPTION_REG,PS0

        banksel     INTCON
        bsf         INTCON,TMR0IE   ; enable TMR0 interrupt
        bsf         INTCON,GIE      ; enable interrupt globally.

loop:
        bsf         PORTA,0
        nop
        nop
        bcf         PORTA,0
        goto        loop

--- End code ---

David_AVD:

--- Quote from: elliot42 on July 12, 2012, 11:55:38 pm ---In the code below I'm setting the prescaler to be assigned to Timer0 and to have a ratio of 1:128, so I expected to get an interrupt event every 16.384ms (I think **), but the interrupt just seems to be running as fast as it possibly can.
--- End quote ---

One obvious issue is that you're not clearing the interrupt flag when you service it.

Also, the bsf / bcf method of twiddling the port bits on a PIC16F88 will result in RMW issues. (lots of info on that if you search)

notsob:
PIC RMW - ReadModifyWrite issues

http://www.piclist.com/techref/readmodwrite.htm

notsob:
If you are beginning ASM on PIC there are some tutorials on pcbheaven.com

elliot42:
Thank you, David, notsob. I have been looking at the Timer0 tutorial on PCBHeaven and must have just read past this bit:

--- Quote from: pcbheaven.com ---The TMR0IF must be cleared in software (BCF INTCON,TMR0IF) for the TMR0 interrupt to be re-enabled.

--- End quote ---
Thanks for pointing it out.

Thanks for the info too about the RMW issues.

I am just starting out with ASM, been at it for only a week. I've done some stuff with Arduinos before in C and I program in Java and C++ (and sometimes Python, Ruby, sh, SQL) at work, but thought I'd try learning about the lower-level operations of the PIC instead of just using C and copying some tutorials.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version