Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Estimating time calculation

Status
Not open for further replies.

richacm

New Member
Hi,

I searched around a few threads trying to answer my question but I still can't see where my calculations are going wrong.

What I want to do is estimate roughly 5 minutes while processing in PIC and then do some other code.

I am using the PIC16F877A.

What I've done is setup up a TMR1 interupt. I set the TMR1H and TMR1L to be 0. Then everytime the interupt fires I increment a count variable which I keep track of in the core routine.

Now to calculate 5 minutes I did this:

1. 4/Osc Freq = Time per instruction = 4/8Mhz = 0.5:mu:Sec
2. Time it takes for the TMR1 interupt to fire is the time per instruction * the timer Low * the timer High registers = 0.5:mu:Sec * 256 * 256 = .5*256*256
= 0.032768 Sec
3. 1 sec would therefore be when the count = 1 / 0.032768 = ~30.5
4. So 5 minutes is the 30.5 * 300 = 9155

But when I check the timing on the chip this turns out to be 10 minutes. Can someone check my calculations?

Thanks,

Craig
 
What crystal do you have connected? Your calculations suggest an 8MHz crystal but this is an unusual value. What value do you put in T1CON? Other than that your calculations look correct.

Mike.
 
One simple way to test is run your code through MPLABs simulator and use the stopwatch. I'll look at the math in a bit. Are you resetting or preloading TIMER1 or allowing it to freerun?
 
I have a 8Mhz crystal. When the timer interupts I set the registers back to 0 and clear the interupt flag.

I'll try testing in MPLAB as well.

Thanks
 
I can use any timer I like, the reason I used timer 1 was it wasn't timer 0 which only went up to 0xFF.

Are there reasons for changing?

I suppose the registers all are set to 0 anyway so understand why I don't need to reset.

Cheers
 
Can you post your ISR code and the code for checking the 9155 if it's not in the ISR?

Mike.
 
I'm using mikroBasic - pretty easy to understand...

Code:
sub procedure interrupt
    ' Timer interupt
    if TestBit(INTCON, TMR1IF) = 1 then
      Inc(cnt)
      ClearBit(INTCON, TMR1IF)            ' clear TMR1IF
      TMR1H = $00
      TMR1L = $00
    end if
end sub

main:
  TRISA  = $FF              ' PORTA is input
  TRISB = $0                ' PORTB is output
  TRISC = $0                ' PORTC is output
  PORTB = 0                 ' Initialise Port B - this is the filling status and External EEprom
  PORTC = 0                 ' Initialise Port C - this is the LED display

  'Set up the timer
  T1CON = 1                 ' Setup timer
  PIR1.TMR1IF = 0           ' clear TMR1IF
  TMR1H = $00
  TMR1L = $00
  PIE1.TMR1IE  = 1          ' enable Timer1 interrupt

  cnt =   0                 ' initialize cnt
  INTCON = $C0              ' set GIE, PEIE
  
  while TRUE
    ' do sample
    adc_r = Adc_Read(0)
    o_r = convertToBar(adc_r)
    PORTC = o_r              ' place the output on to PORT C
    if cnt > timeLimit then  ' Check if times up and we need to do a recording
    ' Save the value in to EEprom
        o_r = convert10bitTo8bit(adc_r)
        writeToMemory(byte(o_r))
        cnt = 0              ' Reset count
    end if
  wend
end.

I've taken out irrelevant code. timeLimit variable is 9155
 
Last edited:
Stop clearing the TMR1H & TMR1L in the interrupt routine.

I don't use MicroBASIC, do they have MPLAB integration?
 
Last edited:
I'm sure it's very popular, I use ASM with the 16F PICs. I've also used PIC BASIC Pro and it does have MPLAB debug support.
I could write some demo code in MPASM, do use use assembly?
 
I can understand assembly and can compare with the assembly produced from mikrBasic so that would be good!

So do you think my calculations are correct?

Thanks
 
Here's a TMR2 based 20ms exactly interrupt code fragment (based on your 8MHz crystal)
Code:
; 20ms interrupt using TMR2 with 8MHz crystal        
    list    p=16F877A
    include    <p16F877A.inc>
    __CONFIG        _HS_OSC&_WDT_OFF&_LVP_OFF
Jiffy   equ     0x20
        org     0x00    
        goto    Init
        org     0x04
IRQ     btfss   PIR1, TMR2IF
        goto    Exit
        incf    Jiffy   ; 20ms interval
        bcf     PIR1, TMR2IF
Exit    retfie       
; 8MHz OSC / 4 / 16 / 250 / 10 = 50 (20ms period)
Init    movlw   b'01001111'     ; TMR2 ON
        movwf   T2CON           ; 1:16pre , 1:10post
        bsf     STATUS,RP0      ;b1
        movlw   .249            
        movwf   PR2             ;b1 249 period
        bsf     PIE1, TMR2IE    ;b1 enable TMR2 IRQ
        bcf     STATUS,RP0
        movlw   0xC0
        movwf   INTCON
        goto    $
        END
 
Last edited:
Many appologies. I have finally figured out what was going on. MikroBasic was actually throwing me out. I was doing preliminary testing on the PIC16F690 that came with the PICkit 2 and its actually got an internal oscilator that can be used. I set this within the IDE for mikroBasic to 8Mhz but I figured out that this does absolutely nothing.

I had to manually set the IRCF bits to 111 (8Mhz) for it to run at that speed. By default it runs at....you guessed it 4Mhz - hence all my time calculations when I tested them were double what they should be. It wasn't until I poored through the datasheet again and again that I figured it out.

Phew....

Thanks again and sorry for the red herrings!

Oh and thanks Bill for that listing - it gave me really good pointers on how to use Timer 2. I am going to switch to this one instead.
 
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top