---
+ Post New Thread
Results 1 to 15 of 15
  1. #1
    Newbie level 5
    Points: 966, Level: 7
    sycluap's Avatar
    Join Date
    Dec 2007
    Posts
    10
    Helped
    0 / 0
    Points
    966
    Level
    7

    picbasic pro timer

    I would like to ask, how to utilize the timer function in the microcontroller to get the difference between start time and stop time and then display it at LCD. E.g, switch pressed once to start timer, press again to stop timer, then the difference between start time and stop time is calculated and displayed on LCD. I am doing the programming using PicBasic Pro.

    May I ask can this be done? I am a total newbie in using microcontroller, hope can help. Thanks in advance to all the experts.

  2. #2
    VVV
    VVV is offline
    Advanced Member level 5
    Points: 20,960, Level: 35
    VVV's Avatar
    Join Date
    Nov 2004
    Posts
    1,582
    Helped
    363 / 363
    Points
    20,960
    Level
    35

    timers in pic16f877a

    Of course it can be done.
    Depending on how much code you need to run, you can choose an interrupt approach or a polling approach.

    For polling, you just monitor an input pin and when it changes state, you start the timer. Then monitor the pin again and stop the timer when the state of the pin changes back. The timer contents are the time you need.
    Of course, with this approach you wil lose a few instruction cycles, but running at 20MHz your instruction cycle is 200ns. So if you lose 5 cycles, you lose only 1us.

    If this is a problem, then you can try using the CCP in the PIC16F877A.
    Set it up to capture every rising edge. So the contents of the timer will get latched when the rising edge occurs. At the same time, you get an interrupt and read the latched timer contents and save them. On the next edge the new timer contents will be latched and you get an interrupt. Subtract the two latched values and you get the exact time between the events, because all is now done in HW, you do not lose any cycles.
    It all depends on your actual requirements.



    •   Alt13th December 2007, 17:25

      advertising

        
       

  3. #3
    Newbie level 5
    Points: 966, Level: 7
    sycluap's Avatar
    Join Date
    Dec 2007
    Posts
    10
    Helped
    0 / 0
    Points
    966
    Level
    7

    pic 16f877a counter

    Timing precision is very critical for my project, thus, I think the best method is the method that will not lose any cycles.

    However, I will first start with polling method to get used to the codes as I am totally new. How to declare the timer function to be used and monitor the pin changes? How to stored the timing difference in a variable and the display it to the LCD? Can you please guide me further in this matter? I am coding using PicBasic Pro.

    Very much thanks!



  4. #4
    VVV
    VVV is offline
    Advanced Member level 5
    Points: 20,960, Level: 35
    VVV's Avatar
    Join Date
    Nov 2004
    Posts
    1,582
    Helped
    363 / 363
    Points
    20,960
    Level
    35

    using pic16f877a timer

    The most precise is indeed the one using the CCP, but even that has some limitations, in terms of resolution. I think the best resolution you can get is 0.2us, when the oscillator is running at 20MHz.



    •   Alt14th December 2007, 22:17

      advertising

        
       

  5. #5
    Member level 1
    Points: 1,624, Level: 9

    Join Date
    Mar 2005
    Location
    USA
    Posts
    39
    Helped
    8 / 8
    Points
    1,624
    Level
    9

    timer1 coding for pic16f877a

    Hello,

    If you goto www.picbasic.uk.co you will find many threads regarding the use of timers. Just about anything you could ask for including lots of example code. Also try www.melabs.com.

    HTH,

    BobK



  6. #6
    Newbie level 5
    Points: 966, Level: 7
    sycluap's Avatar
    Join Date
    Dec 2007
    Posts
    10
    Helped
    0 / 0
    Points
    966
    Level
    7

    pin functions of pic16f877a

    Thank for the reply VVV and BobK. I have found an example project (Olympic Timer) which is very similar to what I need for me project in the forum suggested.

    However, I am facing a problem which, I need the timer to count in the interval of 1ms. What I can obtain and learn is 10ms interval.

    The expert in that forum suggested me to change the preset Timer1 register value to suit the 1ms interval. But I do not know how to get it, no matter what value I change, the timer gets even slower compare to 10ms interval. Can anyone teach me how to calculate the actual preset value for Timer1 register, so that I can get 1ms timer interval instead of 10ms? I am using 16F877A and 4Mhz clock, and I am coding in PicBasic Pro.

    Please see here. http://www.picbasic.co.uk/forum/showthread.php?t=7729

    Or is there any better solution to get 1ms timing interval?

    1ms interval is very important for my project. Please help.



    •   Alt24th December 2007, 04:55

      advertising

        
       

  7. #7
    VVV
    VVV is offline
    Advanced Member level 5
    Points: 20,960, Level: 35
    VVV's Avatar
    Join Date
    Nov 2004
    Posts
    1,582
    Helped
    363 / 363
    Points
    20,960
    Level
    35

    why tmr1 value change

    I am sorry, I do not understand the requirements anymore: do you need a resolution of 1ms or do you need to measure time intervals in the 1ms range with the best possible resolution?

    For 1ms resolution you can simply use polling, even at 4MHz.
    If you need better resolution, then again I suggest you use the CCP, which will allow you to measure with a resolution of 1us at 4MHz.

    I cannot help with PICBasic, I am an assembler guy.



  8. #8
    Newbie level 5
    Points: 966, Level: 7
    sycluap's Avatar
    Join Date
    Dec 2007
    Posts
    10
    Helped
    0 / 0
    Points
    966
    Level
    7

    pic16f877 timer calculation

    I am sorry for making the requirement unclear. Actually, I need to timer to count in 1ms resolution. Meaning that, the timer will count in 1ms increment value and display in LCD. E.g. If I press start button, the timer will start counting in 1ms increment, until I press stop button, the counted value will be displayed on the LCD.

    The TIMER1 function I know how to use, the problem is I do no know how to set the TIMER1 register value so that it can be in 1ms resolution and display it on the LCD.

    Perhaps coding in assembly will help?



  9. #9
    VVV
    VVV is offline
    Advanced Member level 5
    Points: 20,960, Level: 35
    VVV's Avatar
    Join Date
    Nov 2004
    Posts
    1,582
    Helped
    363 / 363
    Points
    20,960
    Level
    35

    1us in seconds

    OK, now I understand.

    You can use TMR1 to generate interrupts every 1ms.
    To do that, preload the timer with a qantity that will make it overflow in 1ms.
    For example: assume the oscillator is 4MHz. Then the TMR1 clock is 1MHz. That means you need 1000 counts for 1ms. So preload the timer with 65536-1000=64536.

    It will then generate an iterrupt every 1ms. In the ISR, increment a pair of registers (or more) which will be your ms counter. These registers get cleared when the first rising edge is detected and read on the second rising edge. That is the time in ms between the edges, which is what you need.

    Note that you need to do the debouncing in hardware.


    So the code might look like this:
    Code:
    #define    BUTTON   PORTB,0
    
    
    	ORG 0x00			;reset vector
    
    	goto	main			;
    
    
    
    	ORG 0x04 			;Interrupt vector
    
    	movwf	W_temp			;save W
    	swapf	STATUS,W		;save status reg
    	movwf	STATUS_temp		;
    	clrf	STATUS			;make sure we are in bank 0, although we do not switch banks here
    
    	bcf	PIR1, T1IF		;clear interrupt flag
    
    	bcf	INTCON,T1ON		;stop the timer
    	movlw	high (.65536-.1000)	;reload timer; the value may need to be adjusted slightly, to get exactly 1ms
    	movwf	TMR1H			;
    	movlw	low (.65536-.1000)	;
    	movwf	TMR1L			;
    
    	incfsz	Counter,F		;increment the 16 bit ms counter
    	incf	Counter+1,F		;
    
    	swapf	STATUS_temp,W		;restore registers
    	movwf	STATUS			;
    	swapf	W_temp,F		;
    	swapf	W_temp,W		;
    	retfie				;return
    
    
    
    main:					;main code
    
    	;put all your initializations here
    
    
    	clrf	Counter			;clear the 16-bit counter
    	clrf	Counter+1		;
    
    	
    	movlw	B'10000000'		;enable interrupts in general
    	movwf	INTCON			;
    
    Wait_h:	btfss	BUTTON			;wait here until button pressed
    	goto	Wait_h			;
    
    	movlw	high (.65536-.1000)	;preload timer; value can be changed, so the first interrupt occurs exactly after 1ms
    	movwf	TMR1H			;
    	movlw	low (.65536-.1000)	;
    	movwf	TMR1L			;
    
    	bsf	T1CON,TMR1ON		;turn on TMR1
    	bcf	PIR1,T1IF		;clear TMR1 interrupt flag, just in case
    	bsf	INTCON,PIEI		;enable peripherals interrupts (TMR1 is a peripheral)
    
    Wait_l:	btfsc	BUTTON			;wait for button to be released
    	goto	Wait_l			;
    
    Wait_r:	btfss	BUTTON			;wait for the rising edge here
    	goto	Wait_r			;
    
    	bcf	T1CON			;stop TMR1
    	bcf	INTCON,PIEI		;disable peripheral interrupts
    
    	call	DISPLAY			;call the routine that displays the time on the LCD
    
    	clrf	Counter			;clear the 16-bit counter
    	clrf	Counter+1		;
    	
    Wait_f:	btfsc	BUTTON			;now wait here for a falling edge
    	goto	Wait_f			;
    
    	goto	Wait_h			;re-start the cycle



  10. #10
    Newbie level 5
    Points: 966, Level: 7
    sycluap's Avatar
    Join Date
    Dec 2007
    Posts
    10
    Helped
    0 / 0
    Points
    966
    Level
    7

    function of pic 16f877a

    I refer to the Assembly Codes provided by Mr.VVV, I manage to get the clock to have in very near to 1ms interval. But, I the timer seems to be slightly out of the actual timing when I compare the timer to a watch.

    e.g, watch seconds ticked 1.5x ~ 2x faster than the timer programmed in the uController.

    I tried to change the value to load into the TIMER1 registers, even to Highbyte=$FF, LowByte=$FF, but it seems that still unable to get as accurate as in the watch, although it is very near to it.

    And, my device cannot run when I change to 20MHz crystal. But it works just fine in 4Mhz, may I know what is wrong? Tried to change the configuration bits from XT to HS in MPLAB 8.00, but when I recompile, the bit change back to XT.

    I attach the codes I wrote using PicBasic Pro, can any experts correct my mistakes to get the desired interval?

    Help is very much appreciated.



  11. #11
    Advanced Member level 5
    Points: 14,575, Level: 29
    blueroomelectronics's Avatar
    Join Date
    Sep 2006
    Location
    Toronto, Canada
    Posts
    1,682
    Helped
    178 / 178
    Points
    14,575
    Level
    29

    fosc/4 pic 16f877a

    Hints:
    * Use a crystal that divides perfectly with binary into seconds
    * Don't run the timers asynchronously (don't clear or set them let them free run)
    * Use the CCP module (Compare mode)

    For 1ms timing 1/100th of a second a 6.5536MHz crystal would be perfect.



  12. #12
    Member level 1
    Points: 1,117, Level: 7

    Join Date
    Nov 2007
    Posts
    37
    Helped
    0 / 0
    Points
    1,117
    Level
    7

    pic16f877 timing

    PICbasic probably is a lot harder to be achieved than assembly language.



  13. #13
    Advanced Member level 5
    Points: 14,575, Level: 29
    blueroomelectronics's Avatar
    Join Date
    Sep 2006
    Location
    Toronto, Canada
    Posts
    1,682
    Helped
    178 / 178
    Points
    14,575
    Level
    29

    assembly pic16f877a variable definition

    Quote Originally Posted by IamnotJunk
    PICbasic probably is a lot harder to be achieved than assembly language.
    Very true. Who knows what sort of code the BASIC generates.



  14. #14
    Newbie level 5
    Points: 966, Level: 7
    sycluap's Avatar
    Join Date
    Dec 2007
    Posts
    10
    Helped
    0 / 0
    Points
    966
    Level
    7

    how to load value into timer1 of pic16f877

    Thanks for the hints, I will try on it now. Still need to study how to use CCP first.:D

    Added after 4 hours 14 minutes:

    Ok. I redo the program to make the Timer1 free run timer. Before timer start, it is loaded with with 0000h in the timer1 register. The timer starts when I press START.

    When I press stop, I get the value from TMR1H and TMR1L into 2 separate variables which I define as BYTE. After that, I get the actual result by:

    RESULT=TMR1H*256+TMR1L

    So, it that mean, the total RESULT * 1us = the total timing in seconds I obtained from the event? Not really sure about the calculation of the timer, but as far as I understand, using 4Mhz clock, it will be:

    4Mhz/4 = 1Mhz (Fosc/4 from T1CON.1=0, internal clock)
    T=1/1M=1us (per instruction cycle)
    thus, Result*1us = total time in second.

    Please correct me if I am wrong, really not very sure about the Timer1 calculation.

    Thanks in advance!



  15. #15
    VVV
    VVV is offline
    Advanced Member level 5
    Points: 20,960, Level: 35
    VVV's Avatar
    Join Date
    Nov 2004
    Posts
    1,582
    Helped
    363 / 363
    Points
    20,960
    Level
    35

    timer example in pic16f877a

    Yes, that is correct. With a prescaler of 1:1 the timer increments every 1us, so the result is in microseconds.


    1 members found this post helpful.

+ Post New Thread
Please login