Menu

Timer0 as word counter

Help
Paul Haug
2017-07-18
2017-07-18
  • Paul Haug

    Paul Haug - 2017-07-18

    Here I have setup the TIMER0 as word, and counter, but I cannot seem to read it as word. Any hints would be appreciated.
    When I run the code shown, it prints out xpcounter as a word, but timer0 as a byte, as it counts from 0 to 255 then returns to 0 and counts up again. It is like I am reading only the lower byte of the word.
    Any suggestions how to fix this ?
    (I am using Terminal.exe) as display)
    ASSY Ver 0.97.01 2107-02-20

    'Board test for bd v0.50
    ;Using PIC18F26K20
    ;Simple test for board checkout
    ;Includes Terminal test
    ; and timer0 as word counter
    ;P Haug 7/18/2017

    '#include "lcd_driver.h"
    #Option Explicit
    #chip 18F26K20, 8
    #config mclr=on ;reset PB enabled
    #config osc=int ;use internal clock
    set CKTXP = ON ;Set UART output to invert
    set DTRXP = ON ; set UART recv to inverted
    #define USART_BAUD_RATE 9600 ;this really is 19200 baud at current 8 clock rate of 8
    #define USART_BLOCKING
    #define USART_TX_BLOCKING
    #define RS232Out PORTC.6
    ; #define RS232In PORTC.7
    #define USART_BAUD_RATE 9600
    Dir RS232Out Out
    ; Dir RS232In In
    Dir porta.0 in
    #define T0CON = 0XA8 ;Config timer0 as input ctr
    #define T0CKI in ;Configure T0CKI (pin 6) as input for data
    #define pb porta.0 ;push button input
    dir pb in

    Dim delay as word
    Dim xpcounter as word
    ; #define output portb.0
    DIR PORTB out

    xpcounter = 0 ;reset count value for test
    Do
    timer0=0 ;reset timer0
    ;-------For simple test only------------------
    ;++++++++++++++++++++++++For debug test only;++++++++++++++++++++++++
    ; Slows down prgm
    HserPrint "Counter Value ==> "
    Hserprint timer0 ;This contains timer 0 as counter value
    HserPrintCRLF ;new line
    ;
    HSerPrint "Paul's Term Test "
    wait 10 ms ;Screen
    hserprint " "
    hserprint xpcounter
    xpcounter = xpcounter +257 ;Just big number to check output of 'word' values
    hserprint " "

    ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    wait 200 ms ;slow to make crt readable
    loop

     

    Last edit: Paul Haug 2017-07-18
  • Anobium

    Anobium - 2017-07-18

    I am not the master at timers but as Bill is away.. I will do my best.

    timer0=0 very bad practice. Usecleartimer 0. The method ensures the timer is cleared in the correct register order and it should handle byte and word timers.

    #define T0CON = 0XA8 ;Config timer0 as input ctr
    #define T0CKI in ;Configure T0CKI (pin 6) as input for dat
    

    Why not use inittimer0 (ext, {somevlue}) or correct your code? to be

    T0CON = 0XA8 ;Config timer0 as input ctr
    dir porta.4 in ;Configure T0CKI (pin 6) as input for data
    

    and, you are aware the lcd_driver.h is not required. We have a very extensive LCD driver - see all the demos,

     
  • Paul Haug

    Paul Haug - 2017-07-18

    Yes, I am aware of the extensive lcd driver library, this was my own custom for a serial 4 X20 display with special control charcters. I should have removed the "include" as it is not needed, just left over from a previous code.
    Still, that does not explain, to me anyway, how to read the timer0 word, not just the byte.
    I will include your other changes immeaditly.

     
  • Anobium

    Anobium - 2017-07-18

    Assign timer0 to a word.

    Notes from the Help: Timer 0 on Microchip PIC 18(L)F, as well as small number of 18C and 16(L)F microcontrollers, can be configured for either 8-bit or 16-bit operation.
    The default operation is as an 8-bit timer. Refer to the datasheet for your microcontroller to determine if it supports both 8-bit and 16-bit operation.

    Microchip PIC microcontrollers 16bit Timer 0 support:

    To configure PIC Timer 0 for 16_bit operation add the following line to the source code.

    #define TMR0_16bit
    

    As shown above, where Timer 0 supports 16bit you must use the following syntax:

    InitTimer0 source, prescaler, postscaler
    

    An example is shown below using the Great Cow BASIC constants. See the tables below for the constants.

    InitTimer0 Osc, PRE0_256 + TMR0_HFINTOSC ,  POST0_2
    

    In this example specfic values have been passed to the method. Great Cow BASIC supports passing specfic values to setup Timer 0. These specfic values be obtained from the MicroChip Configurator.

    InitTimer0 Osc, 0x91 ,  0x48      ' Where these values are specfic to the timer setup.
    
     
  • Paul Haug

    Paul Haug - 2017-07-18

    I guess I am really dense, sorry. I did configure timer0 as a word (16 bit) by using :
    #define T0CON = 0XA8 ;Config timer0 as input ctr
    #define T0CKI in ;Configure T0CKI (pin 6) as input for data
    but I also tried #define TMR0_16bit which seems to be the same thing.
    ;
    But my question is: How do I read timer0 as a 16 bit word. ?
    My code seems to read it (as a counter) only the lower 8 bits, thus when it overflows the the 8 bit lower byte and presumably increments the upper byte, I can only seem to read the lower byte.
    : Sorry for my repeated question, I just need to know how to read both bytes (lower & upper) of the 16 bit timer0 as a counter, as a word or two seperat bytes (upper & lower bytes), if needed..
    Paul
    EDIT: Further study of the PIC18F data sheet shows the upper byte as Timer0H, just need to figure out where it is located to read it.
    .

     

    Last edit: Paul Haug 2017-07-18
  • Paul Haug

    Paul Haug - 2017-07-18

    Data sheet calls for tmr0L and tmr0H as byte so changed the code to use the following:
    Hserprint tmr0L ;print lower byte
    Hserprint tmr0H ;print upper byte

    tmr0L works, but tmr0H always return zero., but the asm and compiler accepts these without errors.
    .

     

    Last edit: Paul Haug 2017-07-18
  • Anobium

    Anobium - 2017-07-18

    Here you go - a few syntax errors on using the timers. When you get a moment I would like feedback re the Help - no rush.

    'Board test for bd v0.50
    ;Using PIC18F26K20
    ;Simple test for board checkout
    ;Includes Terminal test
    ; and timer0 as word counter
    ;P Haug 7/18/2017
    
    '#include "lcd_driver.h"
        #Option Explicit
             #chip 18F26K20, 8
                #config mclr=on            ;reset PB enabled
                    #config osc=int             ;use internal clock
     set CKTXP = ON  ;Set UART output to invert
     set DTRXP = ON  ; set UART recv to inverted
         #define USART_BAUD_RATE 9600  ;this really is 19200 baud at current  8 clock rate of 8
             #define USART_BLOCKING
                #define USART_TX_BLOCKING
                    #define RS232Out PORTC.6
     ; #define RS232In  PORTC.7
         #define USART_BAUD_RATE 9600
     Dir RS232Out Out
     ; Dir RS232In In
     Dir porta.0 in
    
     #define TMR0_16bit   'set up timer0 as a 16 bit timer
    
    T0CON = 0XA8  ;Config timer0 as input ctr
    dir porta.4 in   '#define T0CKI in      ;Configure T0CKI (pin 6) as input for data
    #define pb porta.0   ;push button input
     dir pb in
    
    Dim  delay as word
    Dim xpcounter as word
    ; #define output portb.0
    DIR PORTB out
    
      xpcounter = 0  ;reset count value for test
     Do
    cleartimer 0  ' timer0=0  ;reset timer0
    ;-------For  simple test only------------------
    ;++++++++++++++++++++++++For debug test only;++++++++++++++++++++++++
     ; Slows down prgm
      HserPrint "Counter Value ==> "
      Hserprint timer0  ;This contains timer 0 as counter value
      HserPrintCRLF ;new line
      ;
      HSerPrint "Paul's Term Test "
         wait 10 ms ;Screen
           hserprint "  "
           hserprint xpcounter
           xpcounter =  xpcounter +257 ;Just big number to check output of 'word' values
          hserprint "  "
    
      ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    wait 200 ms  ;slow to make crt readable
    loop
    
     
  • Paul Haug

    Paul Haug - 2017-07-18

    Copied and pasted your corrected code, works perfect, thanks. Now I need to study your corrections to understand how it works.
    Many thanks Anobium, now my project can move forward.

     

    Last edit: Paul Haug 2017-07-18
  • Anobium

    Anobium - 2017-07-18

    Excellent. Good to hear.

     

    Last edit: Anobium 2017-07-18
  • Paul Haug

    Paul Haug - 2017-07-19

    OK, the code works, but a few questions to help me learn this 16 bit counter stuff.
    ;
    #define TMR0_16bit 'set up timer0 as a 16 bit timer
    T0CON = 0XA8 ;Config timer0 as input ctr
    ;
    Here you added the define TMR0_16bit
    Should not T0CON = 0XA8 alone have set the T0CON register to a 16 bit (Bit 6 set to 0) as defined in the PIC18F data sheet, but yet I need both for the code to work (I tested all combinations)??.
    Data sheet:
    Bit 7 (msb) 1 enable
    Bit 6 = 0 Timer0 as 16 bit ctr
    Bit 5 = 1 Transition on T0CKI pin
    Bit 4 = 1 increment on posite edge
    Bit 3 = 1 prescaler not assigned. timer0 input bypasses prescaler
    Bit 2 thru 0 prescaler values 1:2 (but not used so don't care)
    Sorry, I am one of those that need to understand the details.
    Paul

     

    Last edit: Paul Haug 2017-07-19
    • Anobium

      Anobium - 2017-07-19

      What a good question.

      Setting the T0CON register bit does enable the Timer to operate as a 16 bit timer. Setting the #define then enables the Great Cow library to handle the timer as a 16 bit timer - the default is an 8 bit timer.

      Inside the library the methods treat your calls as 16 bit or 8 bit dependent upon that define, And, all done with the same commands/methods.

      • Defines timer0 as a word or a byte variable
      • Handles the different chips for timer0 with 16bit
      • Return timer0 as a word or a byte
      • Handles timer0 methods as 16 or 8
      • Handles PIC and AVR 16 or 8 timer registers

      So, omitting the define simply meant none of the methods worked in 16 bit mode for timer 0.

      If you want to have a look - please do. Find timer.h, then search for TMR0_16BIT, if you are using the IDE then in the search dialog select Mark all. You will see all the work that is controlled by this define.

      Anobium

       
  • Paul Haug

    Paul Haug - 2017-07-19

    >* Setting the #define then enables the Great Cow library to handle the timer as a 16 bit timer - the default is an 8 bit timer*
    Many thanks Anobium, that makes sense and I will look at timer.h. Again thanks for your input.

     

    Last edit: Paul Haug 2017-07-19
  • Anobium

    Anobium - 2017-07-19

    P

     
  • William Roth

    William Roth - 2017-07-23

    Define TMR0_16Bit does several things.

    One is .... to tell the timer library to set up the alias variable "Timer0" as a Word. This variable is used to "READ" the timer but NEVER to write a value to the timer.. Why not write? Because the Assembler writes word vaiables low byte first, then high byte. 16bit timers must always be written high byte first, so that's why we have a settimer command.... to wiite the bytes in the correct order. It you attempt to write using the "timer0" word... only the low byte will be written. This is how the silicon works. The actual "write" does not take place until the low byte is written.

    If you are going to bypass the library and do it the hard way... then to write the TMR0 registers they MUST be written like this ( example to write a value of 1275) :
    .
    TMR0H = 4
    TMR0L = 251

    Much easier to use settimer 0, 1275,

     

    Last edit: William Roth 2017-07-23
  • Paul Haug

    Paul Haug - 2017-07-24

    Thanks William for tha additional info, it all helps.
    Another page to put in my GCB notebook.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.