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?
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