Searching \ for '[PIC]: Timing Problems' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page:
Search entire site for: 'Timing Problems'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: Timing Problems'
2002\01\24@170917 by Ted Mawson

OK, the story so far.

I bought and built my PICALL programmer (I now have an unused melabs
EPIC programmer with vn 2.11 disk for sale) and it works great!

I have three 16x2 LCD displays that I picked up cheap so I decided to
build something real simple, really to prove the displays work.  I chose
the worktime.asm program from the piclist source library - this is
designed for a 32,768 Hz crystal and uses the 16F84 .  Only having a
4MHz crystal, a changed the timing routines to give me interrupts every
0.065536 seconds or 15.26 Hz.  I've attached the .asm code for those who
are interested enough to look at it.

The PIC programmed first time.  I hooked it up with a 4MHz crystal and
2x25pF caps and.. it works!  sort of.  The display initializes and
displays correctly but it takes 40 seconds for 1 second to clock up on
the display.  I also substituted an 8MHz crystal and it does exactly the
same thing with exactly the same timing??? Duh?

My suspicion is that, because (shock horror) I built the circuit on
breadboard, the crystal isn't running properly.  I do have an 18 pin PIC
proto board but no 18-pin DIP socket yet.  The layout on the breadboard
is really neat but that doesn't mean that it will run at 4MHz, anyone
got any comments on the breadboard thing?

Q1        If the oscillator wasn't oscillating, would I get the results
I do?  Will the internal oscillator run the chip when the external one
isn't working?  Only this would explain why I get exactly the same
results whether I use a 4 or 8 MHz crystal and it might explain why time
is going by so slowly.. unless I've found a way to slow down time ;-)

Q2        Check of understanding - Xtal at 4MHz, system clock is 1MHz,
with prescaler set to 256, TMR0 will get clocked at 3906.25 Hz and the
TMR0 interrupt will be 3906.25 / 256 = 15.26 Hz.  RIGHT?

Thanks in advance.

Ted Mawson

-- hint: The PICList is archived three different
ways.  See for details.

2002\01\24@170932 by Ted Mawson

part 0 47 bytes
his is a multi-part message in MIME format. part 1 2367 bytes content-type:multipart/alternative; boundary="Boundary_(ID_nim/1Igy0RET7tjPB1twwg)" (decoded 7bit)
Content-type: multipart/alternative; boundary="Boundary_(ID_nim/1Igy0RET7tjPB1twwg)" --Boundary_(ID_nim/1Igy0RET7tjPB1twwg) Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7BIT Sorry, I forgot to attach the .asm file. Ted Mawson --Boundary_(ID_nim/1Igy0RET7tjPB1twwg) Content-type: text/html; charset=us-ascii Content-transfer-encoding: 7BIT

Sorry, I forgot to attach the .asm file.


Ted Mawson


part 2 20563 bytes content-type:text/plain; name=tedtmr1.asm
(decoded 7bit)
Content-type: text/plain; name=tedtmr1.asm Content-transfer-encoding: 7BIT Content-disposition: attachment; filename=tedtmr1.asm ;Countdown Timer with Memory ; based off 'worktime.asm' ;Program #8 - LCD display of Timer ;-------------------------------------------------------------------------; ; TedTimer1.ASM Pushbutton toggles clock keeping track of time on LCD ; ;-------------------------------------------------------------------------; ; Note: must add additional time digit to run over 99 hrs. LIST P=16F84 ; 16F84 Runs at 4 MHz INCLUDE "" __CONFIG _CP_OFF & _PWRTE_ON & _HS_OSC & _WDT_OFF ; uses 4 MHz crystal ; Code protection off, power-up timer enabled, high speed oscillator, watch dog timer off ERRORLEVEL -224 ; supress annoying message because of tris ; Define Information #DEFINE RS PORTA, 0 #DEFINE E PORTA, 1 #DEFINE TOGGLESW PORTB, 4 ; Macro EStrobe MACRO ; Strobe the "E" Bit bsf E nop ; )*( add 2 microsecond delay nop ; )*( bcf E ENDM CBLOCK 0x0C sec ; seconds digit sec10 ; 10's of second digit mins ; minutes digit min10 ; 10's of minutes digit hr ; hours digit hr10 ; 10's of hours digit highlim ; high limit + 1 of digit w_temp ; holds W during interrupt status_temp ; holds STATUS during interrupt fsr_temp ; holds FSR during interrupt Dlay ; 8 Bit Delay Variable msCount ; )*( 8 bit counter to get to 1 ms increments dcount ; )*( counter used by the delay n ms routine working ; working flag 0 not working, 1 working ptr ; used in displaying message Temp ; a temporary variable bin ; a temporary variable oset ; offset of time register oldtime ; holds last value of sec ENDC ORG 0 ; start at location 0 goto main ; jump over to main routine ORG 4 goto isr ; jump to interrupt routine ;-------------------------------------------------------------------------; ; High limit + 1 of digits at position W ; ;-------------------------------------------------------------------------; sethi: addwf PCL, f dt H'A',H'6',H'A',H'6',H'A',H'A' ;-------------------------------------------------------------------------; ; Data for message to be output ; ;-------------------------------------------------------------------------; shomsg ; Message to Output addwf PCL, f ; Output the Characters dt "Working Time:", 0 ;-------------------------------------------------------------------------; ; Interrupt routine, increments time by one second (BCD) ; ;-------------------------------------------------------------------------; ; I modified this routine to add msCount which is initially set to 15. Because the pre-scaler is set to ; 256, we get 1,000,000 / 256 / 256 = 15.26 Hz TMR0 interrupts. msCount counts 15 TMR0 interrupts before ; it resets to 15 and enters the original code to increment the time by 1 second. isr: movwf w_temp ; save W swapf STATUS,W ; save status movwf status_temp ; without changing flags swapf FSR,W ; save FSR movwf fsr_temp ; without changing flags movf working, f ; check working flag btfsc STATUS, Z ; )*( if not zero then move to increment time test goto restore ; else get out of interrupt routine ; my extra time code decfsz msCount,F ; )*( decrement msCount goto restore ; )*( if msCount isn't zero, get out ; )*( but if msCount is zero then movlw .15 ; )*( reset mscount to dec 15 movwf msCount ; original routine movlw sec ; point at sec register movwf FSR newdigit: incf INDF, f ; current digit up one movlw sec ; get difference between sec and FSR subwf FSR, W call sethi ; use to get high limit + 1 subwf INDF, W ; reached that number yet? btfss STATUS, Z ; skip over if yes goto restore ; else exit isr clrf INDF ; set current digit to 0 incf FSR, f ; point at next digit goto newdigit ; no, increment the next digit restore: swapf status_temp,W ; get original status back movwf STATUS ; into status register swapf fsr_temp,W ; get original fsr back movwf FSR ; into status register swapf w_temp,f ; old no flags trick again swapf w_temp,W ; to restore W bcf INTCON,T0IF ; clear the TMR0 interrupt flag retfie ; finished reset GIE ;-------------------------------------------------------------------------; ; Initialize the ports ; ;-------------------------------------------------------------------------; init: clrf PORTA clrf PORTB movlw 0 ; Port A all outputs tris PORTA movlw B'00010000' ; RB4 input, others outputs tris PORTB movlw B'00000111' ; pull-ups enabled ; prescaler assigned to TMR0 ; )*( prescaler set to 1:256 ; rolls over 15.26 times each second, my timing assumes 15 - inaccurate at 4MHz option movlw 0 ; zero out all registers movwf hr10 movwf hr movwf min10 movwf mins movwf sec10 movwf sec clrf working ; working flag to zero movlw B'10100000' ; GIE set T0IE set, T0IF cleared movwf INTCON movlw .15 ; )*( initialize msCount to dec 15 movwf msCount return ;-------------------------------------------------------------------------; ; Initialize the LCD ; ;-------------------------------------------------------------------------; initlcd: movlw D'40' call nmsec ; Wait 40 msecs before Reset bcf RS ; send an 8 bit instruction movlw 0x03 ; Reset Command call NybbleOut ; Send the Nybble call Dlay5 ; Wait 5 msecs before Sending Again EStrobe call nmics ; )*( Wait 247 usecs before Sending the Second Time EStrobe call nmics ; )*( Wait 247 usecs before Sending the Third Time bcf RS ; send an 8 bit instruction movlw 0x02 ; Set 4 Bit Mode call NybbleOut call nmics ; )*( Wait 247 usecs movlw 0x028 ; 4 bit, 2 Line, 5x7 font call SendINS movlw 0x010 ; display shift off call SendINS movlw 0x001 ; Clear the Display RAM call SendINS call Dlay5 ; Note, Can take up to 4.1 msecs movlw 0x006 ; increment cursor call SendINS movlw 0x00C ; display on cursor off call SendINS return ;-------------------------------------------------------------------------; ; Send the character in W out to the LCD ; ;-------------------------------------------------------------------------; SendASCII addlw '0' ; Send nbr as ASCII character SendCHAR ; Send the Character to the LCD movwf Temp ; Save the Temporary Value swapf Temp, w ; Send the High Nybble bsf RS ; RS = 1 call NybbleOut movf Temp, w ; Send the Low Nybble bsf RS call NybbleOut return ;-------------------------------------------------------------------------; ; Send an instruction in W out to the LCD ; ;-------------------------------------------------------------------------; SendINS ; Send the Instruction to the LCD movwf Temp ; Save the Temporary Value swapf Temp, w ; Send the High Nybble bcf RS ; RS = 0 call NybbleOut movf Temp, w ; Send the Low Nybble bcf RS call NybbleOut return ;-------------------------------------------------------------------------; ; Send the nibble in W out to the LCD ; ;-------------------------------------------------------------------------; NybbleOut ; Send a Nybble to the LCD movwf PORTB EStrobe ; Strobe out the LCD Data nop nop return ;-------------------------------------------------------------------------; ; Output the message on the LCD ; ;-------------------------------------------------------------------------; OutMessage: movwf FSR ; Point at first letter OutLoop: movf FSR, w ; Get pointer into W incf FSR, f ; Set up for next letter call shomsg ; Get character to output iorlw 0 ; At the End of the Message? btfsc STATUS, Z ; Skip if not at end return ; Yes - Equal to Zero call SendCHAR ; Output the ASCII Character goto OutLoop ; Get the next character ;-------------------------------------------------------------------------; ; Wait until button is released ; ;-------------------------------------------------------------------------; waitup: btfss TOGGLESW ; test toggle switch goto $ -1 ; ck again if pressed movlw 20 ; wait 20 msec for debounce call nmsec btfss TOGGLESW ; check again, still up? goto $ -4 ; no start over return ; yes, finished ;-----------------------------------------------------------------------; ; Delay routine ; ;-----------------------------------------------------------------------; ; I rewrote this delay routine to provide a delay in mSec equal to the number in w on entry ; for a 4MHz xtal, each instruction takes 0.001 mSecs ; added nmics to do a 250 micro-second delay nmics: movlw .1 ; put 1 in dcount movwf dcount ; so that it will zero at first decrement and get us out movlw .60 ; prepare for 60 x 4usec loops goto mslp1 ; and enter the 4 microsecond delay loop routine ; 4x60=240 +7 extra pre+post insts=247 microSecs Dlay5: movlw .5 ; delay for 5 milliseconds nmsec: ; delay for # msec in W on entry movwf dcount ; )*( save the ms delay number mslp2: movlw .250 ; )*( put dec 250 into w mslp1: nop addlw 0xFF ; )*( w=w-1 btfss STATUS, Z ; )*( skip next if result is zero goto mslp1 ; )*( do it again until w=zero decfsz dcount, F ; )*( ok, we've counted w down to zero so dcount-1 goto mslp2 ; )*( if dcount not zero, do it again for the next mSec return ; )*( we're done, return to calling point ;-------------------------------------------------------------------------; ; Display the Time ; ;-------------------------------------------------------------------------; DispTime: MOVLW H'C0' CALL SendINS MOVF hr10, W CALL SendASCII MOVF hr, W CALL SendASCII MOVLW ":" CALL SendCHAR MOVF min10, W CALL SendASCII MOVF mins, W CALL SendASCII MOVLW ":" CALL SendCHAR MOVF sec10, W CALL SendASCII MOVF sec, W CALL SendASCII RETURN ;-------------------------------------------------------------------------; ; Toggle Work Flag ; ;-------------------------------------------------------------------------; togglewk: movf working, f ; set zero flag if zero btfss STATUS, Z ; skip if working is zero goto turnoff incf working, f ; set working to 1 call waitup ; wait for button release return turnoff: clrf working ; working set to zero call waitup ; wait for button to be released return ;-------------------------------------------------------------------------; ; The Main routine ; ;-------------------------------------------------------------------------; main: call init ; initialize ports, set up timer call initlcd ; initialize the LCD movlw 0 ; display 'Working Time:' call OutMessage ckbutton: ; check for a press of the TOGGLE button btfss TOGGLESW ; skip if not pressed call togglewk ; else change the mode of timer movf oldtime, W ; is oldtime the same as sec? subwf sec, W btfsc STATUS, Z ; if not, skip over next instruction goto ckbutton ; else continue checking call DispTime ; sec has changed, display the time movf sec, W ; make sec and oldsec the same movwf oldtime goto ckbutton ; and continue checking end Worktime Program This program is a timer with pushbutton to start and stop accumulating time. The output is displayed on a Liquid Crystal Display, (LCD). An interrupt service routine, (isr), runs in the background. Every second it checks a flag called 'working'. The register 'sec' is incremented if the flag is set. An overflow of sec increments sec10 and so forth through tens of hours. The display will flicker if the main loop displays the time continuously. Instead, the current seconds values is checked against the last displayed seconds value in 'oldtime'. Only if they are different is the display and oldtime updated. Notice that there are two entry point to the subroutine that displays characters. At the entry point 'SendASCII', the value of the character '0' is added to W changing a binary number to an ASCII character. Sending instructions differs from sending characters. The RS line is high when sending characters, low for instructions. Tables are used twice in this program. One table holds overflow values for each time register. The second holds the characters of a message to be displayed on the LCD. In both cases, the value of W on entry determines the value returned in W. This is the first program to use a macro. The two instructions of the macro 'EStrobe' are inserted at each location in the program where the name of the macro, (EStrobe), appears. The puropose of the macro is to make the program easier to read. LCD as an Output Device Surplus LCD units that use the Hitachi 44870 controller can be purchased from B.G. Micro, (, for as little as $3. Another supplier is Marlin P. Jones, ( This program requires at least a two line by 16 character unit. Hooking it up, contrast voltage The first thing to do when you get your LCD is to confirm that it works. Apply +5 volts to pin 2 and ground pin 1. Also ground pin 3 which is the contrast voltage. You should see a line of squares where the characters appear. You may have to look at a low angle to see these. If you see nothing, the contrast voltage may not be right. Put a 10K, (or so), pot between +5 and ground and run the wiper to pin 3. Adjust the pot and see if you can make the squares appear and disappear. Some units require a negative contrast voltage. Initialization We must go through a complex procedure just to initialize the display. We also put it into 4 bit mode so only six control 6 wires are needed instead of ten. If you want to read more about the 44780, here are some URL's: Myke Predko at Christopher Burian at Ian Harris at Peer Ouwehand at Scott M. Bruck has a physics description of the LCD at Your Turn The purpose of this program was to demonstrate a simple application that uses a LCD display. It does contain many elements you would use in any program with a LCD display unit. Among these are: initialization of a 44780 based LCD and putting it in 4 bit mode sending characters and instructions to the LCD outputting an ASCII string to the LCD outputting numbers to the LCD by displaying individual ASCII characters Try to use subroutines from this program to change some of the previous programs to use a LCD display as an output device. file: /techref/piclist/cheapic/worktime.htm, updated: 7/19/00 2:41:04 PM, More.., Top, Search News These pages are served without commercial sponsorship. (No Advertisements). Bandwidth abuse will increase hosting cost and force sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Did you find what you needed? "Not quite. Look for more pages like this one." "No. I'm looking for: " "No. I need to do an advanced boolean search" "No. Take me to the top so I can drill down by catagory" "No. Please refer me to an expert in this area" "No. But I'm interested. me at when this page is expanded." After you find an appropriate page, you are invited to your question comment link program listing to this massmind site! (posts will be reviewed) Just type in the box and press the Post button. (HTML welcomed!): Members can LOGIN to post directly, become page editors, and be credited for their posts. Link? Put it here: if you want a response, please enter your email address: Check out Doug Woods' EXCELLENT PIC Microcontroller Instruction Set Quick Reference and Core Comparison Matrix Feel the NEED for SPEED? Ubicom SX18 thru SX52, PIC 16c5X compatibile, 50 to 100 MIPS microcontrollers! Now US customers can buy the Excellent SXDev from for $150 + $15 import fee + s&h (~ $180 total+tax in CA)
part 3 141 bytes
- -- hint: The PICList is archived three different ways. See for details.

2002\01\24@191936 by kben

picon face
Hi Ted,
The 4mhz version of worktime.asm is wktim4m.asm and is on
half way down the page. The page has all the Beginner projects
in 4mhz versions.

>I have three 16x2 LCD displays that I picked up cheap so I decided to
>build something real simple, really to prove the displays work.  I chose
>the worktime.asm program from the piclist source library - this is
>designed for a 32,768 Hz crystal and uses the 16F84 .  Only having a
>4MHz crystal, a changed the timing routines to give me interrupts every
>0.065536 seconds or 15.26 Hz.  I've attached the .asm code for those who
>are interested enough to look at it.

-- hint: The PICList is archived three different
ways.  See for details.

2002\01\24@191955 by Ted Mawson

One other thought - is there a difference between the 16F84 and the
16F84a that would cause me the problems I have experienced?

I noticed that I have 16F84 set up in the .asm file and the chip I
programmed is a 16F84a.

Ted Mawson

-- hint: The PICList is archived three different
ways.  See for details.

More... (looser matching)
- Last day of these posts
- In 2002 , 2003 only
- Today
- New search...