More PIC Projects
To order send an email to us and we will reply with the details.

$25.00 plus $6.50 postage

Save this article as:
 .doc   .pdf   .zip  .exe


It's 1970 and a 12 digit LED Display for pocket calculators has just been released.
Nation Semiconductors are in the forefront of designing miniature displays for calculators and have a range from 2-digit to 16-digit displays.
The actual 7-segment displays are so small it takes a bubble magnifier in front of the LEDs to see the digits. We have used one of these in this project.

Fast forward to 2011. These displays are now obsolete and we can find them in surplus stores for a few dollars.
In this project we use one to produce a LED display. It has two features. The characters can be static or "running" and the display can be seen at night.

The circuit consists of a number of "Building Blocks."
The main blocks are the LED display, the micro, the 4017 IC and the 5-buttons.

The Display is a 12 digit calculator display, very similar to that shown in the photo:

A 12-Digit Display. This one is from HP. Ours is from
NS and has different pin-outs.

12-Digit Running Sign built on Surface-Mount Experimenter PC board
(once you start with surface-mount you never go back to through-hole components)
The [   ] button is for future ideas such as "Count To 10 million."

The camera takes a picture of the segments during the scan process
and the characters are not complete!
The board is designed to take a surface-mount PIC micro or
an 18-pin chip in a socket. 

The display is scanned (multiplexed) but not in the normal way.
Normally the segments are accessed and the common cathode for the first display is turned on to produce a run-of-12 and each display would get 8% of the total time.
In other words the digits are illuminated from left-to-right and this is done quickly so that they all appear to be lit at the same time. 
But we can improve on this by a factor of 50% by connecting all segment A's together, all B segments together etc and take all the cathodes to 0v rail via separate lines. In this way we can access the segments via a run-of-eight and provide 12% illumination for each segment. This will result in a brighter display.
This is how the display is configured internally and how the display is intended to be accessed.
In this method of driving the display, only one segment of each digit is turned on at any time and this means the "common" only requires about 25mA "sinking capability." This requirement can be handled via the micro, while the emitter-follower from the 4017 drives all 12 segments (such as segment "A") at the same time.
We supply 25mA (actually sink 25mA) via the micro but when this is divided by a run-of-eight, the average current is only 3mA to each segment. However this is sufficient to produce a bright display.
The 4017 must be synchronised with the data being delivered to the display from the micro, otherwise the wrong segments will be illuminated and the correct image will not appear. 
Synchronisation is done by monitoring "output 8" - the 9th output of the 4017 IC and when it is high, we can clock the 4017 to the first output, ready for the start of the scanning routine.
The 4017 is a "shifting chip" in which one output of the 10 is HIGH at a time. We use this to access the 8 segments and the 9th output is taken to the micro to produce co-ordination between the two chips.
The 5 keys on a single input/output line is polled for activity by calling the Sw sub-routine and if a button is pressed, the program goes to the sub-routine associated with the button.
To find which key has been pressed, a 100n capacitor is charged via output RA6 of the micro. The line is then turned into an input and polled to see if the capacitor discharges. If one of the buttons is pressed it will get discharged before a 20mS time-interval and the routine knows a button is pressed.
The capacitor is now charged again and the line is turned into an input and the time taken for the capacitor to discharge, via the button being pressed, is detected.
The resistor values have been chosen to produce different timings and the sub-routine detects the correct button.
The micro has two 8-bit ports. 4 lines from port A and 8 lines from port B have been used to take the common cathodes of each digit to 0v.
The micro will allow 25mA to flow though the common cathode of each digit and this is sufficient to produce a bright display via the multiplexing routine we have used.
All the rest of the features of this project are in the program.
The numbers and letters for the display are contained in a table and only a few of the letters are missing as they cannot be reproduced.
This program consists of sub-routines and these are placed in alphabetical order so they can be easily located when working on the program.
All the code was created and tested by creating one sub-routine at a time and if a problem develops, you can add a halt instruction to the program (goto $) and see how a particular part of the code operates.
The micro starts at location 000 and carries out the Start-Up routine.
It then goes to Main where it finds a number of instructions to call sub-routines. One of the sub-routines is the switch or button routine where it checks to see if a button has been pressed.
The most difficult code to generate was the timing for the 5 buttons.
We had to work out the timing (delay value) and resistor value for each button. We created a sub-routine where button 1 turned on segment A, button 2 turned on segment B etc. We then added a 100k pot and a separate button. By turning the pot, a particular segment was illuminated. You will find this sub-routine as "Sw" in the final program. We then found the resistance where one segment turned off and the next segment turned on.  These became the limits for each segment (by measuring the resistance of the pot) and we chose a resistor mid-way between the two values.
A button can be pressed at any time and it is detected by charging a 100n capacitor while the button is pressed and measuring the time for the cap to discharge via a resistor connected to the button.
Each button has a different resistance and a loop of 2mS is executed. When a LOW is detected, a count-value is created and this corresponds to a button.

The following diagram shows how a LED is illuminated:

Starting at the 6v rail, we have a 4017 IC with 10 outputs. Only one output goes HIGH at a time and it
takes the base of an emitter-follower transistor towards the 6v rail. The output is about 0.3v below the 6v rail. and the emitter is 0.7v below the base.
The 7-segment display is equivalent to a red LED and it has a characteristic voltage drop across it of about 1.7v.
This means the top of the 100R resistor has a voltage of 6v - 0.3v - 0.7v - 1.7v = 3.3v.
The PIC chip takes the other end of the 100R to 0v rail and the chip has a slight voltage across it of about 0.3v.
This means the 100R has a voltage of 3v across it and the current will be 3/100 = 33mA. As the battery voltage drops the current will decrease slightly.

The next routine to be called is the SCAN sub-routine.
This is a routine that accesses all the segments but does not actually put anything on the display.
It is exactly the same as the scanning routine in old-style TV's (with Cathode ray tubes).
The screen is illuminated via a scanning routine and you can see this when changing to a channel that is not operating. The screen will be white with black and white spots (called snow). The TV produces this screen (called a RASTER) and the TV channel supplies the picture that appears on the RASTER.
This is exactly what we have done. The SCAN routine (multiplexing routine) is called a RASTER.
We have allocated 12 files (from 50h to 5Bh) and any "bits" (1's) in a file will be represented by an illuminated segment on the display.
The first file (50h) is assigned to the first digit on the display and file 5Bh corresponds to the last digit.
The sub-routine starts by outputting bit0 to the display via the micro and any 1's make the corresponding output line or port A and/or B LOW to turn on the particular LEDs when the first output of the 4017 takes the emitter-follower transistor HIGH.
The sub-routine now looks a bit1 of the 12 files to add to the sequence but rather than having extra instructions to look at each bit in the 12 files, we have created a shift routine whereby each of the 12 files is shifted right and we look at bit 0. This is actually bit1 that has been shifted into bit0 location.
When shifting a file (called rotating), bit0 comes out of the file and into the carry. When we shift the next file, the carry bit enters the new file as bit7. In other words, all the 12 files get destroyed in the process of shifting and that's why we have to "block move" all the files from 50h-5Bh to a new area (60h-6Bh) for the scanning and shifting operation.
After a single scan of the display, the files from 50h have to be moved to 60h for the next scan.
When we are creating a message, we load data into files 40h-4Bh and these are called the GHOST FILES. When the ten files are full, the program shifts them one place to the left until the 28 character-buffer is full. When Sw5 is pressed, the RUN routines is activated and the data from files 40h to 5Bh is then moved to 60h-6Bh in groups of 12 files at a time, for SCANNING. And they become the  SCANNING files.
Once we have the preliminary sub-routines running, we can add the button sub-routines to get all the effects on the screen.
Some of the other sub-routines do simple things such as shift a block of data from one location to another, increment or decrement a value on the display by looking at a table and incrementing a pointer for the table to look up or down the table.
Possibly the cleverest sub-routine is RUN.
It shifts the characters across the screen.
The message to be displayed is contained in files 40h to 5Bh. This is 28 characters. We take a window 12 characters wide - just like cutting out a rectangle in a piece of paper - and place it over files 35h to 40h. Only the last file will have a value.
We now transfer the 12 files to 60h-6Bh and call the scan routine.
Only the last display will illuminate.
We then increment a pointer so the "window" looks at file 36h to 41h and transfers them to be scanned.
Only the last two digits will appear on the screen and the data will be shifted one place to the left.
This is how we get the RUNNING EFFECT.
When the project is turned on, a message is scrolled across the screen "12-Digit RUNNING SIGN by TE."
The micro then blanks the screen and the project is ready to load your message.
The first button increments the numbers and letters of the alphabet on the 12 displays.
The second button decrements the characters.
The third button Stores the character by taking it to the right-hand-side of the display.
As each letter is selected, they are added to the sentence and when 10 characters are displayed, they are shifted to the left one-place as each new character is added until the 28 character buffer is filled.


The RUN button (Sw5) is now pressed and the complete message is scrolled across the screen and repeated.
The diagram above shows how a 12-byte wide "window" looks at files 35h to 40h and transfers them to 60h-6Bh for scanning.
The "window" is then advanced to the right to look at 12 files and this puts two active files into the window.
When these files are transferred and scanned the effect is a running sign.
The following diagram shows the 5 buttons and their function:

The fourth button is available for future features such as games, flashing, blinking, etc. See P2 for a project using this button - a counter that counts seconds up to 10 Million - about 115 days.

The circuit is built on a prototyping PC board designed for surface-mount components.
Once you start with surface-mount you will never go back to through-hole components. Surface-mount makes the project look so much simpler and less cluttered.
The project comes with two sets of 20-pin machine pins that can be soldered to the lands on the PC board and wires connected to the display can be fitted into the ends of the pins.
This allows the display to be removed, if needed.
The surface-mount transistors are mounted on a slight angle so the collector, base and emitter leads all touch one of the lands on the board.
All the collectors are connected together and taken the 5v while the emitters go to the appropriate pins on the display.
The 100R surface-mount resistors are placed upright near the pins on the socket of the micro.
Enamelled wire is used to join all the components and the enamel must be removed with a hot soldering iron before making a connection.
Make sure the 5 switches are placed around the right way as the switch has two pins connected together across the top and two lower pins connected together when the button is mounted correctly. If the button is soldered incorrectly, the circuit will not work.  

If the display flashes, the battery voltage is low. This will occur when the voltage is 4.5v or lower or if the cells are weak during the instant when current is required for the display - such as for a row of "8's".
If the project does not work, the most likely cause will be incorrect wiring to the display.
To check the segments in the display, you can make a "Safety Battery" with 3 or 4 cells and a 220R or 470R resistor in the positive lead. The end of the resistor now becomes the positive lead. The resistor will prevent more than a few milliamps flowing and nothing will be damaged.
Remove the two chips from the project and place the positive lead on pin 3 of the 4017 and the negative lead on pin 17 of the micro. Segment "a" of the first digit will illuminate. Keep the positive on pin 3 and try pins 17, 18, 1, 2, 6 of the micro and you will see segment "a" of each digit illuminate.
Keep doing this until all segments of all digits have been identified.
If the message runs across the screen, but the buttons are not detected, the button detection section is not working. It is a high impedance section and you can see if the timing delay in the program is detecting the buttons by placing a 100k pot and switch in series from pin 15 to 0v. Turn the pot slightly from zero ohms and push the button. Keep turning then pushing the button connected to the pot to see what resistance-value is detected by the program.
Only the first and third buttons are detected at the beginning as the second button (decrement) does not have any effect until the increment button puts a value on the display.
The RUN button does not operate at start-up as there are no characters to shift across the display.
After the start-up message has appeared, pin 3 of the micro will be active, sending a clock pulse to the 4017. If pin 4 is also active, it indicates the 4017 is "clocking" and sending a pulse back to the micro - so the 4017 is working.
Use a LOGIC PROBE shown below to detect these features as it gives an indication of HIGH, LOW and PULSE.
When a switch is pressed, the probe will detect activity on the switch-detection line going to pin 15 of the micro.
This covers all the sections and the only remaining fault can be a non-programmed micro. If you have programmed it yourself, try re-programming. The micro in the kit has been checked for correct operation, before adding them to the kit, so check the wiring and make sure all the components have been connected.
Don't worry if the project does not turn work the first time. You will learn more about electronics in your efforts to find the fault, than simply having the project work first go.
When projects are supplied on a printed circuit board, they always work first time. 
This project is a bigger challenge. It requires to you connect the components and think about what you are doing.
Get someone else to check your construction as it is very difficult to fault-find your own work.
If you have followed all our notes above, all the section will have been covered and the only thing to do is contact Colin Mitchell via email and describe the fault.
As a last resort, you can send your project to him for checking.


12 Digit Running Sign
$25.00 plus $6.50 postage
or the pre-programmed chip as a
separate item is $10.00 plus $5.00 post

12  -  100R     1/4 watt or surface mount
1  -  220R          "
2  -  22k          "
1  -  47k          "
1  -  82k          "
1  -  120k         "
1  -  150k         "

2  -  100n ceramics (monoblock)
1  -  100u 25vw electrolytic

1  -  1N4148 signal diode
8  -  BC 547 transistors or BC848 surface-                       mount transistors
1  -  CD4017 IC
1  -  PIC16F628A micro with 12DigDisp.hex

1 -  12 Digit Display
5  -  tactile switches
1  -  16 pin IC socket
1  -  18 pin IC socket
2 -  20 machine-pin header strips for display
1  -  4-cell AA battery holder
1  -  on/off slide switch
4  -  AA cells
1m - fine tinned copper wire
2m - fine enamelled wire
1m  -  very fine solder
1  -  Surface-mount
                       Experimenter  PC board

Buy a kit

The only piece of test-gear needed to test this project is a logic probe - to check the clocking of the 4017.
The circuit can be found in our 200 Transistor Circuits eBook:


We used the Logic Probe to locate one of the faults in our prototype. The pulse on the clock-line of the 4017 was going LOW but not going HIGH. The 4017 was not clocking.
Then we realised RA4 had to be pulled HIGH via a 22k as the output was only "active-low." The Logic Probe was very handy at finding this.
The probe is not designed for high-speed circuits or for very short pulse-widths but can be used for the 12-Digit Running Sign as the pulses are fairly long.

The 12 Digit LED DISPLAY
circuit looks simple because the micro does all the work.
And the micro does all the work due to a program it contains.
Writing a microcontroller program is one of the most interesting challenges.
It can be written in many different ways.
Just like a book or novel, the sentence-structure can be impressive or simple.
You can add instructions in a way that is easy to understand or add them in a way that requires a considerable amount of reasoning to see how they perform.
This is because some instructions are easy to understand and others are complex and the layout can be "linear" or "jumping all over the place."
An example of a simple instruction is: incf  count,f
This increments the count file and places the result in the file.
An example of a complex instruction is:   xorwf   count,w
This exclusively OR's the contents of w with the count file and places the result in w.
This is called a Boolean instruction or LOGIC instruction and each corresponding bit is OR'ed and if only ONE of the bits is "1" the result is "1."
The answer may be different with each pass of the routine and this makes it complex or difficult to determine, when you are looking through the lines of code. You need to work out the result so you can determine where the micro will "jump to" in the program.
Sometimes a program can be shortened by one or two instructions by using an instruction that performs a number of operations and has a number of results.
However you need to know all these outcomes to be able to follow the code and this makes it complex.
Fortunately, we have used only simple-to-understand instructions so you can read the lines of code "like a book."
The program runs a routine called MAIN and calls a number of sub-routines. A sub-routine is any routine that is called more than once and is presented separately so it only needs to be written once.
We have only used the 35 instructions supplied with the chip and not used any special or "underground" instructions known only to advanced programmers and assemblers.
As with everything you are trying to learn, if there is one thing that is not explained in full detail, you get lost.
The 35 instructions we are using are called MACHINE CODE or MACHINE LANGUAGE as they can be read directly by the micro. The line of code (called the instruction) is converted directly into a value that is loaded into the chip. Rather than writing 100100110010, or a similar hex value: AD068, we use a short sentence as explained above.
For example: decfsz  count,f  tells the micro to decrement the count file and leave the result in the file. If the result is zero, the next instruction is jumped-over.
As you read each instruction, you can see exactly what the micro is doing and if something does not work, you can go over the instructions and locate the fault.
You will hear a lot of discussion about the best type of programming language to use, such as "BASIC," "JAL" or "C" in place of Machine Language.
The choice is yours. All I can say is this:
You have decided to learn how to program a PIC microcontroller. All languages other than PIC MACHINE CODE keep you one step away from understanding how the chip operates and you are not learning anything about the codes it reads.
This also includes the product called PIC-AXE. You are using a programming language that can be ported to almost any microcontroller and the code you are producing has nothing to do with a PIC micro. The fact that a PIC micro has been used is mere co-incidence. Almost any micro could be chosen.  In addition, this concept utilizes the micro to only a fraction of its capability and costs 4 times more than using a PIC chip. 
Secondly, when a program does not work, you do not know if your coding is incorrect or the instructions produced by the higher-level language are at fault. You don't know what the high-level language has prepared and it's very difficult to trouble-shoot. 
And thirdly, you need to learn how to write in BASIC or "C," and get all the syntax correct, whereas the 35 instructions that come with the PIC are available as a table and only takes a few days to learn.
The PIC chip we are using has space for 1024 lines of code and when you consider the first 3-level chess game fitted into 1,000 lines of code (for a Z-80), you can see how much can be achieved.
1,000 lines of code occupies more than 20 printed pages and this is about the limit to "hand coding." But up to this level, Machine Code is the quickest way to learn.
In our case, coding is done with mnemonics. This makes it easier for the programmer to write each line of code and a program called an ASSEMBLER converts the code into "0's" and "1's" for the chip. 
To make it easy to read a program, it is laid out so that MAIN is at the end of the program and each sub-routine is placed in alphabetical order. Tables are placed at the beginning, then delays.
We also advise to use only the minimum number of sub-routines so it is easy to follow the flow of the program. Rather than create lots of short sub-routines, it is best to produce those that are more than say 10 lines. Short sub-routines can be added to MAIN.
But the biggest assistance to learning to program is our method of "copy and paste."
We have provided a library of terms and sub-routines as well as lots of programs and any part of these can be copied and placed into your program. All this can be found on Talking Electronics website along with lessons on programming.
See "Start Here with PIC16F628" in the left index of the website and you will find the details on programming chips, including a programmer, a connector that fits between programmer and project, prototyping boards and a number of projects with fully explained programs.
We have everything to get you into PIC programming and the easiest way to start is to look at the program in this project.
Contrary to popular belief, you don't "start at the beginning" with our method of education.  You start "at the end" by removing a few lines of code and see what happens. Then you change a few values and see what happens. Then you add a few lines and see what happens.
There are also a number of forums on the web that deal exclusively with PIC micros and these are active 24 hours a day as enthusiasts from around the world are are constantly on-line to help. Try this forum: http://www.electro-tech-online.com/

After all this discussion, some readers will ask: "Why learn to program?"
The answer is simple.
Go to a toy store and see what is on the shelves.
They have talking robots, games with LCD screens, sounds and effects at the push of a button. Gone are the days of a flashing LED and an amplified telephone. The toys of today include speech, InfraRed detection, colour screens and everything to impress a child.
Most of the toys are microcontroller based and when you consider there are millions of toys and each one is produced in the millions; the market is enormous.
But maybe you don't want to get into the toy market.
There are lots of other fields: medical, automotive, mobile phone, security and more.
Not only is a microcontroller cheaper than individual components but it produces a product that is protected from copying by the fact that the program can be "locked from prying eyes."
Even though the project we have described in this article is very simple, it provides the gateway to the future and once you have the capability of writing a program, you can advance fairly quickly to more complex things.
But it is the starting point that we are famous for. Talking Electronics starts enthusiasts in electronics.
We have always said that building a project is worth a 100 pages of reading material and tens of thousands of hobbyists have already built one or more Talking Electronics kits.
Now is the era of the micro and this project is the starting point. Need I say more.

There are a number of different manufacturers of microcontrollers on the market and the obvious question is to ask is: "Why pick a PIC microcontroller?"
The author had a requirement to chose a micro for a project to be placed inside a greeting card. Ten different designs were developed, including a breath analyser, a game, flashing lights and similar novel ideas.
The production-run was to be 100,000 units of each and to make the project viable, it was intended to design the circuit using the cheapest micro.
After considerable investigation, the only reply from manufacturers and wholesalers was from  Microchip. The simplest micros were being phased out by the other manufacturers and this left only the PIC range.
In fact PIC has a chip designed for the Chinese market and is only available in China. That's the power of the Chinese.
If you intend producing a large run of a project, a die can be made and the chip will be produced as a COB (Chip On Board), but the set-up costs makes this only viable for very large runs. In addition, you must be sure the program is "bug-free" as a chip in the form of a die cannot be altered.
However the advantage of going from a program written for a PIC chip to the same device in the form of a die means the program cannot be directly copied across and no further programming costs are involved.
This project has been built on a PROTOTYPE PC board.
There are three reasons for this.
Talking Electronics has designed a number of projects and they are all built on the same prototype board.
This allows you to buy a number of these boards and build any of the projects as they appear on the web or in a magazine.
The board has been designed especially for surface-mount components and allows circuits to be built and tested using these tiny items.
As you will very quickly find out, designing a circuit for surface-mount is completely different to through-hole components. Most of the time you need to produce a board before anything can be constructed.
However the cost of a producing a board is quite expensive.
Our method reduces the cost to less than 10%.
Once you start designing with surface-mount you will never go back to through-hole as the project is smaller, more-compact and appears to be simpler.
Whenever you put a lot of effort into a project, your eventual goal should be towards commercialisation and the only way to make anything economical is with surface-mount.
With this in mind we have developed a universal surface-mount prototyping board.
The parts are connected with short wires and by careful layout, you will be preparing for the eventual trackwork of the board.
Most of the prototyping boards on the market are quire useless. They don't allow a circuit to be laid out as it will appear in a final design.
With our prototype board, you can build the circuit exactly as you want it to eventually appear and this reduces the change of a mistake.
The last thing you want is a fault.
A mistake in the layout or the program will be very difficult to locate as it is very difficult to fault-find your own work.
By doing everything in small steps, the chance of a mistake creeping in is minimised.

The actual process of programming a chip - we call BURNING. This comes from the original act of "burring an EPROM"  and we still use the wording to differentiate from the art of creating a program for a chip  - called programming.
PIC chips are "programmed" or Burnt on a programmer and there are a number of different types on the market.
If you have a laptop you can build the PIC-2 USB Burner from Talking Electronics.
It is cheap and comes with CD's containing programs to support the hardware and lots of very useful data.
The PIC-2 USB Burner also has the advantage of automatically identifying the chip before burning and detecting if it can be programmed successfully "in circuit."
This programmer is connected to the USB port of your laptop, making it convenient to write your program on a laptop and then burn a chip.
I originally needed three different areas in the work room.
One area for designing, building and soldering, one for writing a program on a desktop computer (and burning the chip) and another for erasing the EPROMS via an ultraviolet light-box for windowed chips.
You can now do everything in a compact area on a desk.
You only need a PIC-2 USB Burner,  a connector to go between the PIC-2 USB Burner and the project you are working on, and a prototyping board containing the project.

You need to look at the enormous amount of material on Talking Electronics website to see what can be done with a microcontroller.
A 180MB mini CD is available, filled with programming material and this would have to be equal to a stack of books one metre high.
There are so many advantages to designing with a micro.
Apart from the professional result; it can be cheaper, quicker and simpler.
And one of the features is the "good-size" memory.
As your code gets longer, you can call sub-routines already produced and this makes your program more and more powerful as you get towards the end of memory.
Of course we are not talking about Gigabytes of memory and a main-frame computer-system.
We are talking about a project that can be really quite impressive and could only be "dreamed-about" some 20 years ago.
One example that comes to light is a telephone dialler produced some 20 years ago. It used cards that fitted into a slot and dialed a phone number.
The box contained 16 simple logic chips and the unit cost more than $150.00.
This was equivalent to a weeks wages.
We can now produce exactly the same product for less than $20.00 using a PIC chip.
However it is not needed as every phone has redial and 10 number storage.
That's why we have to be on the look-out for new ideas. And these are lots of them.
One idea introduces another and it's simply a matter of considering things you will need and including elderly and sick friends and family into your ideas.
All sorts of monitoring devices are needed as well as mechanical aids and equipment.
Nearly all inventions are the result of a personal need and that's why new things are being invented all the time.

Here are the files:


;* 12 Digit RUNNING SIGN    Started 23/8/2010		     	*

	;list P = 16F628	;microcontroller 
	include 	;registers for F628

	errorlevel -302  ;remove message about using proper bank

	__Config 	_cp_off & _lvp_off & _pwrte_on & 
        _wdt_off & _intRC_osc_noclkout & _mclre_off
;code protection - off
;low-voltage programming - off
;power-up timer -  on
;watchdog timer - off
;use internal RC for 4MHz - all pins for in-out

; variables - names and files

		;Files for F628 start at 20h 
temp1		equ 20h	
temp2		equ 21h	
store		equ 22h	;for storing data for first 10 digits in Sw3
timera		equ 23h	;
timerb		equ 24h	;
Sw_Flag		equ 25h	;
count		equ 26h	;loops of discharge time for 100n
flags		equ 27h	;
Jump_1		equ 28h	;jump counter for table1
Run		equ 29h	;used in RUN (Sw5) routine		
temp_sw		equ 2Ah
ScanLoops	equ 2Bh
RunLoops	equ 70h 
Save		equ 71h	
Ghost		equ 72h
GhostTemp	equ 73h
Window   	equ 74h
WindowTemp	equ 75h
_12loops	equ 76h

status	equ	0x03
cmcon	equ	0x1F
rp1	equ	0x06
rp0	equ	0x05

;Beginning of program
reset	org	00		;reset vector address	
SetUp	bsf	status,rp0	
	movlw	b'00000000'	;A in/out
	movwf	05h			
	movlw	b'00000000'	;B output
	movwf	06h		
	movlw	b'10000000'	;Turn off T0CKI, prescale for TMR0 = 1
	movwf	option_reg		
	bcf	status,rp0	;select programming area - bank0 
	movlw	07h		;turn comparators off and enable
	movwf	cmcon		;    pins for I/O functions	
	call	Clear
	call	Attract 
	call	Clear
	goto 	Main	
;* Tables		  *
	addwf 	02h,1	;add W to program counter
	retlw 	06h 	;1 
	retlw 	5Bh 	;2
	retlw 	4Fh 	;3
	retlw 	66h 	;4
	retlw 	6Dh 	;5
	retlw 	7Dh 	;6
	retlw 	07h 	;7
	retlw 	7Fh	;8
	retlw 	6Fh 	;9
	retlw 	3Fh  	;0	
	retlw 	77h	;A 
	retlw 	7Ch	;b  
	retlw 	39h	;C
	retlw 	5Eh	;d
	retlw 	79h	;E
	retlw 	71h	;F
	retlw 	6Fh	;g
	retlw 	76h	;H
	retlw 	06h	;I
	retlw 	1Eh	;J
	retlw 	38h	;L
	retlw 	37h	;N
	retlw 	3Fh	;O
	retlw 	73h	;P
	retlw 	67h	;q
	retlw 	50h	;r	
	retlw 	6Dh 	;S
	retlw 	78h	;t
	retlw 	3Eh	;U
	retlw 	6Eh	;y	
	retlw	80h	;dot
	retlw	40	;-
	retlw	08h	;_space
	retlw	1	;line on top
	retlw	48h	;equals  . . . . . .24h chars
	retlw	0ffh	;end of table	
;* Delay sub-routines  		        *

		;Delay  10uS
_10uS	nop		
	retlw	00	
_500uS	decfsz 	temp1,f
	goto 	$-1
	retlw 	00
_1mS	nop
	decfsz 	temp1,f
	goto 	_1mS
	retlw 	00
_4mS	movlw	04h
	movwf	temp2
_b	nop
	decfsz 	temp1,f
	goto 	_b
	decfsz 	temp2,f
	goto 	_b	
	retlw 	00			

_10mS	movlw	0Ah
	movwf	temp2
_c	nop
	decfsz 	temp1,f
	goto 	_c
	decfsz 	temp2,f
	goto 	_c	
	retlw 	00		

Delay1	movlw	1
	movwf	timerb
Del_a	decfsz 	timera,1
	goto 	Del_a
	decfsz 	timerb,1
	goto 	Del_a	
	retlw 	00
Delay2	Decfsz 	timera,1
	goto 	Delay2
	Decfsz 	timerb,1
	goto 	Delay2
	retlw 	00	
;* sub-routines  		

		;Attract calls Sw5 RUN sub-routine (Sw_Flag is empty)
Attract	movlw	06h ;1
	movwf	40h
	movlw	5Bh ;2
	movwf	41h
	movlw	40  ;-
	movwf	42h	
	movlw	5Eh ;d
	movwf	43h
	movlw	06h ;I
	movwf	44h
	movlw	6Fh ;g
	movwf	45h
	movlw	06h ;I
	movwf	46h
	movlw	78h ;t
	movwf	47h
	movlw	08h ;_
	movwf	48h
	movlw	50h ;r
	movwf	49h
	movlw	3Eh ;U
	movwf	4Ah
	movlw	37h ;N
	movwf	4Bh
	movlw	37h ;N
	movwf	4Ch
	movlw	06h ;I
	movwf	4Dh
	movlw	37h ;N
	movwf	4Eh
	movlw	6Fh ;g
	movwf	4Fh
	movlw	08h ;_
	movwf	50h
	movlw	6Dh ;S
	movwf	51h
	movlw	06h ;I
	movwf	52h
	movlw	6Fh ;g
	movwf	53h
	movlw	37h ;N
	movwf	54h
	movlw	08h ;_
	movwf	55h		
	movlw	7Ch ;b 
	movwf	56h
	movlw	6Eh ;y	
	movwf	57h
	movlw	08h ;_
	movwf	58h	
	movlw	78h ;t
	movwf	59h
	movlw	79h ;E
	movwf	5Ah		
	call	Set4017
	call	Transfer
	call	sw5					
	retlw	00
Clear			;all files from 21h to 6Fh are cleared
	movlw	4Fh	;number of files to be cleared =loops
	movwf	temp1				
	movlw	21h
	movwf	fsr		
	movlw	0
	movwf	00h
	incf	fsr,1
	decfsz	temp1,1
	goto	$-4			
	retlw	00		
	;Clock the 4017
clock	bsf	05h,4	;clock the 4017 via RA4
	call	_10uS			
	bcf	05h,4					
	call	_10uS	
	retlw	00

		;12 digits are scanned by making first output of 4017 HIGH
		;and making appropriate digits LOW via PIC chip.
		;Data is taken from files 60h - 6Bh. 
		;"1" in bit0 becomes segmentA etc.    "1" in bit7=dot.
		;move the 12 files to the right and use bit0 again. 
		;Repeat 8 times.
Scan	movlw	08	
	movwf	ScanLoops		
	clrf	portA
	decf	portA,1   ;make bits 0 to 3 HIGH to turn off segments
	clrf	portB
	decf	portB,1	  ;make bits 0 to 7 HIGH to turn off segments
	btfsc	60h,0
	bcf	portA,0
	btfsc	61h,0
	bcf	portA,1
	btfsc	62h,0
	bcf	portA,2
	btfsc	63h,0
	bcf	portA,3		
	btfsc	64h,0
	bcf	portB,0
	btfsc	65h,0
	bcf	portB,1
	btfsc	66h,0
	bcf	portB,2
	btfsc	67h,0
	bcf	portB,3
	btfsc	68h,0
	bcf	portB,4
	btfsc	69h,0
	bcf	portB,5
	btfsc	6Ah,0
	bcf	portB,6
	btfsc	6Bh,0
	bcf	portB,7
	call	clock		;to advance 4017 to output "0"	
	call	_500uS
	rrf	60h,1
	rrf	61h,1
	rrf	62h,1
	rrf	63h,1
	rrf	64h,1
	rrf	65h,1
	rrf	66h,1
	rrf	67h,1
	rrf	68h,1
	rrf	69h,1
	rrf	6Ah,1
	rrf	6Bh,1
	decfsz	ScanLoops,1
	goto	Scan+2
	movlw	0ffh
	movwf	PortA	;prevents bright dot
	movwf	PortB	;prevents bright dot
	retlw	00
Set4017	bsf	status,rp0
	movlw 	b'00100000'	;Set TRISA in for RA5   
	movwf	05h					
	bcf	status,rp0
	call	clock
	btfss	05h,5		;see if 4017 is at 9th output 
	goto	$-2
	call	clock		
	retlw	00	;output "10" on 4017 HIGH = before start of scan
			;to prevent anything appearing on screen
	;detect switches & generates bit 1,2,3,4,5 in Sw_Flag file	
Sw	bsf	status,rp0			
	bcf	trisA,6		;Make bit 6 output
	bcf	status,rp0
	bsf	portA,6		;make bit 6 HIGH	
	call	_1mS		;create delay to charge 100n
	bsf	status,rp0			
	bsf	trisA,6		;Make bit 6 input
	bcf	status,rp0		
	call	_10mS
	call	_1mS
	btfss	portA,6		;if set, no sw pushed	
	goto	$+3		;sw pushed
	clrf	Sw_Flag		;no sw pressed			
	retlw	00				;
	btfsc	Sw_Flag,0	;test "first-pass" sw flag
	retlw	00						
	clrf	count
	bsf	status,rp0			
	bcf	trisA,6		;Make bit 3 output
	bcf	status,rp0
	bsf	portA,6		;make bit 3 HIGH	
	call	_1mS		;create delay to charge 100n		
	bsf	status,rp0			
	bsf	trisA,6		;Make bit 3 input
	bcf	status,rp0					
	call	_1mS		;count until cap discharged
	call	_1mS		
	incf	count,f
	btfsc	portA,6		;is input HIGH?		
	goto	$-4		;count exits with 1-5	
	decfsz	count,f			
	goto	$+3
	bsf	Sw_Flag,1	;set a flag-bit for first sw
	retlw	00		
	decfsz	count,f
	goto	$+3
	bsf	Sw_Flag,2	;set a flag-bit for second sw
	retlw	00		
	decfsz	count,f
	goto	$+3
	bsf	Sw_Flag,3	;set a flag-bit for third sw
	retlw	00		
	decfsz	count,f
	goto	$+3
	bsf	Sw_Flag,4	;set a flag-bit for fourth sw
	retlw	00		
	bsf	Sw_Flag,5	;set a flag-bit for fifth sw
	retlw	00			
			;Sw1 increments data on display12 

sw1	btfsc	Sw_Flag,0  ;first pass? If no, return	
	retlw	00
	bsf	Sw_Flag,0  ;set sw flag (clr in Sw routine)
	incf	Jump_1,1  ;incr jump value 		
	movf	Jump_1,0  ;set-up jump value for table 1
	call	table1	  ;get display data		
	movwf	5Bh	  ;display-12 holds the image to be incremented
	xorlw	0FFh	  ;see if end of table 1              
	btfss	03,2		
	retlw	00
	clrf	5Bh
	clrf	Jump_1
	goto	sw1+3	
	;Sw2 decrements data on display12

sw2	btfsc	Sw_Flag,0  ;first pass? If no, return	
	retlw	00
	bsf	Sw_Flag,0  ;set sw flag (clr in Sw routine)
	movf	Jump_1,0
	xorlw	1	  ;see if start of table1 is reached 
	btfss	03,2
	goto	$+4
	movlw	24h	  ;number of values in table1	
	movwf	Jump_1
	goto	sw2	
	decf	Jump_1,1  ;decr jump value 
	movf	Jump_1,0  ;set-up jump value for table 1
	call	table1	  ;get display data
	movwf	5Bh	  ;display-12 holds the image to be incremented
	retlw	00	
	;sw3 store

sw3	btfsc	Sw_Flag,0	;first pass? If no, return	
	retlw	00
	bsf	Sw_Flag,0	;set sw flag (clr in Sw routine)
	movlw	0Ah
	movwf	store	;.10 loops
	movlw	50h	;start of display
	movwf	04h	;load FSR
	movf	00h,0	;move value looked at by FSR into W
	xorlw	00h	;see if display is empty              
	btfsc	03,2
	goto	$+5	;display empty			
	incf	04h,1	;display not empty	
	decfsz	store,1
	goto	$-6
	goto	$+5	;go to section that moves display left 
	movf	Jump_1,0
	call	table1
	movwf	00h
	retlw	00
	movf	40h,0	;look at file 40h 
	xorlw	00h		;see if it is empty              
	btfss	03,2
	retlw	00
	movlw	1Ah
	movwf	store	;1Ah loops
	movlw	40h	;start of block move
	movwf	04h	;load FSR
	movf	00h,0	;move value looked at by FSR into W
	decf	04h,1	;decr fsr to 2Fh
	movwf	00h	;put value into 2Fh
	incf	04h,1
	incf	04h,1
	decfsz	store,1
	goto 	$-6
	movf	5Bh,0	;move character from 12th to 10th display
	movwf	59h	;put value into 10th display
	retlw	00
sw4	btfsc	Sw_Flag,0	;first pass? If no, return	
	retlw	00
	bsf	Sw_Flag,0	;set sw flag (clr in Sw routine)
	;movlw	1Ch		;not yet completed 
	;movwf	12h		;not yet completed 
	retlw	00

			;RUN     Runs characters across display
			;files 60h-6Fh get destroyed after SCAN, so
			;a 12-file wide window looks at 35h to 40h 
			;and transfers to 60h-6Bh for scan routine.
sw5	clrf	3Fh		;remove unwanted shifted data 	
	clrf	5Bh		;remove unwanted data		
	movlw	35h		;start of Ghost files   
	movwf	Ghost			
	movlw	60h		;window 60h-6Bh		
	movwf	Window		
	movlw	20h		;creates shift timing 
	movwf	RunLoops	;loops of scan 		
	movf	Ghost,0
	movwf	GhostTemp	;for incrementing
	movf	Window,0
	movwf	WindowTemp	;for incrementing
	movlw	0Ch			;shift 12 bits of data  
	movwf	_12loops	;12 loops		
	movf	GhostTemp,0	;look at first Ghost file        
	movwf	fsr	
	movf	00h,0		;move value looked at by FSR into W
	movwf	Save		;save it		
	movf	WindowTemp,0	;load first window file
	movwf	fsr		;put into pointer
	movf	Save,0
	movwf	00h		;put value into 60h
	incf	GhostTemp,1
	incf	WindowTemp,1
	decfsz	_12loops,1
	goto	$-.11
	call	Set4017
	call	Scan
	decfsz	RunLoops,1
	goto	Sw5+8
	incf	Ghost,1	
	movf	Ghost,0
	xorlw	54h		;end of Ghost files? + spaces         
	btfss	03,2	
	goto	Sw5+6	
	movf	Sw_Flag,1	
	btfss	03,2		
	goto	Sw5+2		
	retlw	00		;Sw_Flag is empty so return to Attract
	;Transfer the data in files 50h - 5Bh to 60h - 6Bh
	movlw	0Ch
	movwf	temp1	;no of loops
	movlw	50h	;start of 1st block
	movwf	04h	;load FSR
	movf	00h,0	;move value looked at by FSR into W
	bcf	04h,4
	bsf	04h,5	;turns FSR 50h to 60h
	movwf	00h
	bsf	04h,4
	bcf	04h,5	;turns FSR 60h to 50h
	incf	04h,1
	decfsz	temp1,1
	goto	$-8
	retlw	00

;* Main 			   *

Main	call	Set4017
	call	Transfer
	call	Scan
	call	Sw      ;see if a button has been pressed
	movf	Sw_Flag,1
	btfsc	03,2		;see if Sw_Flag is clear
	goto	Main
	btfss	Sw_Flag,1
	goto	$+3			
	call	sw1		;increment data for display12.
	goto	Main
	btfss	Sw_Flag,2
	goto	$+3
	call	sw2		;decrement data for display12.
	goto	Main
	btfss	Sw_Flag,3
	goto	$+3
	call	sw3		;store
	goto	Main		
	btfss	Sw_Flag,4
	goto	$+3
	call	sw4		;to the used for future effects
	goto	Main
	btfsc	Sw_Flag,5				
	goto	sw5		;RUN
	goto	Main

We have especially left "switch 4" non-operational. You can add different features to this project via this button and the best ones will be included in future updates of the project.
That's the beauty of the web. Articles can be updated, improved and add-to at any time and you can download the new program and burn it yourself.

A pre-programmed PIC16F628 chip for this project is available for $10.00 with 12DigDisp
.hex burnt into it. However the whole kits costs only $25.00 and you will find is very difficult to get the 12 Digit Display from any other supplier, so it's best to order the kit.

If you intend to add more features, you will you will need a programmer. Talking Electronics has two programmers in kit-form.
MultiChip programmer connects to the serial port of older-type computers, such as desk-top or towers. It comes with an 18pin programming socket and lead. The kit and lead costs $17.00.
PIC-2 USB Burner connects to the USB port of a laptop. You will also need a small PC board with 18pin socket ($2.50) and a
6 pin to 5 pin adapter to connect between the PIC-2 USB Burner and the 18pin socket ($1.50).  The kit, lead and programming socket costs $30.00
Before modifying or programming a chip, read about programming PIC chips by clicking this link:
Start here with PIC12F629
If you have any other questions, contact Colin Mitchell via email.

On Page 2 we have an idea that can be added to this project. It is a counter that counts the number of seconds up to 10 million.