Hi,
I appreciate this has been asked before, but am struggling to get this working, looking for some sample code and clarification i am looking to measure frequency (between about 5hz and 125hz) on one of the pins on a 16F688, i am completely confused with timers, interupts, prescalers, and cant even decide which pin to use now as input. (8 or 16bit and which pin?)
Any help appreciated.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
hi again, sorry, realised i may be asking a bit much here.
I realise (hopefully correctly) that i should be timing the time gap with a timer between interups, which gives me the data i need, i am confused about which input on the 16F688 to use, is it RA2? and just cant get any code working at all.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I see no one is answering your questions. I certainly don't have all the answers but would give you some advise.
You are asking about some of the more difficult topics in programming: timing, counting and interrupts.
so break them up into specific questions, littler pieces. Make a list of things you want to accomplish.
constraints so far: 16F688 which has two counters T0 is 8 bit and T1 is 16 bit. they both have prescalers if needed.
second you want to count 5 to 125 counts per second
so logically, maybe not practically, both counters can count this high… 8bit=256 16bit ~ 65535
if you want to be accurate, you will need a crystal oscillator to give a time period to count in,
by definition= counts/sec
both counters can have a crystal osc source. also there is a tunable internal clock
I just looked at the 16F688 spec sheet for clock source and it is a little confusing.
One of my favorite resources is PICList website.
Also Microchip has a lot of good app notes and spec sheets with some examples.
Good Luck
Mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I know this is a combination of assembler and GCBasic BUT that is one of the wonderful things about GCBasic.
I give credit to Microchip and one of the timer apps but I forgot which one.
Mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
thanks for the reply, i guess my question and title was a bit wrong initially, i think what i meant to ask was:-
I want to measure frequency (between about 5hz and 125hz on a 16F688, i am assuming the best way is to measure the time interval between pulses with interupts (and then average them out), can someone point me in the right direction with a code example please of measuring time intervals with interupts?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here is a concise example on setting up the Timer interrupt, prescaler, and registers to overflow at a specific interval. I would try that first and measure the ouput by blinking an led in Main after X number of increments or overflows. So for instance try adding the code below to that example for a 1Hz signal. After getting that going, then try something along the lines of a 50us, or 100us rollover for the 5Hz to 135Hz periods.
That will get you half the way there. The other half would be to keep track of the signal edges and determining how many rollovers while polling a digital input (e.g. dir PortC.1 in). Another possibility is using a CCPx interrupt, if other things are happening in the program, check out the forum for an example.
#define led PortC.0
dir led out
Main:
'Main code
'Do something useful with TenthSeconds here
Do
If TenthSeconds = 5 Then Set led On
'led = ! OnOff
'TenthSeconds = 0
If TenthSeconds = 10 Then
Set led Off
TenthSeconds = 0
end if
Loop
goto Main
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here is a working code!
It is for the 16F887 because that is the proto board I had to test on.
The interrupt does all the work. Port D has 8 LEDS on the protoboard.
It is running in front of me right now and when I touch my metal pen to the RA4 input which is the T0CKI - T0 Clk input the LEDS on portD light up 00****00 … that is binary for 60hertz!! yahoo sometimes thing work
Good luck converting the code
'Frequecy read out on port D by 8 Leds
' Couter T0 counts the pulses into RA4
' Counter timer T1 interrupts every 1 sec because it has a 32khz clock crystal on it and acouple of caps and a resistor
' Read about the external T1 osc in the Microchip specs sheet
'
'1/29/2010 all rights reserved.. Mike Otte
#chip 16F887, 8
#config INTOSC
RTCinit
mins = 0
hours = 0
secs=0
'Pin Direction
DIR PORTD OUT ' this is the frequency read out in binary
Hi,
I appreciate this has been asked before, but am struggling to get this working, looking for some sample code and clarification i am looking to measure frequency (between about 5hz and 125hz) on one of the pins on a 16F688, i am completely confused with timers, interupts, prescalers, and cant even decide which pin to use now as input. (8 or 16bit and which pin?)
Any help appreciated.
hi again, sorry, realised i may be asking a bit much here.
I realise (hopefully correctly) that i should be timing the time gap with a timer between interups, which gives me the data i need, i am confused about which input on the 16F688 to use, is it RA2? and just cant get any code working at all.
I see no one is answering your questions. I certainly don't have all the answers but would give you some advise.
You are asking about some of the more difficult topics in programming: timing, counting and interrupts.
so break them up into specific questions, littler pieces. Make a list of things you want to accomplish.
constraints so far: 16F688 which has two counters T0 is 8 bit and T1 is 16 bit. they both have prescalers if needed.
second you want to count 5 to 125 counts per second
so logically, maybe not practically, both counters can count this high… 8bit=256 16bit ~ 65535
if you want to be accurate, you will need a crystal oscillator to give a time period to count in,
by definition= counts/sec
both counters can have a crystal osc source. also there is a tunable internal clock
I just looked at the 16F688 spec sheet for clock source and it is a little confusing.
One of my favorite resources is PICList website.
Also Microchip has a lot of good app notes and spec sheets with some examples.
Good Luck
Mike
i meant to add this to last posting but forgot.
This is an example that I implemented for use in a sideral clock I built.
It is the subroutines for the 1 sec interrupt.
' 32khz Clock crystal on T1 osc pins
#chip 16F886, 8
#config OSC = INTRC_IO
#define inchrs PORTC.3 ' clock seting buttons
#define incmin PORTC.4
#define incsec PORTC.5
RTCinit ' sets up the interrupt
'Pin Direction
dir inchrs in
dir incmin in
dir incsec in
' Main Loop
'
'Sub routines
sub RTCinit
MOVLW 0x80 ; Preload TMR1 register pair
MOVWF TMR1H ; for 1 second overflow
CLRF TMR1L
BSF INTCON, PEIE ; Enable Peripheral Interrupts
BSF INTCON, GIE ; Enable all Interrupts
MOVLW b'00001111' ; Configure for external clock,
MOVWF T1CON ; Asynchronous operation, external oscillator
CLRF secs ; Initialize timekeeping registers
CLRF mins
MOVLW .12
MOVWF hours
Wait 5 10us
BSF PIE1, TMR1IE ; Enable Timer1 interrupt
end sub
sub INTERRUPT
BSF TMR1H, 7 ; Preload for 1 sec overflow
BCF PIR1, TMR1IF ; Clear interrupt flag
BSF INTCON, PEIE ; Enable Peripheral Interrupts
BSF INTCON, GIE ; Enable all Interrupts
secs = secs +1 ' Increment seconds
if secs < 60 then goto fini ' yes, done
secs = 0 'Clear seconds
mins = mins +1 ' Increment minutes
if mins < 60 then goto fini ' yes, done
mins = 0 ' clear minutes
hours = hours +1 ' Increment hours
if hours < 24 then goto fini ' yes, done
hours =0 ' Clear hours
fini: 'Done
end sub
I know this is a combination of assembler and GCBasic BUT that is one of the wonderful things about GCBasic.
I give credit to Microchip and one of the timer apps but I forgot which one.
Mike
thanks for the reply, i guess my question and title was a bit wrong initially, i think what i meant to ask was:-
I want to measure frequency (between about 5hz and 125hz on a 16F688, i am assuming the best way is to measure the time interval between pulses with interupts (and then average them out), can someone point me in the right direction with a code example please of measuring time intervals with interupts?
Here is a concise example on setting up the Timer interrupt, prescaler, and registers to overflow at a specific interval. I would try that first and measure the ouput by blinking an led in Main after X number of increments or overflows. So for instance try adding the code below to that example for a 1Hz signal. After getting that going, then try something along the lines of a 50us, or 100us rollover for the 5Hz to 135Hz periods.
That will get you half the way there. The other half would be to keep track of the signal edges and determining how many rollovers while polling a digital input (e.g. dir PortC.1 in). Another possibility is using a CCPx interrupt, if other things are happening in the program, check out the forum for an example.
Here is a working code!
It is for the 16F887 because that is the proto board I had to test on.
The interrupt does all the work. Port D has 8 LEDS on the protoboard.
It is running in front of me right now and when I touch my metal pen to the RA4 input which is the T0CKI - T0 Clk input the LEDS on portD light up 00****00 … that is binary for 60hertz!! yahoo sometimes thing work
Good luck converting the code
'Frequecy read out on port D by 8 Leds
' Couter T0 counts the pulses into RA4
' Counter timer T1 interrupts every 1 sec because it has a 32khz clock crystal on it and acouple of caps and a resistor
' Read about the external T1 osc in the Microchip specs sheet
'
'1/29/2010 all rights reserved.. Mike Otte
#chip 16F887, 8
#config INTOSC
RTCinit
mins = 0
hours = 0
secs=0
'Pin Direction
DIR PORTD OUT ' this is the frequency read out in binary
Mainloop:
' waste time her in main loop that does nothing
wait 1 s
'
wait 1 s
Goto Mainloop
' ----------- Subrutines below -----------------
sub RTCinit
CLRF PIR1 ;
MOVLW 0x0E
MOVWF T1CON ; RC1 is overridden by TCKO
BSF INTCON, PEIE ; Enable Peripheral Interrupts
BSF INTCON, RBIE ; Disable PORTB<7:4> Change Interrupts
BSF INTCON, GIE ; Enable all Interrupts
MOVLW b'11101000' ; Configure for external clock counting
MOVWF OPTION_REG
MOVLW 0x80 ; Preload TMR1 register pair
MOVWF TMR1H ; for 1 second overflow
CLRF TMR1L
MOVLW b'00001111' ; Configure for external clock,
MOVWF T1CON ; Asynchronous operation, external oscillator
CLRF secs ; Initialize timekeeping registers
CLRF mins
MOVLW 12
MOVWF hours
Wait 5 10us
'BANKSEL PIE1
BSF PIE1, TMR1IE ; Enable Timer1 interrupt
end sub
sub INTERRUPT
'BANKSEL TMR1H
BSF TMR1H, 7 ; Preload for 1 sec overflow
BCF PIR1, TMR1IF ; Clear interrupt flag
BSF INTCON, PEIE ; Enable Peripheral Interrupts
BSF INTCON, RBIE ; Disable PORTB<7:4> Change Interrupts
BSF INTCON, GIE ; Enable all Interrupts
INCF secs, F ; Increment seconds
PortD = Tmr0
Tmr0 = 0
'If PORTD.3 = ON Then
' Set PORTD.3 OFF
' RETURN
'END IF
'Set PORTD.3 ON
RETURN ; Done
end sub
thanks to all, forgot the mention Great Cow Basic is great, thanks to all for the work and help!