|
|
THREE DIGIT
COUNTER
and
A-to-D CONVERTER
Page 9
INDEX
Even though the PIC LAB-1 board has only a single display, a 3-digit counter can
be displayed by flashing the 3 digits then pausing before displaying again. Ws
have produced up to 5 digits in this manner and the counter is fairly easy to
read once you realize how the digits are displayed.
The 3-digit counter serves to show how the limitations
of a single display can be overcome.
We have produced another project 5x7
Display, using a single display to produce a 3 and 5-digit counter.
It uses a matrix of LEDs to produce a single digit and the same principle of
"flashing" has been used.
Multiple-digit counters can be called "tally counters" for
recording the total production of a particular item. Some items can be weighed
to get a quantity but this takes time and expense.
The simplest is to have a detector (plus electronics) record each item as it is being
produced and keep track of the total. This can be used to "back up" the values
obtained from individually weighed amounts.
A tally counter will only need to be read once a day and the
single digit can be a low-cost way of showing this value.
The program can be designed to accept a code from a set of buttons so that
operators cannot access the data. It's a security measure to
avoid theft and fraud.
THE PROGRAM
A 3-digit counter requires three files to hold the "tally." Each
digit is held in the lower "nibble" (a nibble is 4 bits).
These files are initially cleared so the readout is "000."
The first digit (actually the hundreds) is displayed then the display is cleared for a short time.
This is repeated for the second and third digit.
The display is then cleared for a longer period of time to indicate the end
of the number.
The routine is then repeated.
Throughout the program, the input must be poled at (looked at) regular intervals.
The most difficult part of the program is to place the button-instruction
where it can be constantly executed by the micro.
The only place is within the display routine.
The program takes about 1 second to display the three digits and in this time
the button can be pressed 10 or more times.
By placing the button instruction (BTFSS 05,0) in the display routine it is
accessed every 2mS.
You can press the button while the display is flashing and the program will
increment the tally in the background. The result is very impressive. It
appear that the program is down two things at the same time.
The circuit for the counter:
Here is the complete program:
;3digit.asm
;Project: 3 Digit Counter
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh ;_CP_OFF & _PWRTE_ON
& _WDT_OFF & _RC_OSC |
SetUp
Table
Clear
Display
Disp1
Disp2
DelA
Inc
Main
|
ORG 0
BSF 03,5
CLRF 06
MOVLW 01
MOVWF 05
BCF 03,5
CLRF 05
CLRF 1F
CLRF 11h
CLRF 12h
CLRF 13h
GOTO Main
ADDWF 02h,1
RETLW 3Fh
RETLW 06h
RETLW 5Bh
RETLW 4Fh
RETLW 66h
RETLW 6Dh
RETLW 7Dh
RETLW 07h
RETLW 7Fh
RETLW 6Fh
MOVLW 20h
MOVWF 0D
CLRF 06
CALL Disp1
RETURN
MOVLW 80h
MOVWF 0Ch
BTFSS 05,0
GOTO Disp2
BTFSC 1F,0
GOTO DelA
BSF 1F,0
CALL Inc
GOTO DelA
BCF 1F,0
NOP
DECFSZ 1A,1
GOTO DelA
DECFSZ 0C,1
GOTO Disp1
RETURN
INCF 11h,1
MOVLW 0A
XORWF 11h,0
BTFSS 03,2
RETURN
CLRF 11h
INCF 12h,1
MOVLW 0A
XORWF 12h,0
BTFSS 03,2
RETURN
CLRF 12h
INCF 13h,1
MOVLW 0A
XORWF 13h,0
BTFSS 03,2
RETURN
CLRF 13h
RETURN
MOVF 13h,0
CALL Table
MOVWF 06
CALL Display
CALL Clear
MOVF 12h,0
CALL Table
MOVWF 06
CALL Display
CALL Clear
MOVF 11h,0
CALL Table
MOVWF 06
CALL Display
CLRF 06
CALL Clear
CALL Clear
CALL Clear
GOTO Main
END
|
;This is
the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Load W with 0000 0001
;Make RA0 input
;Go to Bank 0 - the program memory area.
;Clear portA
;Clear the button-press file
;Clear 'units' file
;Clear 'tens' file
;Clear 'hundreds' file
;Add W to the Program Counter to create a jump.
;0 format= gfedcba
;1 If any table value has a leading
letter, it must be
;2 preceded with a
"0." E.g: 0A3h, 0FFh, 0CCh
;3
;4
;5
;6
;7
;8
;9
;Clear the display
;Test the input line on port A
;Button not pressed
;Button pressed first time?
;Button already pressed
;Set button-press flag
;Button pressed. Increment count
;Increment units.
;Has count reached ten?
;Compare file 11h with ten
;Check the zero flag in Status file
;Count has not reached ten
;Zero the units file
;Increment tens.
;Has count reached ten?
;Compare file 12h with ten
;Check the zero flag in Status file
;Count has not reached ten
;Zero the tens file
;Increment hundreds.
;Has count reached ten?
;Compare file 13h with ten
;Check the zero flag in Status file
;Count has not reached ten
;Zero the hundreds
;Copy 'hundreds' into W
;Display the number
;Copy 'tens' into W
;Display the number
;Copy 'units' into W
;Display the number
;Blank the display
;Tells assembler end of program
|
|
It is very easy to change the program to create a 4 or 5 digit
display. A new file (say 14h) must be added. It is cleared in SetUp
and added to Inc
sub-routine (by copying instructions) to produce thousands. It is then added to Main
by copying a small block of instructions in Main and changing the values as needed.
ANALOGUE TO DIGITAL (A-to-D)
The analogue input on the PIC LAB-1 reads a value of resistance connected to
the "pot" terminals.
Connecting a potentiometer to the PIC LAB-1
The value of resistance can be almost any value from 10 ohms
to 1M (and higher).
But it's a little bit more complex than simply fitting an unknown value of resistance
and showing the value on the display.
The program has to be "set up."
It works like this:
The first step is to decide on the maximum resistance you wish to measure.
Suppose it is 1,000 ohms.
The input line is capable of dividing this value into 256 parts (say 250 parts).
This means the resolution is 1,000/250 = 4 ohms
If the maximum value is 10,000 ohms, the resolution is 40 ohms.
If the maximum resistance is 100,000 ohms, the resolution is 400 ohms and for
1M it is 4k.
This is the resolution if we use a single file to hold the result. We can get
a better resolution if two files are used (256 x 256 = 65,535 parts) and this
will be a future experiment.
For now, we will keep it simple and use a single file.
In the first case, a filled count-file (containing 250) must indicate 1,000 on
the display. To perform the conversion, the transfer from the count-file to
the display files (files 11h, 12h and 13h) is carried out 4 times. In
other words the 250 is multiplied by 4 to get 1,000.
The pot included in the kit is 10,000 ohms. To convert 1,000 to 10,000 a zero
is added to the display.
Connect the pot to the project, burn the following
program into the PIC chip and rotate the pot. You will be able to read the
value on the display (from nearly zero ohms to about 10k).
The lowest digit ("0") is added to the 3-digit counter (shown above)
to get 4
digits.
;Pot1.asm
;Project: Potentiometer to PIC LAB-1
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh ;_CP_OFF & _PWRTE_ON
& _WDT_OFF & _RC_OSC |
SetUp
Table
Clear
Delay
Inc
Look
Look2
Main
Main1
Main2
Main3
Main4
|
ORG 0
BSF 03,5
CLRF 06
MOVLW 10h
MOVWF 05
BCF 03,5
CLRF 05
GOTO Main1
ADDWF 02h,1
RETLW 3Fh
RETLW 06h
RETLW 5Bh
RETLW 4Fh
RETLW 66h
RETLW 6Dh
RETLW 7Dh
RETLW 07h
RETLW 7Fh
RETLW 6Fh
MOVLW 80h
MOVWF 1B
CLRF 06
CALL Delay
RETURN
NOP
NOP
DECFSZ 1A,1
GOTO Delay
DECFSZ 1B,1
GOTO Delay
RETURN
INCF 11h,1
MOVLW 0A
XORWF 11h,0
BTFSS 03,2
RETURN
CLRF 11h
INCF 12h,1
MOVLW 0A
XORWF 12h,0
BTFSS 03,2
RETURN
CLRF 12h
INCF 13h,1
MOVLW 0A
XORWF 13h,0
BTFSS 03,2
RETURN
CLRF 13h
RETURN
CLRF 0C
BSF 06,7
NOP
INCF 0C,1
BTFSC 05,4
GOTO Look2
BCF 06,7
RETURN
MOVF 13h,0
CALL Table
MOVWF 06
CALL Delay
CALL Clear
MOVF 12h,0
CALL Table
MOVWF 06
CALL Delay
CALL Clear
MOVF 11h,0
CALL Table
MOVWF 06
CALL Delay
CALL Clear
MOVLW 3Fh
MOVWF 06
CALL Delay
CALL Clear
CALL Delay
CALL Delay
CLRF 11h
CLRF 12h
CLRF 13h
CALL Look
MOVLW 04
MOVWF 0F
MOVF 0C,0
MOVWF 0E
DECFSZ 0E,1
GOTO Main4
DECFSZ 0F,1
GOTO Main2
GOTO Main
CALL Inc
GOTO Main3
END
|
;This is the start of memory for the program.
;Go to Bank 1
;Make all Port B output
;Load W with 0001 0000
;Make RA4 input
;Go to Bank 0 - the program memory area.
;Clear PortA
;Add W to the Program Counter to create a jump.
;0 format= gfedcba
;1 If any table value has a leading letter, it must be
;2 preceded with a "0."
E.g: 0A3h, 0FFh, 0CCh
;3
;4
;5
;6
;7
;8
;9
;Clear the display
;Create 300mS delay
;Increment units.
;Has count reached ten?
;Compare file 11h with ten
;Check the zero flag in Status file
;Count has not reached ten
;Zero the units file
;Increment tens.
;Has count reached ten?
;Compare file 12h with ten
;Check the zero flag in Status file
;Count has not reached ten
;Zero the tens file
;Increment hundreds.
;Has count reached ten?
;Compare file 13h with ten
;Check the zero flag in Status file
;Count has not reached ten
;Zero the hundreds
;Count-down file
;Take cap HIGH
;Is input LOW?
;Take cap low
;Copy 'hundreds' into W
;Display the number
;Copy 'tens' into W
;Display the number
;Copy 'units' into W
;Display the number
;Output "0"
;Blank display
;Clear 'units' file
;Clear 'tens' file
;Clear 'hundreds' file
;Four loops of "Count to display"
;Copy 0C to W
;Move W to 0E
;Move count-down file to display-value
;Create display value
;Tells assembler end of program
|
|
You will find the readout starts at 0000 and goes as high as
approx 8760. It does not show 9999.
What is the problem?
This is where the answer gets technical, but very interesting.
The time-delay circuit made up of the 100n and 10k resistor in series, has a
time-constant of approx 1,100mS to charge the 100n when the resistance is
10k. This is not the normal "time-constant" covered in a normal
RC or time-delay circuit, where the capacitor charges to approx 66% of its
maximum value. In our case the capacitor charges until the lower threshold of
the input to the PIC detects a LOW. You can select any "cut-off
point" or "trigger point" for any determination, providing the value
can be repeated.
The "Look" circuit, looks at the input for the 4 instructions
between "Look2" and GOTO Look2. These instructions take 5uS. 256
loops of 5uS = 1280uS. At a time-interval of 1,100uS the loop counter is 220.
The program multiplies this by 4 to get 8800.
HOW CAN THE READING BE ALTERED?
This highlights two factors.
At an execution speed of one million instructions per second, the instruction-speed is not
high enough to allow the programmer to adjust the length of the loop. In other words, instructions
cannot be added or deleted to make minor increments or decrements. If we remove the NOP in the loop, the
counter will reach 256 when the resistance is about 8 or 9k and this will
produce a false reading on the other side of the range.
The only thing we can do is match the circuit to the program.
If the capacitor is increased in value by about 10 times (to 1u), the charge-time will increase and this
will give the programmer the ability to adjust the length of the loop.
ALTERNATIVE
DETECTION METHOD
There is another method of detecting the value of resistance using only a
single input/output line. The circuit is shown below. It does not matter if
the pot is above or below the capacitor.
Measuring resistance with a single in/out line
The program is not as fast as the method above and will result in a slower
"up-date." To achieve the same resolution as above, the charging
capacitor will have to be a large value (1u or higher) to allow the
loop-counter to fill completely.
The program starts with an uncharged capacitor and the "drive-line"
goes high for a short period of time. The line is then changed to an input (a
sense-line) and
the voltage measured. The input line can only detect a change from a LOW to a HIGH. If it
does not detect a HIGH, the line is changed back to an output ("drive-line")
and the cycle is
repeated. In this way the capacitor is gradually charged. The line reversal takes a few microseconds and a delay (a NOP) should
be placed in the program to allow the line to settle from one state to the
other before a reading is made.
The program for the "look" section is as follows. To take advantage
of the TRIS function, you must know the state of the other lines on Port B, if
you don't want them to change state during this operation.
LookB
LookC
|
CLRF 0C
MOVLW 00h
TRIS 06
BSF 06,7
INCF 0C,1
MOVLW 80h
TRIS 06
NOP
BTFSS 06,7
GOTO LookC
RETURN
|
;Count-down file
;Make the top line an output. (0000
0000)
;Take cap HIGH
;Make the top line an input. (1000 0000)
;Create a delay before reading input
;Is input HIGH?
;No
;Yes.
|
|
This method takes 10uS per loop and our previous method takes
5uS.
This is not a problem with our simple experiments. It simply means the update
time is longer.
To get the count-file to completely fill using the 10uS loop, the capacitor
will have to be larger and this will also increase the update time.
NEXT
|
|