See more projects using micros:
Elektor,EPE,Silicon Chip
2 Digit Up/Down Counter with PIC12F628 and prototype PC board $25.00 plus $5.00 postage.
To order the kit, [send an email](mailto:colin@elechelp.com?Subject=Buying components for the 2 Digit Up/Down counter&Body=Please e-mail the cost of components for the 2 Digit Up/Down counter on prototype PC board for $25.00 plus postage by air mail to my country:****___**** and send details of how I can pay for it. My name is:____**)** to us and we will reply with the details of how to order etc.
To take our programming skills further, we can use a PIC12F629 chip to produce a 2-Digit Up/Down Counter.
It might seem impossible to convert a project using an 18 pin chip to an 8-pin micro, but by using multiplexing skills and placing 2 buttons on the input-ONLY line of the chip, we can achieve this.
Most of the program sets up the drive-lines to access the segments. The actual part of the program that produces the “effect” is contained in the Main routine.
The PC board has two 7-segment displays made up of individual LEDs. Each segment consists of 2 LEDs in series. These are placed on an output line so that when the line is HIGH, one segment is illuminated, and when it is LOW, another segment is illuminated.
This allows the micro to illuminate 6 segments with 3 drive-lines.
The circuit is then made more complex by including a set of 4 transistors to select the left-hand or right-hand display.
This requires 2 more drive-lines.
The last line is an input-ONLY line and is used for the buttons.
Segment “g” is driven directly from the transistors in a similar way to an “H-bridge” where two diagonally opposite transistors turns on to produce a drive for the left-hand “g” segment and the other two diagonally opposite transistors turn on for the other “g” segment.
This project is merely a “conceptual” design to prove that noting is impossible in electronics.
PIC chips are less than 50 cents in large qualities and all the other components are less than 1 cent each.
This makes the project viable as the display is 50% larger and cheaper than using 7-segment displays.
The whole aim of the project is to learn programming and interfacing the micro to the outside world.
PIC12F629 2-Digit Counter
There are a few interesting features in this circuit and they need some explaining.
The first is the illuminating of the LEDs. By connecting 2 LEDs in series and using a 5.5v supply, we can illuminate two LEDs for each segment.
The LEDs are connected to the positive rail via a transistor. This transistor is an NPN device and is acting as an emitter-follower so that when output GP0 or GP5 of the micro is HIGH, the emitter will deliver current to the LEDs via the collector-emitter circuit. The voltage at the emitter is 0.6v less than the base and the micro will rise to nearly rail voltage (about 0.3v below rail voltage), so the positive voltage is approx 6v - 0.6v - 0.6v - 0.3v = 4.5v
The cathode of the LED-pair is connected to one of the output lines GP1, GP2 or GP4 and the voltage on the line will be approx 0.3v. This will provide a supply voltage of approx 4.2v and illuminate the two LEDs. Each LED has a natural voltage drop of approx 1.9v so you can’t allow the battery voltage to drop very much before the display will fail to work. The 47R resistor limits the current though the LEDs.
When a drive-line GP1, GP2 or GP4 is taken HIGH, output GP0 or GP5 of the micro must be LOW to allow the other two LEDs will be illuminated.
To illuminate each segment, the input/output for each line must be allocated to the TRISIO register and each line must be allocated HIGH or LOW if it is an output. The combination of segments produces a digit on either the left display or right display and the instructions are contained in a separate sub-routine.
Once the sub-routine for each character (digit) has been worked out, the program from the previous project was pasted into the program and the only instructions needed changing were those that applied to the output port.
Two separate tables are needed; one for the left display and one for the right display.
The tables have a “goto” instruction at the beginning of each line so that the micro goes immediately to the sub-routine corresponding the chosen digit for either the left or right display. The sub-routine for each digit contains the “retlw” command, to send the micro back to the Main routine.
The project has been produced on Experimental board using surface-mount components with yellow LEDs for the display. It is not for beginners, however a kit of components is available from Talking Electronics for $15.00 plus $5.00 postage. The board must be adapted for the project and this requires cutting 10 of the tracks and fine enamelled wire to connect the components to the micro.
The PIC12F629 2-Digit Counter
Cut 10 tracks as shown in the layout below, so the board suits this project.
Layout for 2 Digit Up/Down Counter
Cut 10 tracks as shown in the layout above, so the board suits this project.
The files:
The program below is the assembly program. This is for viewing ONLY. To modify the program you will need to load this file: 12F629Counter.asm into NotePad2 and make the changes.
The .asm is then compiled via MPASM to produce a .hex file for PICkit-2.
Set up your desktop as follows, with a folder called PICkit-2 files. Inside this folder you can have other folders such as PIC12F629 Counter; then an icon for MPASM and an icon for PICkit-2:
;2Digit Counter 12F629.asm ; 13-6-2009 list p=12F629 radix dec include "p12f629.inc" errorlevel -302 ;Dont complain about BANK 1 Reg during assembly __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;Internal osc. temp1 equ 20h ; temp2 equ 21h ; temp3 equ 22h ; SwUp equ 23h ; SwDwn equ 24h ; units equ 25h ; tens equ 26h ; Sw_Flag equ 27h ; FastCount equ 28h ; Count equ 29h ; counting 00 to 99 File5mS equ 2Ah ; FileXmS equ 2Bh ; ;**************************************************************** ;Equates ;**************************************************************** status equ 0x03 rp1 equ 0x06 rp0 equ 0x05 portA equ 0x05 portB equ 0x06 status equ 03h option_reg equ 81h ; bits on GPIO pin7 equ 0 ;GP0 pin6 equ 1 ;GP1 pin5 equ 2 ;GP2 pin4 equ 3 ;GP3 input only pin3 equ 4 ;GP4 pin2 equ 5 ;GP5 ;bits rp0 equ 5 ;bit 5 of the status register Start org 0x00 ;program starts at location 000 nop nop nop nop ;NOPs to get past reset vector address nop nop ;set up to allow counting from external oscillator SetUp bsf status, rp0 ;Bank 1 movlw b'11110111' ;Turn on T0CKI, prescale for TMR0 = 1:256 movwf option_reg bcf status, rp0 ;bank 0 movlw 07h ;Set up W to turn off Comparator ports movwf CMCON ;must be placed in bank 0 clrf GPIO ;Clear GPIO of junk clrf units clrf tens clrf Sw_Flag goto Main Table1 addwf 02,1 ;Add W to the Program Counter to create a jump goto showX0 ;the zero on the right-hand display goto show01 goto show02 goto show03 goto show04 goto show05 goto show06 goto show07 goto show08 goto show09 Table2 addwf 02,1 ;Add W to the Program Counter to create a jump goto show0X ;the zero on the left-hand display goto show10 goto show20 goto show30 goto show40 goto show50 goto show60 goto show70 goto show80 goto show90 ;Delay 0.005 sec (5mS) _5mS movlw 05h movwf File5mS Del5mS nop decfsz FileXmS,1 ; ,1 denotes the result of the decrement goto Del5mS decfsz File5mS,1 ; is placed in the file goto Del5mS retlw 00 FastUp btfss Sw_Flag,2 ;First time through loop? goto FU_2 ;yes btfsc Sw_Flag,7 ;Has 5Hz bit been set? goto FU_3 FU_1 incfsz FastCount,1 ;Increment FastCount movlw d'50' ;determines the time before fast incrementing xorwf FastCount,0 btfss status,2 ;reached 50 loops? retlw 00 clrf FastCount bsf Sw_Flag,7 ;set bit for 5Hz incrementing FU_2 bsf Sw_Flag,2 ;Up button has been pressed incf units,1 movlw 0Ah ;put 10 into w xorwf units,0 ;compare units file with 10 btfss status,2 ;zero flag in status file. Set if units is 10 retlw 00 clrf units incf tens,1 movlw 0Ah ;put 10 into w xorwf tens,0 ;compare units file with 10 btfsc status,2 ;zero flag in status file. Set if tens is 10 clrf tens retlw 00 ;display passes 99 but not below 0 FU_3 incfsz FastCount,1 ;Increment FastCount movlw d'5' ;Determines the speed of the increments xorwf FastCount,0 btfss status,2 ;reached 5 loops? retlw 00 clrf FastCount goto FU_2 Dwn btfsc Sw_Flag,3 retlw 00 bsf Sw_Flag,3 decf units,1 movlw 0FFh ;put FFh into w xorwf units,0 ;compare units file with FFh btfss status,2 ;zero flag in status file. Set if units is 10 retlw 00 movlw 09 movwf units ;put 9 into units file decf tens,1 movlw 0FFh ;put 0FFh into w xorwf tens,0 ;compare tens file with 0FFh btfsc status,2 ;zero flag in status file. Set if tens is 0FFh goto $+2 ;tens file is 0FFh retlw 00 clrf tens clrf units retlw 00 ;display not below 0 show01 bsf status, rp0 ;Bank 1 movlw b'00011001' ;Set TRIS to show seg B movwf TRISIO ; bcf status, rp0 ;bank 0 movlw b'00100101' ; movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10010011' ;Set TRIS to show seg C movwf TRISIO ; bcf status, rp0 ;bank 0 movlw b'00000110' ; movwf GPIO call _5mS retlw 00 show02 bsf status, rp0 ;Bank 1 movlw b'00000101' ;Set TRIS to show seg A & E movwf TRISIO ; bcf status, rp0 ;bank 0 movlw b'00010111' ; movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10011000' ;Set TRIS to show seg B & D & G movwf TRISIO ; bcf status, rp0 ;bank 0 movlw b'00100000' movwf GPIO call _5mS retlw 00 show03 bsf status, rp0 ;Bank 1 movlw b'00010001' ;Set TRIS to show seg A & C movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010111' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10011000' ;Set TRIS to show seg B & D & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00100000' movwf GPIO call _5mS retlw 00 show04 bsf status, rp0 ;Bank 1 movlw b'00010011' ;Set TRIS to show seg C movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010111' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10001100' ;Set TRIS to show seg B & F & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00100000' movwf GPIO call _5mS retlw 00 show05 bsf status, rp0 ;Bank 1 movlw b'00010001' ;Set TRIS to show seg A & C movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010111' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10001010' ;Set TRIS to show seg D & F & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00100000' movwf GPIO call _5mS retlw 00 show06 bsf status, rp0 ;Bank 1 movlw b'00000001' ;Set TRIS to show seg A & C & E movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010111' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10001010' ;Set TRIS to show seg D & F & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00100000' movwf GPIO call _5mS retlw 00 show07 bsf status, rp0 ;Bank 1 movlw b'00010001' ;Set TRIS to show seg A & C movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010111' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10011101' ;Set TRIS to show seg B movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00100000' movwf GPIO call _5mS retlw 00 show08 bsf status, rp0 ;Bank 1 movlw b'00000001' ;Set TRIS to show seg A & C & E movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010111' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10001000' ;Set TRIS to show seg B & D & F & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00100000' movwf GPIO call _5mS retlw 00 show09 bsf status, rp0 ;Bank 1 movlw b'00010001' ;Set TRIS to show seg A & C movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010111' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10001000' ;Set TRIS to show seg B & D & F & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00100000' movwf GPIO call _5mS retlw 00 showX0 bsf status, rp0 ;Bank 1 movlw b'00000001' ;Set TRIS to show seg A & C & E movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010111' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10001001' ;Set TRIS to show seg B & D & F movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00100000' movwf GPIO call _5mS retlw 00 show0X bsf status, rp0 ;Bank 1 movlw b'00100000' ;Set TRIS to show seg A & C & E movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010110' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10101000' ;Set TRIS to show seg B & D & F movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00100001' movwf GPIO call _5mS retlw 00 show10 bsf status, rp0 ;Bank 1 movlw b'00111000' ;Set TRIS to show seg B movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00100101' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10110010' ;Set TRIS to show seg C movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000110' movwf GPIO call _5mS retlw 00 show20 bsf status, rp0 ;Bank 1 movlw b'00100100' ;Set TRIS to show seg A & E movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010110' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10011000' ;Set TRIS to show seg B & D & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000001' movwf GPIO call _5mS retlw 00 show30 bsf status, rp0 ;Bank 1 movlw b'00110000' ;Set TRIS to show seg A & C movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010110' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10011000' ;Set TRIS to show seg B & D & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000001' movwf GPIO call _5mS retlw 00 show40 bsf status, rp0 ;Bank 1 movlw b'00110010' ;Set TRIS to show seg C movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010110' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10001100' ;Set TRIS to show seg B & F & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000001' movwf GPIO call _5mS retlw 00 show50 bsf status, rp0 ;Bank 1 movlw b'00110000' ;Set TRIS to show seg A & C movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010110' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10001010' ;Set TRIS to show seg D & F & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000001' movwf GPIO call _5mS retlw 00 show60 bsf status, rp0 ;Bank 1 movlw b'00100000' ;Set TRIS to show seg A & C & E movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010110' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10001010' ;Set TRIS to show seg D & F & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000001' movwf GPIO call _5mS retlw 00 show70 bsf status, rp0 ;Bank 1 movlw b'00110000' ;Set TRIS to show seg A & C movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010110' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10111100' ;Set TRIS to show seg B movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000001' movwf GPIO call _5mS retlw 00 show80 bsf status, rp0 ;Bank 1 movlw b'00100000' ;Set TRIS to show seg A & C & E movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010110' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10001000' ;Set TRIS to show seg B & D & F & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000001' movwf GPIO call _5mS retlw 00 show90 bsf status, rp0 ;Bank 1 movlw b'00110000' ;Set TRIS to show seg A & C movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00010110' movwf GPIO call _5mS bsf status, rp0 ;Bank 1 movlw b'10001000' ;Set TRIS to show seg B & D & F & G movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000001' movwf GPIO call _5mS retlw 00 ;**************************************************************** ;* Main * ;**************************************************************** Main bsf status, rp0 ;Bank 1 movlw b'11111101' ;Set TRIS movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000000' ;Set GP1 low movwf GPIO btfsc GPIO,3 call FastUp ;UP switch pressed bsf status, rp0 ;Bank 1 movlw b'11111101' ;Set TRIS movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000010' ;Set GP1 High movwf GPIO btfss GPIO,3 ;down produces 90 call Dwn ;Down switch pressed clrf GPIO movf units,0 ;copy unit value into w call table1 ;unit display value will return in w movf tens,0 ;copy tens value into w call table2 ;tens display value will return in w bsf status, rp0 ;Bank 1 movlw b'11111101' ;Set TRIS movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000010' ;Set GP1 High movwf GPIO btfsc GPIO,3 ;bit will be zero when sw is pressed - down bcf Sw_Flag,3 ;button not pressed. Clear down flag bsf status, rp0 ;Bank 1 movlw b'11111101' ;Set TRIS movwf TRISIO bcf status, rp0 ;bank 0 movlw b'00000000' ;Set GP1 low Testing for UP switch movwf GPIO btfsc GPIO,3 ;UP will be High when pressed goto Main bcf Sw_Flag,2 ;button not pressed. Clear Up flag bcf Sw_Flag,7 ;Clear Up repeat flag clrf FastCount goto Main ;oscillator calibration call 03ffh movwf OSCCAL end
PIC12F629 version with SM LEDs
(All surface mount 1/10th watt)
You will also need the 6 pin to 5 pin adapter for “In Circuit Programming” to connect between the PICkit-2 programmer and the Project ($1.50): A PC board is being produced for the adapter.
Now that you know how to access each of the segments i the left and right displays, you can produce all sots of programs.
Some of the ideas we have in the pipeline include a timer. How many times have you burnt something or forgotten to ring someone back after an hour?
This handy timer has a few buttons and by simply pressing a button it will count down and sound a piezo when the time has expired.
This will be one of the next projects but you can get in first and try your hand at programming.
All you need do is add a buffer to drive a piezo and since all the lines are fully occupied, this will require a clever bit of interfacing.
I will give you a clue how to do it.
The output of one of the lines will contain a delay circuit (say 0.2 second) and when this is kept low, the other line can be used to drive the buffer transistor, as shown in the following diagram:
To order the kit, [send an email](mailto:colin@elechelp.com?Subject=Buying components for the 2 Digit Up/Down counter&Body=Please e-mail the cost of components for the 2 Digit Up/Down counter on prototype PC board and 5/6 pin adapter for $23.00 posted by air mail to my country:****___**** and send details of how I can pay for it. My name is:____**)** to us and we will reply with the details of how to order etc.
If you have any questions on how the circuit works or how to add different features, [email the author](mailto:colin@elechelp.com?Subject=Query on 2 Digit Up/Down counter&Body=Please let me know the following:****___******)** and your answer will be posted here:
Quick Links
Legal Stuff
Social Media