This is a multi-part message in MIME format. ------=_NextPart_000_0B75_01C50127.707E39C0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit ----- Original Message ----- From: "John Mullan" To: Sent: Saturday, January 22, 2005 5:49 PM Subject: [PIC] TMR0 counter and RB0/INT help. > I was hoping someone on the list could supply my with (or point me to) some > simple example code for using the TMR0 as counter. > > I would like to measure time between interupts on RB0/INT pin. I would be > measuring the mains frequency through bridge rectifier (ie; should average > 120 interupts per second). However, I would want to have a range from 0 > (missing) to say 75hz (150 interupts). I presume I will need the example to > include the prescaler for this. You don't necessarily need the prescaler, you can count the roll-overs of TMR0 and acheive 1uS precision. If you'd like to keep it all in 8 bits, then the prescaler will be needed. The period between peaks in your signal is about 8.3333R mS (8 1/3 to be precise ;-) for 60Hz AC that has been fully rectified. You didn't specify a minimum value on the number of ints, so it's hard to nail down the exact prescaler value you need. A prescaler of 256 will let you measure up to 65.535 mS before a TMR0 rollover occurs using a 4MHz crystal. However that will only give you resolution to about .25mS. > I learn best by example. I have done several PIC projects, but nothing > really to do with interupts. I attached an example. It is UNTESTED, but is cut and pasted from working code. It should at least give you an idea of how to do what you wish. ------=_NextPart_000_0B75_01C50127.707E39C0 Content-Type: application/octet-stream; name="killme.asm" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="killme.asm" ;------------------------------------------------------------------------= --------------------- ; HEADER: ;------------------------------------------------------------------------= --------------------- LIST P=3D16f84a=20 RADIX DEC=20 INCLUDE "p16f84a.inc"=20 __CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON ;------------------------------------------------------------------------= --------------------- ; EQUATES: ;------------------------------------------------------------------------= --------------------- STARTOFRAM equ 0x0C ;First Usable RAM Location = for 16f84 ENDOFRAM equ 0x4F ;Last Usable RAM Location = for 16f84 cblock STARTOFRAM ; ; General Purpose Temp Storage ; W_TEMP STATUS_TEMP FSR_TEMP endc ;------------------------------------------------------------------------= --------------------- ; START: ;------------------------------------------------------------------------= --------------------- org 0x000 goto Start org 0x004 ; Interrupt handler right here movwf W_TEMP ;Save everything = =20 swapf STATUS, W movwf STATUS_TEMP movfw FSR movwf FSR_TEMP bcf STATUS, RP0 ;Back to Bank 0 btfsc INTCON, T0IF ;Is it a timer0 interrupt = (indicating a roll over) goto Tmr0Int btfsc INTCON, INTF ;Is it RB0 goto RB0Int ;Yes goto IntExit ; A new cycle has arrived RB0Int movfw TMR0 ;get the value since the = last interrupt ; Now do something useful with it like passing it to the main level code = =20 bcf INTCON, INTF ;clear int occured flag clrf TMR0 ;set counter back to zero bcf INTCON, T0IF goto IntExit ; TMR0 rollover occured, this means no signal present or the period is = too long Tmr0Int goto IntExit ; Restore everything and return IntExit movfw FSR_TEMP movwf FSR swapf STATUS_TEMP, W movwf STATUS swapf W_TEMP, F swapf W_TEMP, W retfie ; ; ; Main level code begins here ; ; Start =20 bsf STATUS, RP0 ;Switch to Bank 1 movlw b'00000001' ;Define I/O on Port B (set = all as output except RB0) movwf TRISB & 0x07F movlw b'00000000' ;Define I/O on Port A (set = all as output) movwf TRISA & 0x07F bcf STATUS, RP0 ;Back to Bank 0 call IntInit ;Initialize interrupts MainLoop ; Put your main level code here. For example, the ISR could put the = TMR0 value into a RAM location. ; When you see that value become non-zero here, you could do something = clever with it and then clear ; the RAM location. You could also be looking for some kind of = semaphore being passed by the RB0Int ; routine indicating that TMR0 is rolling over (i.e. the incomming = signal frequency is too low) goto MainLoop =20 =20 =20 ;------------------------------------------------------------------------= ; ; Interrupt initialization ; ;------------------------------------------------------------------------= IntInit ; ; Setup of Prescaler and TMR0 ; bsf STATUS, RP0 ; Select Bank 1 bcf OPTION_REG, T0CS ; Tell Timer0 to use Crystal = clock (4 mhz =3D 1us/count) Starts the timer also bcf OPTION_REG, PSA ; Assign prescaler to TMR0 bsf OPTION_REG, PS2 ; Prescaler Divisor (256 in = this case) bsf OPTION_REG, PS1 bsf OPTION_REG, PS0 bcf STATUS, RP0 ; Select Bank 0 ; ; Setup of RB0 Interrupts ; bsf STATUS, RP0 ; Select Bank 1 bsf OPTION_REG, INTEDG ; Trigger on rising edge = (active high) bcf STATUS, RP0 ; Select Bank 0 bsf INTCON, INTE ; Turn on the interrupts for = RB0 return end ------=_NextPart_000_0B75_01C50127.707E39C0 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist ------=_NextPart_000_0B75_01C50127.707E39C0--