PDA

View Full Version : 7 segment digit problem (using Mister E's code)



jmgelba
- 17th June 2005, 04:00
I searched and found this code...

' Pulse counter
'
' File name : Count_Display.bas
' Company : Mister E
' Programmer : Steve Monfette
' Date : 27/12/2004
' Device : PIC16F84A-20/P
' This program display to 3 x 7 segments dislay the result of
' pulses count on PORTA.4 pin/sec.
'
' Hardware connection :
' ---------------------
' 1. 3 X 7 segments display on PORTB<7:0>
' 2. 3 X PNP transistor on PORTA<3:0> to drive common anode
' of each 7 segments display
'
' Programming mode and PIC define
' -------------------------------
'
DEFINE OSC 20 '

' I/O Definition
' --------------
'
TRISA = %11111000 ' PORTA : <2:0> outputs to common Anode of 7 segment
' 1. PORTA.0 More significant
' 2. PORTA.2 Less significant
' : PORTA.4 input for signal
'
TRISB = 0 ' PORTB connected to 7 segments
' B0 : segment a
' B1 : segment b
' B2 : segment c
' B3 : segment d
' B4 : segment e
' B5 : segment f
' B6 : segment g
' B7 : segment decimal dot
' Internal EEPROM definition
' --------------------------
'
data @0,192,249,164,176,153,146,130,248,128,144 ' table to convert
' numbers to 7 segments
' pattern output when
' drive invert



' Interrupt and register definition
' ---------------------------------
'
OPTION_REG = %11101000 ' TMR0 clock source : RA4/T0CKI
' increment on low to high transition
' Prescaler assign to WDT
' WDT rate 1:1
'
INTCON = %10100000 ' Enable global interrupt
' Disable EE write interrupt
' Enable TMR0 overflow interrupt


' Variable definition
' -------------------
'
DisplayPort var PORTB ' Port for 7 Segments
ClockInput var PORTA.4 ' Input pin for signal
_7Seg1 con 14 ' enable more significant 7 segment display
_7Seg2 con 13 ' enable mid significant 7 segment display
_7Seg3 con 11 ' enable less significant 7 segment display
Digit_1 var byte ' Hundreds digit
Digit_2 var byte ' Tenth digit
Digit_3 var byte ' Unit digit
ToBeDisplay var word ' Result of count to be send to 7 segment display
Display var byte ' Temp variable
DisplayLoop var byte '
Delay var word ' Variable for Delay loop
OverFlowVar var word '
Thousands var bit ' Flag for count >= 1000 & < 10 000
TenThousands var bit ' Flag for count >= 10 000


' Variable and software initialisation
' ------------------------------------
'
tobedisplay = 0 ' set initial value of count
TMR0 = $00 ' reset prescaller
on interrupt goto SetVarToBeDisplay

MainLoop:

' MainLoop
' ---------
'
' 1. display the result of the count on RA4 pin
' 2. refresh display
' 3. reset Timer0
' 4. reload prescaler.
'
' Duration of the procedure : 1 sec
' fine tuned by DelayBetweenEachDisplay Sub
'
' Looping 1 sec and get results of the pulse count in
' TMR0 + OverFlowVar
'
DisplayRefresh:
'
' Testing amount of count
' -----------------------
'
' Get the result of count and place decimal point flag
' on the according 7 segments
'
If tobedisplay>=1000 then
tobedisplay=tobedisplay/10
if tobedisplay>=1000 then
tobedisplay=tobedisplay/10
Thousands=0
TenThousands=1
else
TenThousands=0
thousands=1
endif
else
thousands=0
tenthousands=0
endif
'
' convert digit to 7 segment output pattern
' -----------------------------------------
display=ToBeDisplay dig 2 ' Read hundreds digit
read display,digit_1 ' Convert hundreds
if thousands==1 then digit_1=digit_1 & $7F ' enable decimal dot
' by clearing PORTB.7

display=ToBeDisplay dig 1 ' Read tenths digit
read display,digit_2 ' Convert tenths
if tenthousands==1 then digit_2=digit_2 & $7F ' enable decimal dot '
' by clearing PORTB.7

display=ToBeDisplay dig 0 ' Read units digit
read display,digit_3 ' Convert units
'
'
' Send digit to 7 segments
' ------------------------
for displayloop = 0 to 111 ' loop for about 1 sec

' display hundreds
' ----------------
PORTA=_7seg1 ' enable hundreds 7 segment
displayport=digit_1 ' display
gosub DelayBetweenEachDigit

' display tenth
' -------------
PORTA=_7seg2 ' enable tenth 7 segment
displayport=digit_2 ' display
gosub DelayBetweenEachDigit

' display units
' -------------
PORTA=_7seg3 ' enable unit 7 segment
displayport=digit_3 ' display
gosub DelayBetweenEachDigit

next
tobedisplay = overflowvar + TMR0
OverFlowVar = 0 ' Reset OverFlowVar
INTCON.2 = 0 ' clear overflow flag
TMR0 = $D9 ' reset prescaller
goto displayrefresh


DelayBetweenEachDigit:

' DelayBetweenEachDigit
' ---------------------
' Produce delay of about 3 mSec
'
' Fine tuned with MPLAB StopWatch to get MainLoop = 1 sec
'
for delay=1 to 307
@ nop
next
@ nop
@ nop
@ nop
@ nop
@ nop
@ nop
@ nop
return


disable
SetVarToBeDisplay:
'
' SetVarToBeDisplay
' -----------------
' interrupt routine of TMR0 overflow
'
' Reset prescaller
' Reset overflow flag
'
OverFlowVar = OverFlowVar + 256
INTCON.2 = 0 ' clear overflow flag
TMR0 = $D9 ' reload TMR0
resume
enable

jmgelba
- 17th June 2005, 04:00
/\/\/\
I've modified it so that it no longer uses the interupt, but just loops and adds 1 at each loop.
Its also modified to display on 5 displays, and I will add a 6th shortly. It currently ghosts the numbers on each digit. I played with the timing and cant resolve the problem. Also, what are the CON numbers doing, as I changed them and get different results based on their number? There are 10K pull downs on each base and every segment. There 4.7K's between the pic and the base of each 2n3906.

Here is my code so far using a 16F818.......

define OSC 10
TRISA = %11100000
TRISB = 0


data @0,192,249,164,176,153,146,130,248,128,144 ' table to convert
' numbers to 7 segments


DisplayPort var PORTB ' Port for 7 Segments
ClockInput var PORTA.5 ' Input pin for signal
_7Seg0 con 5 ' enable tenthousands 7 segment display
_7Seg1 con 4 ' enable thousands 7 segment display
_7Seg2 con 3 ' enable hundreds 7 segment display
_7Seg3 con 2 ' enable tens 7 segment display
_7Seg4 con 1 ' enable units 7 segment display
Digit_0 var word ' tenthousands digit
Digit_1 var word ' thousands digit
Digit_2 var word ' hundreds digit
Digit_3 var word ' tens digit
Digit_4 var word ' Unit digit
ToBeDisplay var word ' Result of count
Display var word ' Temp variable
DisplayLoop var word '
Delay var word ' Variable for Delay loop
OverFlowVar var word '
Thousands var bit ' Flag for count >= 1000 & < 10 000
TenThousands var bit ' Flag for count >= 10 000





tobedisplay = 0 ' set initial value of count


DisplayRefresh:

' convert digit to 7 segment output pattern
' -----------------------------------------
display=ToBeDisplay dig 4 ' Read tenthousands digit
read display,digit_0 ' Convert tenthousands
if thousands==1 then digit_0=digit_0 & $7F ' enable decimal dot
' by clearing PORTB.7

display=ToBeDisplay dig 3 ' Read thousands digit
read display,digit_1 ' Convert thousands
if thousands==1 then digit_1=digit_1 & $7F ' enable decimal dot
' by clearing PORTB.7

display=ToBeDisplay dig 2 ' Read hundreds digit
read display,digit_2 ' Convert hundreds
if thousands==1 then digit_2=digit_2 & $7F ' enable decimal dot
' by clearing PORTB.7

display=ToBeDisplay dig 1 ' Read tenths digit
read display,digit_3 ' Convert tenths
if tenthousands==1 then digit_3=digit_3 & $7F ' enable decimal dot
' by clearing PORTB.7

display=ToBeDisplay dig 0 ' Read units digit
read display,digit_4 ' Convert units
'
'
' Send digit to 7 segments
' ------------------------

for displayloop = 1 to 53
' display tenthousands
' ----------------
PORTA=_7seg0 ' enable tenthousands 7 segment
displayport=digit_0 ' display
gosub DelayBetweenEachDigit


' display thousands
' ----------------
PORTA=_7seg1 ' enable thousands 7 segment
displayport=digit_1 ' display
gosub DelayBetweenEachDigit

' display hundreds
' ----------------
PORTA=_7seg2 ' enable hundreds 7 segment
displayport=digit_2 ' display
gosub DelayBetweenEachDigit

' display tenth
' -------------
PORTA=_7seg3 ' enable tenth 7 segment
displayport=digit_3 ' display
gosub DelayBetweenEachDigit

' display units
' -------------
PORTA=_7seg4 ' enable unit 7 segment
displayport=digit_4 ' display
gosub DelayBetweenEachDigit

next
tobedisplay = tobedisplay + 1
goto displayrefresh



DelayBetweenEachDigit:

for delay=1 to 307
@ nop
next
@ nop
@ nop
@ nop
@ nop
@ nop
@ nop
@ nop
return

SuB-ZeRo
- 17th June 2005, 05:13
First this is not a pulse counter.This is only the way that i found by my self.
Coz there re no command for 7 segment (i hope they will do)
and u can use like a pulse counter by useing little subrutines

all PORTB connedted to the 7 segment
PORTA.1 enable diggit 1
PORTA.2 enable diggit 2
i did it without transistor if u want to see better
u can put a transistor and decrase the pause command
'''''''''''''''''''''''''''''''''The codes
sayac VAR BYTE
dij1 VAR BIT[9]
dij2 VAR BIT[9]
sayac=0
gosterge1:
IF sayac > 99 Then sayac =0
dij1 = sayac DIG 0
High PORTA.1
IF dij1=0 Then TRISB=%00111111
IF dij1=1 Then TRISB=%00000110
IF dij1=2 Then TRISB=%01011011
IF dij1=3 Then TRISB=%01001111
IF dij1=4 Then TRISB=%01100110
IF dij1=5 Then TRISB=%01101101
IF dij1=6 Then TRISB=%01111101
IF dij1=7 Then TRISB=%00000111
IF dij1=8 Then TRISB=%01111111
IF dij1=9 Then TRISB=%01100111
Pause 90
Low PORTA.1
dij2 = sayac DIG 1
High PORTA.2
IF dij2=0 Then TRISB=%00111111
IF dij2=1 Then TRISB=%00000110
IF dij2=2 Then TRISB=%01011011
IF dij2=3 Then TRISB=%01001111
IF dij2=4 Then TRISB=%01100110
IF dij2=5 Then TRISB=%01101101
IF dij2=6 Then TRISB=%01111101
IF dij2=7 Then TRISB=%00000111
IF dij2=8 Then TRISB=%01111111
IF dij2=9 Then TRISB=%01100111
Pause 90
Low PORTA.2
sayac = sayac + 1
Pause 300
GoTo gosterge1
End
I know it's really simple but i am a newbie i can't do better now :(

mister_e
- 17th June 2005, 05:14
This was the audio frequency counter code... posted there
http://www.picbasic.co.uk/forum/showthread.php?t=1044

And like i said it's also post on the Melabs website and include the schematics wich can help to figure few things
http://www.melabs.com/resources/samples/submitted/counter.zip



Also, what are the CON numbers doing, as I changed them and get different results based on their number?

i always try to make it easy to read but here's a short explanation of those constants because the choice of their value are important in that.

If you look to the schematic and comments at the top of the original code, PORTA<3:0> is attach to a transistor wich is driving the Common anode on each 7 segment display. Each transistor need to be drive with a low level signal at the base.

Using constant make the code easier to read.
_7Seg1 con 14 ' enable more significant 7 segment display

and later we use...
PORTA=_7seg1 ' enable hundreds 7 segment

same as PORTA=14 or PORTA=%11111110
only the 'hundreds' display is used. When i look to your own definition, you choose more than one 7 segment display at the time so you display on more than one 7 segment at the time. this is one of the reason you see some odd results. few other things now
on PIC16F818, PORTA is analogue, you must set it to digital.
PORTA.4 is open drain, you'll need to modify your hardware to fit to this pin.
to use PORTA.5 you must set your configuration fuse to disable MCLR pin and use it as an i/o
don't forget, the original code was made for a 20MHZ crystal speed and will really not do the same things with a 10 MHZ clock since the DelayBetweenEachDisplay is based on a MPLAB stopwatch simulation. you'll need to divide it by 2 to have about the same delay


Once everything above is done... it's suppose to give better results. well as i see now before to go to sleep...

jmgelba
- 17th June 2005, 22:49
Hey Steve thanks for the info. It now works perfectly. I still have to add the 6th digit, and it currently only counts up to 65000 before rolling over. I need to put the count in 2 locations and use them to get up to 999999. Im not sure how to do that. Any idea? lowbyte and hibyte?

Here is the updated code. The display rate is set very fast to count up quickly.

define OSC 10
TRISA = %11100000
ADCON1 = 0
TRISB = 0


data @0,192,249,164,176,153,146,130,248,128,144 ' table to convert
' numbers to 7 segments
' pattern output when
' drive invert


DisplayPort var PORTB ' Port for 7 Segments
ClockInput var PORTA.5 ' Input pin for signal
_7Seg0 con 207 ' enable tenthousands 7 segment display
_7Seg1 con 215 ' enable thousands 7 segment display
_7Seg2 con 222 ' enable hundreds 7 segment display
_7Seg3 con 221 ' enable tens 7 segment display
_7Seg4 con 219 ' enable units 7 segment display
Digit_0 var word ' tenthousands digit
Digit_1 var word ' thousands digit
Digit_2 var word ' hundreds digit
Digit_3 var word ' tens digit
Digit_4 var word ' Unit digit
ToBeDisplay var word ' Result of count to be send to 7 segment display
Display var word ' Temp variable
DisplayLoop var word '
Delay var word ' Variable for Delay loop
OverFlowVar var word '
Thousands var bit ' Flag for count >= 1000 & < 10 000
TenThousands var bit ' Flag for count >= 10 000





tobedisplay = 0 ' set initial value of count


DisplayRefresh:

' convert digit to 7 segment output pattern
' -----------------------------------------
display=ToBeDisplay dig 4 ' Read tenthousands digit
read display,digit_0 ' Convert tenthousands
if thousands==1 then digit_0=digit_0 & $7F ' enable decimal dot
' by clearing PORTB.7

display=ToBeDisplay dig 3 ' Read thousands digit
read display,digit_1 ' Convert thousands
if thousands==1 then digit_1=digit_1 & $7F ' enable decimal dot
' by clearing PORTB.7

display=ToBeDisplay dig 2 ' Read hundreds digit
read display,digit_2 ' Convert hundreds
if thousands==1 then digit_2=digit_2 & $7F ' enable decimal dot
' by clearing PORTB.7

display=ToBeDisplay dig 1 ' Read tenths digit
read display,digit_3 ' Convert tenths
if tenthousands==1 then digit_3=digit_3 & $7F ' enable decimal dot '
' by clearing PORTB.7

display=ToBeDisplay dig 0 ' Read units digit
read display,digit_4 ' Convert units
'
'
' Send digit to 7 segments
' ------------------------

for displayloop = 1 to 10 'was 53
' display tenthousands
' ----------------
PORTA=_7seg0 ' enable tenthousands 7 segment
displayport=digit_0 ' display
gosub DelayBetweenEachDigit


' display thousands
' ----------------
PORTA=_7seg1 ' enable thousands 7 segment
displayport=digit_1 ' display
gosub DelayBetweenEachDigit

' display hundreds
' ----------------
PORTA=_7seg2 ' enable hundreds 7 segment
displayport=digit_2 ' display
gosub DelayBetweenEachDigit

' display tenth
' -------------
PORTA=_7seg3 ' enable tenth 7 segment
displayport=digit_3 ' display
gosub DelayBetweenEachDigit

' display units
' -------------
PORTA=_7seg4 ' enable unit 7 segment
displayport=digit_4 ' display
gosub DelayBetweenEachDigit

next
tobedisplay = tobedisplay + 1
goto displayrefresh



DelayBetweenEachDigit:

' DelayBetweenEachDigit
' ---------------------
' Produce delay of about 3 mSec
'
' Fine tuned with MPLAB StopWatch to get MainLoop = 1 sec
'
for delay=1 to 5 'was 307
@ nop
next
@ nop
@ nop
@ nop
@ nop
@ nop
@ nop
@ nop
return

jmgelba
- 27th June 2005, 02:48
Here's an update to the code. Darrel has done all the hard work, so a big thank you to him.
It currently counts all the way up to 99999.9 hours. All thats remaining is to work the bugs out of the eeprom storage. The project has to store the number accumulated so that when power is restored, we dont start logging hours from 0 again.


Regards,
James.

Darrel Taylor
- 27th June 2005, 03:04
Hey James,

I thinks it's just that there is already data at locations 0-10 for the seven segment decoding.

Try moving the EE_Hours constant to somewhere above that.

Darrel

highlander
- 9th September 2005, 20:25
I've been reading thru the code and am currently working on my own program based on Mr_E's program for 3 digits. I'm actually modding it to work with 2 and am having a slight issue. I'm definitely a newbie on this but could use some pointers.

My current setup is to have PortA pins 0 and 1 be inputs for sensors I'm hooking up. PortA 2 and 3 are hooked up to the transistors as described on meLabs site for the 7seg 4 display. And planning to use either a pin on PortB or PortA pin 5 to drive a motor.

Now on my understanding this would result into what I want

TRISA = %11110011 <--- 0011 being outputs to transistors and inputs from sensors

TRISB = %11111110 <-- 0 being the motor servo

Now is there anything else that may cause a issue with doing it this way where the 1st 7dig segment doens't light up and the 2nd would cycle thru erronous LED's lighting up?

I could go into more detail but being I'm at work, I can't really go into it at the moment. But any hints would be helpful. Thanks