Need help with PIC16F88, assembly and Timer0 interrupts - Page 1
Forum section: electronics / general

author: elliot42
author_rank: Contributor
timestamp: July 12, 2012, 11:55:38 pm
content: 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) = 2Mhz1 / 2Mhz (freq -> time) * 256 (8-bit Timer0 counter) * 128 (prescaler ratio) = 16,384usCan 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_OFForg 0x00goto mainorg 0x04bsf PORTA,1bcf PORTA,1retfiemain:clrf STATUSclrf PORTAclrf PORTBmovlw 0x00banksel TRISAmovwf TRISAbanksel TRISBmovwf TRISBbanksel ANSELclrf ANSELbanksel OSCCONbsf OSCCON,IRCF2bsf OSCCON,IRCF1bsf OSCCON,IRCF0bcf OSCCON,SCS0bcf OSCCON,SCS1banksel PORTAclrf PORTAclrf PORTBbanksel OPTION_REGbcf OPTION_REG,T0CSbcf OPTION_REG,PSAbsf OPTION_REG,PS2bsf OPTION_REG,PS1bcf OPTION_REG,PS0banksel INTCONbsf INTCON,TMR0IE ; enable TMR0 interruptbsf INTCON,GIE ; enable interrupt globally.loop:bsf PORTA,0nopnopbcf PORTA,0goto loop

author: David_AVD
author_rank: Super Contributor
timestamp: July 13, 2012, 12:17:03 am
content: Quote from: elliot42 on July 12, 2012, 11:55:38 pmOne 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)

author: notsob
author_rank: Frequent Contributor
timestamp: July 13, 2012, 12:39:09 am
content: PIC RMW - ReadModifyWrite issueshttp://www.piclist.com/techref/readmodwrite.htm

author: notsob
author_rank: Frequent Contributor
timestamp: July 13, 2012, 12:40:43 am
content: If you are beginning ASM on PIC there are some tutorials on pcbheaven.com

author: elliot42
author_rank: Contributor
timestamp: July 13, 2012, 01:27:03 am
content: 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.comThanks 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.

author: elliot42
author_rank: Contributor
timestamp: July 13, 2012, 09:53:04 am
content: Thank you guys!My interrupt is working now. Not doing much, but working.

author: David_AVD
author_rank: Super Contributor
timestamp: July 13, 2012, 10:43:49 am
content: Excellent. Sounds like you're on the way now.

author: poorchava
author_rank: Super Contributor
timestamp: July 13, 2012, 12:31:49 pm
content: 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.

author: David_AVD
author_rank: Super Contributor
timestamp: July 13, 2012, 12:53:51 pm
content: Nah, interrupts are pretty easy really. It's just a matter of reading the data sheet. Same goes for any brand of micro.