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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
#defineT0CON=0XA8;Config timer0 as input ctr
#defineT0CKIin;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 ctrdirporta.4in;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,
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
'Boardtestforbdv0.50;UsingPIC18F26K20;Simpletestforboardcheckout;IncludesTerminaltest;andtimer0aswordcounter;PHaug7/18/2017'#include"lcd_driver.h"#OptionExplicit#chip18F26K20,8#configmclr=on;resetPBenabled#configosc=int;useinternalclocksetCKTXP=ON;SetUARToutputtoinvertsetDTRXP=ON;setUARTrecvtoinverted#defineUSART_BAUD_RATE9600;thisreallyis19200baudatcurrent8clockrateof8#defineUSART_BLOCKING#defineUSART_TX_BLOCKING#defineRS232OutPORTC.6;#defineRS232InPORTC.7#defineUSART_BAUD_RATE9600DirRS232OutOut;DirRS232InInDirporta.0in#defineTMR0_16bit'setuptimer0asa16bittimerT0CON=0XA8;Configtimer0asinputctrdirporta.4in'#defineT0CKIin;ConfigureT0CKI(pin6)asinputfordata#definepbporta.0;pushbuttoninputdirpbinDimdelayaswordDimxpcounterasword;#defineoutputportb.0DIRPORTBoutxpcounter=0;resetcountvaluefortestDocleartimer0'timer0=0;resettimer0;-------Forsimpletestonly------------------;++++++++++++++++++++++++Fordebugtestonly;++++++++++++++++++++++++;SlowsdownprgmHserPrint"Counter Value ==> "Hserprinttimer0;Thiscontainstimer0ascountervalueHserPrintCRLF;newline;HSerPrint"Paul's Term Test "wait10ms;Screenhserprint" "hserprintxpcounterxpcounter=xpcounter+257;Justbignumbertocheckoutputof'word'valueshserprint" ";+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++wait200ms;slowtomakecrtreadableloop
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
>* 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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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.Why not use
inittimer0 (ext, {somevlue})
or correct your code? to beand, you are aware the
lcd_driver.h
is not required. We have a very extensive LCD driver - see all the demos,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.
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.
As shown above, where Timer 0 supports 16bit you must use the following syntax:
An example is shown below using the Great Cow BASIC constants. See the tables below for the constants.
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.
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
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
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.
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
Excellent. Good to hear.
Last edit: Anobium 2017-07-18
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
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.
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 selectMark all
. You will see all the work that is controlled by this define.Anobium
>* 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
P
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
Thanks William for tha additional info, it all helps.
Another page to put in my GCB notebook.