1 hz interrupt

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
Hi
Have this problem.
PIC 16F690 4 MHz FOSC
have to read timer1(16bit) for 1 sec.
update my LCD and some more.
clear timer1,
read timer1 for 1 sec Again,
update my LCD and some more.
ect.
have to do this repeatly over and over.
until either an input(buttons) or the input from timer1 is way off ( alarm sounds )
Any hints on getting the interrups going ?
 

shteii01

Joined Feb 19, 2010
4,644
Can you use external circuit that is connected to external interrupt pin on the PIC? This way you get external signal that triggers interrupt, the interrupt routine does all the things you need done, then PIC goes back into "holding pattern" like running empty super loop. Then 1 second later another signal arrives, interrupt routing is activated, things that you need done are done, and PIC goes back to waiting.

Another thing you could do is use external clock ic like Real Time Clock ic, DS1307 for example. DS1307 is not the best, there are better ic now that do the same thing. The PIC would poll the RTC, when it sees that the second changed, it would do your stuff, then go back to checking the time to see if the second changed.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
Yes external could be the solution, but it also have some downsides.
When i "Count" for 1 sec, then i will do all the updates of LCD, move to another input, get ready for NeXT "second" to arrive
Lots of waiting time, assuming the external input is 1 Hz.
If i could use internal timers ( second ticks) i should be able to do this
read "Counts" for 1 sec, update LCD move to another input, and now select start om NeXT second, with internal timer on,.
think it's difficult to explain,
could i use timer0 to divide by 100, and the set 100hz as input , that way i could reset the timer to "100" when ready,

Could connect a Xtal to RA4-5, but that will take my spare pins, but think i will go with that solution.
connect a Xtal at 32.768 kHz and use an interrupt, but Again i will have some waiting time.
difficult to deside.
 

shteii01

Joined Feb 19, 2010
4,644
I guess I don't understand the function of the 1 second. Do you want to "do things" at the start of each second? Or. Do you want to have 1 second intervals between "doing things"?

If you simply need 1 second interval between Action A and Action B, then use internal timers. To get 1 second from internal timers you just need to figure out how many times the timer will overflow. Example, lets say that the timer has maximum of 250 milliseconds, so the timer reaches 250 ms, overflow 1, you set it to start again, it reaches overflow 2, you set it again, it reaches overflow 3, you set it again, it reaches overflow 4, you now have four 250 ms intervals, 4*250 ms=1000 ms=1 second. That is how you create large time intervals using small timers.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
1. start a periode of 1 sec, stop by an interrupt,
2 do stuff with the Counts from ex "timer0" ( external signal from RPM )
3. read all my buttons input
3.1 if buttons is pressed, do that stuff.
4 select NeXT shaft to Counts RPM from.
5 starts a new periode of 1 sec.
ect.

Yes i would have used timers if i could figure out how, cause if i use use that need 15 times to get to 1 sec, it would interrupt 15 times, ?
if i run the internal clockspeed at 4 MHz it can only go Down to 66,667 msec. pr overflow, or i dont understand it.
 

shteii01

Joined Feb 19, 2010
4,644
1. start a periode of 1 sec, stop by an interrupt,
2 do stuff with the Counts from ex "timer0" ( external signal from RPM )
3. read all my buttons input
3.1 if buttons is pressed, do that stuff.
4 select NeXT shaft to Counts RPM from.
5 starts a new periode of 1 sec.
ect.

Yes i would have used timers if i could figure out how, cause if i use use that need 15 times to get to 1 sec, it would interrupt 15 times, ?
if i run the internal clockspeed at 4 MHz it can only go Down to 66,667 msec. pr overflow, or i dont understand it.
You would have the overflow flag turn on 15 times. If I remember the code right, you stop the timer, clear overflow flag, load zero into the timer, start timer. You can do that using for loop because you know exactly how many overflows you need for an interval of 1 second. The whole process should take maybe a few milliseconds, maybe even less than that.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
have read a Little on timer2 in 16f690
as i get it, correct if wrong
FOSC is 4 MHz
input to timer2 is FOSC/4 = 1 MHz
Prescaler set to 1:16 gives a 1000000/ 62500 Hz.
Timer2 periode register ( PR2) set to 250.
gives a timer2 rollover at 62500/250 = 250 Hz
this goes to a POSTSCALER there will be set to 1:10
output and interrupt = 25 hz ????
then i need to Count to 25 before i finish the counting - the times it takes to check the timer. ex

if(TMR2IF)
{ puls++;
if (puls==25)
{ // stop timer2 and my RPM input
}

Somethin like that, do i need to take care of these 25 loops time, or is that just nothing ?
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
Study of datasheet.
Taken from the datasheet

6.4 Timer1 Oscillator
A low-power 32.768 kHz crystal oscillator is built-in between pins OSC1 (input) and OSC2 (amplifier output). The oscillator is enabled by setting the T1OSCEN control bit of the T1CON register. The oscillator will continue to run during Sleep. The Timer1 oscillator is shared with the system LP oscillator. Thus, Timer1 can use this mode only when the primary system clock is derived from the internal oscillator or when the oscillator is in the LP mode. The user must provide a software time delay to ensure proper oscillator start-up.

Will this mean that i can use this to 1 sec interrupt ? Without connecting Any thing to the pins ?
Just preset timer1 to 32768 and it will rollover and create an interrupt.
 

joeyd999

Joined Jun 6, 2011
5,220
Study of datasheet.
Taken from the datasheet

6.4 Timer1 Oscillator
A low-power 32.768 kHz crystal oscillator is built-in between pins OSC1 (input) and OSC2 (amplifier output). The oscillator is enabled by setting the T1OSCEN control bit of the T1CON register. The oscillator will continue to run during Sleep. The Timer1 oscillator is shared with the system LP oscillator. Thus, Timer1 can use this mode only when the primary system clock is derived from the internal oscillator or when the oscillator is in the LP mode. The user must provide a software time delay to ensure proper oscillator start-up.

Will this mean that i can use this to 1 sec interrupt ? Without connecting Any thing to the pins ?
Just preset timer1 to 32768 and it will rollover and create an interrupt.
No. You need to connect a 32khz crystal (and caps to ground) between the pins. The oscillator circuit is provided. Not the crystal.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
Thanx, ok then i will use the internal FOSC/4( set to 2 MHz) prescale 8. and set timer to 62500 and rollover every second?
T=(4 /Fosc)∗Presc∗(Resolution−Preload)
1 sec = 4 / 2.000.000*8*(65536-3036)
Am i right ?
 

MaxHeadRoom

Joined Jul 18, 2013
28,576
Here is a sample file from Dave Benson book.
Code:
;=======SECONDS.ASM=================================9/30/02==
        list    p=16f870
    __config  h'3f71'
        radix   hex
;------------------------------------------------------------
;seconds demo
;    external oscillator, 32768 Hz, timer 1, prescaler 1:1
;------------------------------------------------------------
;       cpu equates (memory map)

;------------------------------------------------------------
;------------------------------------------------------------
        org     0x000
    goto    start    ;skip over location pointed to by
            ;   interrupt vector
    org    0x004
    goto    iserv
;
start:
        bsf        STATUS,    RP0  ;switch to bank 1
        movlw   b'00000000' ;port B outputs
        movwf    TRISB
        movlw    b'00000110' ;turn off A/D, port A
        movwf    ADCON1
        bcf        STATUS,    RP0  ;switch back to bank 0
        movlw    b'00000000' ;port B lines low
        movwf    PORTB
        bcf        INTCON,    7    ;disable global interrupts
        bcf        INTCON,    6    ;disable peripheral interrupts
        bsf        STATUS,    RP0  ;bank 1
        bcf        PIE1,    0    ;disable tmr1 interrupts
        bcf        STATUS,    RP0  ;bank 0
        bcf        PIR1,    0       ;clear timer 1 interrupt flag
        movlw    b'00001010' ;prescaler and tmr1 setup,
        movwf    T1CON       ;   tmr1 off
        clrf    TMR1H    ;clear timer 1 high
        clrf    tmr1l    ;clear timer 1 low, clear prescaler
        bsf        INTCON,    7    ;enable global interrupts
        bsf        INTCON,    6    ;enable peripheral interrupts
        bsf        STATUS,    RP0  ;bank 1
        bsf        PIE1,    0    ;enable tmr1 interrupts
        bcf        STATUS,    RP0  ;bank 0
        bsf        T1CON,    0    ;timer 1 on
circle:
        goto    circle
;------------------------------------------------------------
iserv:
        bcf        PIR1,    0    ;clear timer 1 interrupt flag
        bsf        TMR1H,    7    ;set up timer 1 to roll over at
            ;   32,768 counts
        btfss    PORTB,    0    ;port B, bit 0 STATUS?
        goto    setbit    ;bit is clear
clrbit:
        bcf        PORTB,    0    ;clear port B, bit 0
        retfie        ;return from interrupt
setbit:
        bsf        PORTB,    0    ;set port B, bit 0
        retfie        ;return from interrupt
;------------------------------------------------------------
        end
;------------------------------------------------------------
;at device programming time, select:
;       memory unprotected
;       watchdog timer disabled (default is enabled)
;       standard crystal XT (using 4 MHz osc for test)
;       power-up timer on
;    brown-out reset enabled
;    lvp disabled
;    debug mode disabled
;============================================================
Or
Code:
;=======TIME.ASM====================================9/30/02==
        list    p=16f870
    __config  h'3f71'
        radix   hex
;------------------------------------------------------------
;seconds, minutes, hours demo
;    external oscillator, 32768 Hz, timer 1, prescaler 1:1
;------------------------------------------------------------
;       cpu equates (memory map)
status    equ    0x03
porta    equ    0x05
portb   equ     0x06
intcon    equ    0x0b
pir1    equ    0x0c
tmr1l    equ    0x0e
tmr1h    equ    0x0f
t1con    equ    0x10
trisa    equ    0x85
trisb    equ    0x86
pie1    equ    0x8c
adcon1    equ    0x9f
sec    equ    0x20
min    equ    0x21
hr    equ    0x22
;------------------------------------------------------------
;    bit equates
z    equ    2
rp0    equ    5
;------------------------------------------------------------
        org     0x000
    goto    start    ;skip over location pointed to by
            ;   interrupt vector
    org    0x004
    goto    iserv
;
start    bsf    status,rp0  ;switch to bank 1
    movlw   b'00000000' ;port B outputs
        movwf    trisb
    movlw    b'00000110' ;turn off A/D, port A
    movwf    adcon1
    movlw    b'00011111' ;port A inputs
    movwf    trisa
    bcf    status,rp0  ;switch back to bank 0
    movlw    b'00000000' ;port B lines low
    movwf    portb
    bcf    intcon,7    ;disable global interrupts
    bcf    intcon,6    ;disable peripheral interrupts
    bsf    status,rp0  ;bank 1
    bcf    pie1,0    ;disable tmr1 interrupts
    bcf    status,rp0  ;bank 0
    bcf    pir1,0       ;clear timer 1 interrupt flag
    movlw    b'00001010' ;prescaler and tmr1 setup,
    movwf    t1con       ;   tmr1 off
    clrf    tmr1h    ;clear timer 1 high
    clrf    tmr1l    ;clear timer 1 low, clear prescaler
    clrf    sec
    clrf    min
    clrf    hr
    bsf    intcon,7    ;enable global interrupts
    bsf    intcon,6    ;enable peripheral interrupts
    bsf    status,rp0  ;bank 1
    bsf    pie1,0    ;enable tmr1 interrupts
    bcf    status,rp0  ;bank 0
    bsf    t1con,0    ;timer 1 on
display    movf    sec,w    ;get seconds
    movwf    portb    ;display seconds
minutes    btfss    porta,0    ;display minutes?
    goto    hours    ;no
    movf    min,w    ;get minutes
    movwf    portb    ;display minutes
    goto    minutes
hours    btfss    porta,2    ;display hours?
    goto    display    ;no
    movf    hr,w    ;get hours
    movwf    portb    ;display hours
    goto    hours
;------------------------------------------------------------
iserv    bcf    pir1,0    ;clear timer 1 interrupt flag
    bsf    tmr1h,7    ;set up timer 1 to roll over at
            ;   32,768 counts
    incf    sec,f
    movf    sec,w    ;compare
    sublw    d'60'    ;seconds = 60?
    btfss    status,z    ;test z flag, skip next instruction
               ;   if flag is set
    retfie
    clrf    sec    ;clear seconds
    incf    min,f    ;increment minutes
    movf    min,w    ;compare
    sublw    d'60'    ;minutes = 60?
    btfss    status,z    ;test z flag, skip next instruction
               ;   if flag is set
    retfie
    clrf    min    ;clear minutes
    incf    hr,f    ;increment hours
    movf    hr,w    ;compare
    sublw    d'24'    ;hours = 24?
    btfsc    status,z    ;test z flag, skip next instruction
               ;   if flag is clear
    clrf    hr    ;clear hours
    retfie
;------------------------------------------------------------
        end
;------------------------------------------------------------
;at device programming time, select:
;       memory unprotected
;       watchdog timer disabled (default is enabled)
;       standard crystal XT (using 4 MHz osc for test)
;       power-up timer on
;    brown-out reset enabled
;    lvp disabled
;    debug mode disabled
;============================================================
Also http://www.piclist.com/techref/member/jwn-hotmail-f41/TIMER_TUTORIAL.htm

Max.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
The problem is that i will NOT use an external xtal, cause i do not have I/O enough.
And i ASM code it is to difficult, rather C code. :)
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
Could this thereoe work
Set 4 mhz system. Div by 4 is 1mhz
Then prescale by 8. Gives a 125 khz input to timer1.
Then set an input interrupt on change. Then start timer1 . Wait until next interrupt. Stop timer1 read the value. Take the value and calculate a RPM depend on how long time it takes from first to next interrupt.
Or is that to unprecise to read rpm on. ??
Ex timer1 counts 60000 this is then
0.48 sec. Eq. 60/0.48 125 rpm asuming 1 tick each rpm ???
 

joeyd999

Joined Jun 6, 2011
5,220
Could this thereoe work
Set 4 mhz system. Div by 4 is 1mhz
Then prescale by 8. Gives a 125 khz input to timer1.
Then set an input interrupt on change. Then start timer1 . Wait until next interrupt. Stop timer1 read the value. Take the value and calculate a RPM depend on how long time it takes from first to next interrupt.
Or is that to unprecise to read rpm on. ??
Ex timer1 counts 60000 this is then
0.48 sec. Eq. 60/0.48 125 rpm asuming 1 tick each rpm ???
Are you not aware of the ECCP module?
 
Top