Author Topic: Need help with PIC16F88, assembly and Timer0 interrupts  (Read 6241 times)

0 Members and 1 Guest are viewing this topic.

Offline elliot42Topic starter

  • Contributor
  • Posts: 49
  • Country: au
Need help with PIC16F88, assembly and Timer0 interrupts
« on: July 12, 2012, 11:55:38 pm »
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: [Select]
        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
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2863
  • Country: au
Re: Need help with PIC16F88, assembly and Timer0 interrupts
« Reply #1 on: July 13, 2012, 12:17:03 am »
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.

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)
 

Offline notsob

  • Frequent Contributor
  • **
  • Posts: 705
  • Country: au
Re: Need help with PIC16F88, assembly and Timer0 interrupts
« Reply #2 on: July 13, 2012, 12:39:09 am »
PIC RMW - ReadModifyWrite issues

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

Offline notsob

  • Frequent Contributor
  • **
  • Posts: 705
  • Country: au
Re: Need help with PIC16F88, assembly and Timer0 interrupts
« Reply #3 on: July 13, 2012, 12:40:43 am »
If you are beginning ASM on PIC there are some tutorials on pcbheaven.com
 

Offline elliot42Topic starter

  • Contributor
  • Posts: 49
  • Country: au
Re: Need help with PIC16F88, assembly and Timer0 interrupts
« Reply #4 on: July 13, 2012, 01:27:03 am »
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.
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.
 

Offline elliot42Topic starter

  • Contributor
  • Posts: 49
  • Country: au
Re: Need help with PIC16F88, assembly and Timer0 interrupts
« Reply #5 on: July 13, 2012, 09:53:04 am »
Thank you guys!
My interrupt is working now. Not doing much, but working.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2863
  • Country: au
Re: Need help with PIC16F88, assembly and Timer0 interrupts
« Reply #6 on: July 13, 2012, 10:43:49 am »
Excellent.  Sounds like you're on the way now.  :)
 

Offline poorchava

  • Super Contributor
  • ***
  • Posts: 1673
  • Country: pl
  • Troll Cave Electronics!
Re: Need help with PIC16F88, assembly and Timer0 interrupts
« Reply #7 on: July 13, 2012, 12:31:49 pm »
That's the pain in PICs. You always have to read and remember every little word in dtasheet and errata.

Dunno how it's in 16f, but in 18f there are interrupt sources that clear the flag by themselves (like UART - when you read the buffer) and there are ones that do not, in which case you have to manage all this in software. Also in most cases you have to re-set the global interrupt enable.
I love the smell of FR4 in the morning!
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2863
  • Country: au
Re: Need help with PIC16F88, assembly and Timer0 interrupts
« Reply #8 on: July 13, 2012, 12:53:51 pm »
Nah, interrupts are pretty easy really.  It's just a matter of reading the data sheet.  Same goes for any brand of micro.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf