PicBasic Pro, PicBasic, BASIC Stamp, Microchip PIC, 8051, and Remote Control Projects


Time & Temperature Display With
The SLED4C 4-Digit 7-Segment Serial LED Display

NOTE: Although the SLED4C display modules are no longer available, we are leaving this project online for students & hobbyists.

The SLED4C display used the MC14489B display driver IC. The MC14489B display driver ICs' are still available from several sources. If you build this project, you will also need to acquire the MC14489B IC and build your own LED display.


Figure#1: SLED4 Pin Diagram

The 20K potentiometer shown above in figure #1 is optional, and may be replaced with a CDS photocell, a fixed resistor, or eliminated altogether. A photocell will react to changes in ambient lighting, and automatically dim the display in darkness, or brighten it in daylight.

If you don't need automatic display brightness control, simply leave pin #1 un-connected or use the equation below to calculate a fixed resistor value for your preferred brightness level.

The SLED4C had an onboard 10K 1% resistor to set the default display brightness to an acceptable level under most normal indoor lighting conditions. To change this, place a resistor from ground to pin #1 on the SLED4C. This will place the external resistor in parallel to the onboard 10K resistor.

The SLED4C uses a 4-digit common cathode Super RED 7-segment display module. Care should be taken to not exceed 25mA per LED segment to avoid damaging the LED display. We recommend the use of a potentiometer or CDS photocell, but the equation below will aid in selecting a fixed value resistor if required.

Example:

To set the SLED4C peak LED segment current value to ~18mA, use a 2K 1% resistor connected between ground and pin #1 for an Rt (resistance total) value of ~1.6K.

Note: When placing an external display intensity control resistor between the display pin #1 and ground, the external resistor will be in parallel with the onboard SLED4C 10K 1% Rx resistor. The following equation may be used to determine the total parallel resistance.

Rt = Parallel resistance total
R1 = SLED4C onboard 10K 1% Rx resistor
R2 = External resistor connected between the SLED4C Rx input pin #1 and ground

Rt = R1 x R2 / R1 + R2. To set the approximate maximum current at 18mA per segment, use an external resistor value of 2K.
Rt = 10K x 2K / 10K + 2K = 20,000,000 / 12,000 = 1.6K. As shown in figure 2, 1.6K results in ~18mA peak segment drive current.


Figure#2: RX Resistor VS LED Peak Current Levels

This project shows how to use the DS1620 temperature & DS1307 RTC for a digital Time & Temperature display. If you don't have both of these ICs handy, you can use the second code example at the bottom of this project page to cycle the display through several very interesting text messages, a counter, and other SLED4 display test routines.

If you have both these IC, then construct the circuits below in figure #3.


Figure#3: SLED4 Time & Date Controller Schematic

How It Works:

We recommend you download the SLED4C display datasheet located  HERE to follow along with the explanations below. The datasheet covers a few additional details  not shown on this page.


Figure#4: SLED4  LED Display Connections

As shown above in figure #4, the 4-digit common cathode LED clock display module is wired to the display controller a, b, c, d, e, f, g and dp cathode drivers. The leftmost LED digit is labeled #5. The rightmost LED digit is labeled #2. LED digits 5 through 2 are controlled by the anode "bank" drivers. The bank 1 anode driver controls the clock display colon (labeled L1 and L2), and the third upper right-hand decimal point LED labeled L3.

Writing data to the leftmost LED digit (Bank 5) requires sending code to the display register for the Bank 5 digit position. Writing data for display on the rightmost LED digit or Bank 2, we send data for Bank 2. The colon LEDs and upper right hand decimal point LED labeled L3 are turned ON or OFF by writing data to the Bank 1 register. Here's how it works.

The Configuration Register

The configuration register requires a single byte value to configure the decode mode, and control the power-down/normal power modes. The decode mode for each bank driver determines how data will be displayed on each digit of the LED display.

Example: If the display driver IC receives a hex value of $A for display on the LED digit connected to Bank 5, and Bank 5 is in HEX decode mode, then the LED connected to Bank 5 will display the capital letter A. If the display driver receives a hex value of $A for Bank 5, and Bank 5 is configured for "special decode" mode, then the LED digit connected to Bank 5 will display the special character which is the capital letter U. The chart in the datasheet HERE shows the characters for all three decode modes.

This byte sized configuration value has to be sent to the SLED4C before sending data to the display register. This configuration byte consists of 7 bits of decode mode data + 1 bit to control the display power-down or normal power mode. Refer to figure #5 below for details. Refer to the datasheet for the different decode modes, and characters associated with each mode.


Figure#5: Display Driver Configuration Register

You will notice how the configuration byte is loaded with the correct configuration bits in the samples below. Depending on the data we want to display, we need to first configure the display to decode data for display on each bank before sending the actual data to be displayed. Look at the short example below while referring to figure #5 above.

Notice how I always maintain the two most significant bits C7 at 1, and C6 at 1, and the least significant bit C0 at 1. The least significant bit C0 turns the display ON or OFF. This control bit is shown above in figure #5 as C0 LOW POWER MODE. Keeping the two most significant bits C7 and C6 always set to 1 makes it easy to select special decode mode. Keeping both of these bits at logic 1 is OK with the 4-digit clock display since we will never need to use the NO DECODE mode with our 4-digit LED display module.

CFG = %11000011  ' Banks 5,4,3,2 HEX decode, bank 1 (colon) special decode
GOSUB Config     ' Configure display

Note: Something else you may find interesting about the power-down mode is that whatever data was displayed on the LEDs at the time you entered power-down mode, will be restored when you return to normal power mode. This is a really neat feature of the SLED4C display. It maintains the contents of the Display Register and restores the display to the same state on return to normal power mode.

The Display Register

After sending the configuration byte, the display is ready to receive & decode data for display. The Display Register is 24 bits wide. Data is sent to the display MSB first. We use the PBP Stamp SHIFTOUT command to send all data to the display MSB first.

You must send all 24 bits when sending data to the display register. Sending only 8 bits, the display assumes the data is for the configuration register. Sending 24 bits, the display knows the data received is for the display register. If you refer to the SLED4C datasheet you'll see the MSB bits D23, D22, D21 and D20 are used for control of the display brightness, and for control of the 7-segment display DP's or decimal points.

Bit D23 sets the display brightness. If bit D23 = 0 then the display brightness will be set to approximately 50% of the value determined by the Rx resistor. If bit D23 = 1, then the display will be at 100% brightness. Again, as set by the Rx resistor. This single bit in the 24-bit data stream controls the LED brightness.

If you refer to the OUCH sub-routine in the first code example below, you'll see something like this. Note that the code snippet below is totally out of context, and only for a quick example;

Y = %00001000    ' Set bit 3 for toggling display brightness
'                                   5=O   4=U   3=C   2=H   :=OFF
SHIFTOUT DOUT, CLK, MSBFIRST, [Y\4, $0\4, $A\4, $C\4, $2\4, $0\4]
'                              ^--- bit 3 (MSB) of 4-bit value toggles brightness
Y.0[3] = Y.0[3] ^ 1' Toggle Y.bit.3 by XOR-ing with 1 [ 0=DIM, 1=BRIGHT ]

Notice from the code example above that even if even though we have assigned an 8-bit value to variable Y, that only the lower 4-bits of this byte value are shifted out. This is because we're instructing the SHIFTOUT command to send only 4-bits by using Y\4.

This is important to remember since there are only 4 bit positions for this first nibble position of the display register. If you "do not" force the 4-bit shift out using the Y\4 option, PBP will automatically shift out a full 8-bit value, so remember this little tid-bit. <-- pun intended...;o]

After the first nibble D23, D22, D21 and D20, you can send the remaining data for each display bank as byte-sized or nibble-sized packets. It does not matter as long as there are 24-bits total in the data stream, and all 24-bits are sent consecutively. I.E. in the same 24-bit data packet.

Refer to the code example above, then look at the next example below. %0000\4 sends data to dim the display, and turns off all decimal points. The byte value in the Temp variable is shifted out as 8-bits (remember, we're not forcing the 4-bit shift out using the \4 option), so PBP automatically sends a byte-sized value. If you wanted to shift out a 16-bit variable, you would have to force it by using variable_name\16 or hard-code the value something like $1234\16.

EN = 0           ' Enable data input     5/4   deg    F   :=OFF
SHIFTOUT DOUT, CLK, MSBFIRST, [%0000\4, Temp, $F\4, $F\4, $0\4]
EN = 1           ' Transfer data into display registers

Just above each value being shifted out in the example shown above, you'll notice I have inserted the LED bank or digit positions that data is going to be displayed on. Since the display memory is contiguous, the Temp variable is written into the bank 5 and bank 4 positions. This would work equally well if written something like this: [%0000\4, Temp, $FF, $0\4].

Special Note: The data and clock lines may be shared on a common bus. What this means is that several of the SLED4 displays can share the same data and clock lines. To address or control a particular display you only need to connect the "enable" pin for each additional display module to another I/O-pin, and wire the additional display clock & data pins directly into the first display clock and data pins.

To do this with the least amount of effort, simply assign the enable pin to a variable.

Example: EN VAR BYTE

Now assign EN a value that corresponds to the port pin connected to the display enable pin, on the particular display you wish to send data to.

EN = 0 would use PORTB.0.
EN = 1 would use PORTB.1.
EN = 2 would use PORTB.2.

Pretty cool feature. Only "1" single I/O-pin is required for each additional 4-digit LED display module you string onto the bus. They all share the same "common" communications data & clock bus line.

Now change every line in the code examples below where you see EN = 0 or EN = 1. Change these lines to LOW EN or HIGH EN, and "Presto". Now you can control a ton of different SLED4 displays with only 1 measly I/O-pin required per each additional display. Pretty darn handy feature don't you think..?

The 1st code example SLED_1307.BAS will cycle through displaying the Time & Temperature on a single SLED4 display module. Adjust the pause times to speed-up or slow down the time between temperature & time updates.

Since the display shows only a 2-digit temperature reading, the code limits the maximum temperature to 99°F. When the temperature goes above this setpoint, the display will blink the word OUCH several times, then code execution returns to take more time & temp readings. The display will continue to show OUCH until the temperature returns to 99°F or below.

The PicBasic Pro Code:

'****************************************************************
'*  Name    : SLED_1307.BAS                                     *
'*  Author  : Bruce Reynolds                                    *
'*  Notice  : Copyright (c) 2004 Reynolds Electronics           *
'*          : All Rights Reserved                               *
'*  Date    : 7/02/2004                                         *
'*  Version : 1.0  Digital Clock w/ Time & Temp                 *
'*  Notes   : Test code for the SLED4C 4-digit serial           *
'*          : LED/clock display module, DS1620 & DS1307 RTC     *
'****************************************************************
' PIC16F876A @ 20MHz w/boot-loader
DEFINE OSC 20
DEFINE LOADER_USED 1 ' Comment out if not using boot-loader
INCLUDE "modedefs.bas"

' Note: use 10K pull-up resistors on both SDA and SCL i2C lines
' DS1307 control pins
SDA     VAR PORTB.0 ' DS1307 SDA pin #5
SCL     VAR PORTB.1 ' DS1307 SCL pin #6

' DS1620 control pins
DQ      VAR PORTB.2 ' DS1620 DQ pin #1 
CLK0    VAR PORTB.3 ' DS1620 CLK pin #2
RST     VAR PORTB.4 ' DS1620 RST pin #3

' SLED4C display control pins
EN      VAR PORTB.5 ' SLED enable pin #5
CLK     VAR PORTB.6 ' SLED clock pin #4
DOUT    VAR PORTB.7 ' SLED data pin #3

' Variables
X       VAR WORD    ' GP var
Y       VAR BYTE    ' GP var
CFG     VAR BYTE    ' Holds display bank & digit config value
Temp    VAR WORD    ' 1620 temperature result register
DB0     VAR BYTE[8] ' Data byte array

' Port configuration
TRISB   =   0
TRISA   =   0
CMCON   =   %00000111 ' Comparators = off

    PAUSE 1000 ' Allow power to stabilize on power-up
    
    ' 24-hour clock routine for the DS1307 RTC w/SLED4C clock display
Main:
    GOSUB Write_1307 ' Write time & date on entry
    
Read_1307:
    CFG = %11000011  ' Banks 5,4,3,2 HEX decode, bank 1 (colon) special decode
    GOSUB Config     ' Configure display
    
    ' Read time Secs,Mins,Hours,Day,Date,Month,Year,Control
    I2CREAD SDA,SCL,$D0,$00,[STR DB0\8]  ' Read 8 bytes from DS1307
    EN = 0           ' Enable data input
    '                           DIM      5/4     3/2     :=ON
    SHIFTOUT DOUT,CLK,MSBFIRST,[%0000\4, DB0[2], DB0[1], $8\4]
    EN = 1           ' Transfer data into display registers
    PAUSE 2000       ' Display time for 2 seconds
    GOSUB Read_1620  ' Read & display Temp
    GOTO Read_1307   ' Read & display Time
          
Write_1307:
    ' Set time & date to 15:30:00 Tuesday 6th of July 2004
    I2CWRITE SDA,SCL,$D0,$00,[$00,$30,$15,$02,$06,$07,$04,$90] ' Write to DS1307
    RETURN                  ' Sec Min  Hr  Day D   M   Y  Control

Read_1620:    
    RST = 1
    SHIFTOUT DQ,CLK0,LSBFIRST,[$0C,$02] ' Continuous convert, CPU mode
    RST = 0
    PAUSE 10                            ' Minimum wait time after write
    RST = 1                             ' Enable 1620
    SHIFTOUT DQ, CLK0, LSBFIRST, [$EE]  ' Send start temp convert command
    RST = 0                             ' Disable 1620
    PAUSE 1000                          ' Wait for conversion to complete
    
    RST = 1                             ' Enable 1620
    SHIFTOUT DQ, CLK0, LSBFIRST, [$AA]  ' Send read temp command
    SHIFTIN DQ, CLK0, LSBPRE, [Temp\9]  ' Read 9 bit temperature
    RST = 0                             ' Disable 1620
    Temp = Temp/2                       ' Scale reading to whole degrees C. 
    Temp = (Temp */ $01CC)              ' Multiply by 1.8.
    Temp = Temp + 32                    ' Complete C to F conversion.
    IF Temp > 99 THEN Ouch              ' Is Temp > 99 deg F..?
    HSEROUT [DEC Temp DIG 1,".",DEC Temp DIG 0,13,10]
    Temp = (Temp DIG 1*16)+Temp DIG 0   ' No. Convert to BCD
    
    ' Configure display
    CFG = %11001011  ' 5,4,2 HEX decode. 3,1 special decode
    GOSUB Config     ' Write config value to display
    
    ' Display temp in deg F
    EN = 0           ' Enable data input     5/4    deg   F    :=OFF
    SHIFTOUT DOUT, CLK, MSBFIRST, [%0000\4, Temp, $F\4, $F\4, $0\4]
    EN = 1           ' Transfer data into display registers
    PAUSE 2000       ' Display Temp for 2 seconds
    RETURN

Ouch:
    CFG = %11010111  ' 5,3 hex decode. 4,2,1 special decode, display ON
    GOSUB Config     ' Write config value to display
    
    ' Write OUCH to the display when the temperature is > 99 deg F
    Y = %00001000    ' Set bit 3 for toggling display brightness
    FOR X = 0 TO 4   ' This loop causes OUCH to blink
     EN = 0          ' Enable data input
     Y.0[3] = Y.0[3] ^ 1' Toggle Y.bit.3 by XOR-ing with 1 [ 0=DIM, 1=BRIGHT ]
     '                                   5=O   4=U   3=C   2=H   :=OFF
     SHIFTOUT DOUT, CLK, MSBFIRST, [Y\4, $0\4, $A\4, $C\4, $2\4, $0\4]
     '                              ^--- bit 3 of 4-bit value toggles brightness
     EN = 1          ' Transfer data into display registers
     PAUSE 200       ' Set display blink rate here
    NEXT X           ' Close the loop
    GOTO Read_1307   ' Start over
                     
Config:              ' This routine writes the config byte to the display
    EN = 0           ' Enable data input
    SHIFTOUT DOUT, CLK, MSBFIRST, [CFG] ' Write config data to display
    EN = 1           ' Transfer data into display register
    RETURN
            
    END

The code example SLED4_2.BAS below will cycle the SLED4 display through several interesting test routines. It was compiled & tested on the PIC16F876A, but should work on pretty much any PIC. Connect pins RB5,6,7 as shown previously in figures #1 & #3 above.

Routines:

bullet

A digital counter from 0 to 1000

bullet

An ON/OFF blinking full display lamp test displaying 8.8.:8.8. with brightness toggle from 50% to 100%

bullet

A 4-digit digital clock counting from 16:50 to 17:00 with blinking colon LEDs

bullet

Right & Left 2-digit counter from 0 to 14h with display brightness at 100% then 50% and leading 0 blanking

bullet

Display H.E.L.P. while toggling the display brightness from 50% to 100%

bullet

A 4-digit counter from 9994 to 1000 at 50% brightness

bullet

Display O.U.C.H while toggling brightness between 50% & 100%

'****************************************************************
'*  Name    : SLED4_2.BAS                                       *
'*  Author  : Bruce Reynolds                                    *
'*  Notice  : Copyright (c) 2004 Reynolds Electronics           *
'*          : All Rights Reserved                               *
'*  Date    : 7/02/2004                                         *
'*  Version : 1.0                                               *
'*  Notes   : Test routines for the SLED4 4-digit serial        *
'*          : LED display module                                *
'****************************************************************
' PIC16F876A @ 20MHz w/boot-loader

DEFINE OSC 20
DEFINE LOADER_USED 1
INCLUDE "modedefs.bas"

EN      VAR PORTB.5 ' Enable pin
CLK     VAR PORTB.6 ' Clock pin
DOUT    VAR PORTB.7 ' Data out pin
X       VAR WORD    ' GP var
Y       VAR BYTE    ' GP var
                    ' Bank #1 controls the colon ":"
D2      VAR BYTE    ' Bank #2 right LED digit
D3      VAR BYTE    ' Bank #3
D4      VAR BYTE    ' Bank #4
D5      VAR BYTE    ' Bank #5 left LED digit
CFG     VAR BYTE    ' Holds display bank/digit config value

TRISB = 0

Main:
    GOSUB Counter2  ' Count from 0 to 1000
    GOSUB LampTest  ' Lamp test with 8.8.:8.8. + blinking
    GOSUB Clock     ' 4-digit clock from 16:50 to 17:00 w/blinking colon
    GOSUB Counter0  ' Colon ON + 100% bright, count on right 2, then 50% on left 2
    GOSUB Help      ' Display H.E.L.P. pulsing brightness from 50% to 100%
    GOSUB Counter1  ' Counte from 9994 to 0000 @ 50% brightness
    GOSUB Ouch      ' Display OUCH pulsing brightness from 50% to 100%
    GOTO  Main
    
Counter0:   ' Count 00-14h on right 100% bright, then count on left with 50% bright
    CFG = %11110001   ' Digits 5,4 special decode/OFF, 3,2,1 HEX decode
    GOSUB Config      ' Configure display
    
    ' Now write data to the display
    FOR X = 0 TO 20   ' Count from 0 to 14h on digits 3 & 2 with leading 0 blanking
      EN = 0          ' Display banks         5     4    3\2  :=ON
      SHIFTOUT DOUT, CLK, MSBFIRST, [%1000\4, $0\4, $0\4, X, $2\4]
      EN = 1          ' Transfer data into display registers
      PAUSE 150       ' Pause 150mS
    NEXT X
    
    CFG = %11001101   ' Digits 5,4,1 HEX decode, 3,2 special/OFF
    GOSUB Config      ' Configure display
    
    FOR X = 0 TO 20   ' Count from 0 to 14h on digits 5 & 4 with leading 0 blanking
      EN = 0          ' Enable data input    5\4   3     2   :=ON
      SHIFTOUT DOUT, CLK, MSBFIRST, [%0000\4, X, $0\4, $0\4, $2\4]
      EN = 1          ' Transfer data into display registers
      PAUSE 150       ' Display count from 0 to 14h
    NEXT X
    PAUSE 500
    RETURN
       
Counter1:   ' Count from 9994 to 0000
    CFG = %11000011   ' Digits 5,4,3,2 HEX decode, 1 special decode
    GOSUB Config      ' Configure display
    
    ' Now write data to the display
    D5=9 : D4=9 : D3=9 : D2=4 ' Load counter with 9994 on start
    FOR X = 0 TO 6    ' Count from 9994 to 0000
      EN = 0          ' Enable data input
      IF D2 > 9 THEN D2=0 : D3=D3+1 ' Increment each higher digit # on 9
      IF D3 > 9 THEN D3=0 : D4=D4+1 ' value of each lower digit # for BCD
      IF D4 > 9 THEN D4=0 : D5=D5+1 ' counting
      IF D5 > 9 THEN D5=0        '   bright    5     4     3     2    :=OFF
      SHIFTOUT DOUT, CLK, MSBFIRST, [%0000\4, D5\4, D4\4, D3\4, D2\4, $0\4]
      EN = 1          ' Transfer data into display registers
      PAUSE 500       ' Without pause, display can count from 0 to 9999 in ~6 seconds
      D2=D2+1         ' Increment counter
    NEXT X
    PAUSE 500
    RETURN
    
Counter2:   ' Count from 0 to 1000
    CFG = %11000011   ' Digits 5,4,3,2 HEX decode, 1 special decode
    GOSUB Config      ' Configure display
    
    ' Now write data to the display
    D5=0 : D4=0 : D3=0 : D2=0 ' Load counter with 0000 on start
    FOR X = 0 TO 1000 ' Count from 0 to 1000
      EN = 0          ' Enable data input
      IF D2 > 9 THEN D2=0 : D3=D3+1 ' Increment each higher digit # on 9
      IF D3 > 9 THEN D3=0 : D4=D4+1 ' value of each lower digit # for BCD
      IF D4 > 9 THEN D4=0 : D5=D5+1 ' counting
      IF D5 > 9 THEN D5=0'           bright    5     4     3     2    :=OFF
      SHIFTOUT DOUT, CLK, MSBFIRST, [%0000\4, D5\4, D4\4, D3\4, D2\4, $0\4]
      EN = 1          ' Transfer data into display registers
      PAUSE 20        ' Without pause, display counts from 0 to 9999 in ~6 seconds
      D2=D2+1         ' Increment counter
    NEXT X
    PAUSE 500
    RETURN
    
Help:   ' Display H.E.L.P. while toggling brightness from 100% to 50%
    CFG = %11101111    ' Digits 5,3,2,1 special decode, 4 HEX decode
    GOSUB Config       ' Configure display
    
    ' Now write H.E.L.P. to display blinking 50% to 100% brightness
    Y = %00001111      ' Setup bit 3 for toggling display brightness
    FOR X = 0 TO 4     ' and all DP's ON
      EN = 0           ' Enable data input
      Y.0[3] = Y.0[3] ^ 1' Flip Y.bit.3 by XOR-ing with 1 [ 0=DIM, 1=BRIGHT ]
      '           Y = brightness & DP's    5     4     3     2   :=OFF
      SHIFTOUT DOUT, CLK, MSBFIRST, [Y\4, $2\4, $E\4, $5\4, $8\4, $0\4]
      EN = 1           ' Transfer data into display registers
      PAUSE 200
    NEXT X
    PAUSE 500
    RETURN
    
Ouch:   ' Display OUCH while toggling brightness from 100% to 50%
    CFG = %11010111   ' Special decode 4,2,1. 3,5 HEX decode
    GOSUB Config      ' Configure display
    
    ' Now write OUCH to display
    Y = %00001000      ' Set bit 3 for toggling brightness & all DP's OFF
    FOR X = 0 TO 4
      EN = 0           ' Enable data input
      Y.0[3] = Y.0[3] ^ 1' Flip Y.bit.3 by XOR-ing with 1 [ 0=DIM, 1=BRIGHT ]
      '                                    5     4     3     2   :=OFF
      SHIFTOUT DOUT, CLK, MSBFIRST, [Y\4, $0\4, $A\4, $C\4, $2\4, $0\4]
      '                              ^--- bit 3 of 4-bit value toggles brightness
      EN = 1           ' Transfer data into display registers
      PAUSE 200
    NEXT X
    PAUSE 500
    RETURN

LampTest:  ' Lamp test to display 8.8.:8.8.
    CFG = %11000001    ' All digits normal HEX decode
    GOSUB Config       ' Configure display
    
    ' Now write 8.8.:8.8.
    EN = 0             '                 5=8   4=8   3=8   2=8  :=ON
    SHIFTOUT DOUT, CLK, MSBFIRST, [$F\4, $8\4, $8\4, $8\4, $8\4, $2\4]
    '                               ^-- bright display + all DP's ON
    EN = 1             ' Transfer data into display registers
    PAUSE 3000
    ' Now blink display ON & OFF 3 times
    ' Note: Toggling bit.0 of the 8-bit config byte toggles the
    ' display ON (1) & OFF (0) for normal/low power modes
    FOR X = 0 TO 2
     CFG = %11000000    ' All digits HEX decode / display off
     GOSUB Config       ' Configure display
     PAUSE 250
     CFG = %11000001    ' All digits HEX decode / display ON
     GOSUB Config       ' Configure display
     PAUSE 250
    NEXT X
    RETURN
    
Clock: ' 24-hour clock times from 16:50 to 17:00 w/blinking colon
    CFG = %11000011   ' 5,4,3,2 HEX decode, 1 special decode
    GOSUB Config      ' Configure display
    Y = 8             ' Used to toggle colon. 8 = ON, 0 = OFF
    
    ' Now write data to the display
    D5=1 : D4=6 : D3=5 : D2=0 ' Set clock time to 16:50
    FOR X = 0 TO 10   ' Display clock time from 16:50 to 17:00
      EN = 0          ' Enable data input
      IF D2 > 9 THEN D2=0 : D3=D3+1 ' Increment each higher digit on 9
      IF D3 > 5 THEN D3=0 : D4=D4+1 ' Roll-over from 59 minutes
      IF D4 > 9 THEN D4=0 : D5=D5+1 ' Roll-over from hours to tens hours
      IF D5 > 2 THEN D5=0           ' Never > 2 for 10's hour digit
      IF (D5 = 2) AND (D4 > 3) THEN ' Roll-over from 23:59 to 00:00
       D5 = 0 : D4 = 0
      ENDIF'                                  5=1   4=6   3=5   2=0  :=blinking
      SHIFTOUT DOUT, CLK, MSBFIRST, [%0000\4, D5\4, D4\4, D3\4, D2\4, Y\4]
      Y = Y ^ 8       ' 8^8=0, 0^8=8
      EN = 1          ' Transfer data into display registers
      PAUSE 250       ' Update frequency or clock ticks
      D2=D2+1         ' Increment low digit counter
    NEXT X
    PAUSE 500
    RETURN
    
Config:
    EN = 0             ' Enable data input
    SHIFTOUT DOUT, CLK, MSBFIRST, [CFG] ' Write to display config register
    EN = 1             ' Transfer data into display registers
    RETURN
                
    END

dimensions in mm

You can purchase the new SLED4C serial seven-segment display modules HERE.

For those of you that have the CCS C compiler, or just someone that wants to really appreciate how nice PicBasic Pro is when compared to doing this stuff in C, here's a quickie example I worked up for displaying the time on an SLED4C serial display using the CCS C compiler.

This example doesn't use any additional components like the DS1307 or DS1620. It's just a simple count-up timer showing how to write byte & nibble values to the SLED4C using the CCS C compiler. Really makes you appreciate PicBasic Pro doesn't it...;o]

/*

File name: SLED4C.c

Simulates 24 hour clock for
SLED4C serial LED display test

*/


#include <16f876A.h>
#use delay(clock=20000000)


#define EN PIN_B5     // Wire to enable pin on SLED4C
#define CLK PIN_B6    // Wire to clock pin on SLED4C
#define DOUT PIN_B7   // Wire to data pin on SLED4C

struct Time
{
   int hr;
   int min;
   int sec;
};

//                      Hrs   Mins  Secs
struct Time Time_Now = {0x22, 0x55, 0x00}; // Time_Now = 22:55:00

// Function Prototypes
void send_byte(int DAT);
void send_nib(int NIB);
void enable(void);
void disable(void);
void init(void);
void clock(void);

int Y = 8;

void Main(void)
{
   int N = 8;
   init();                         // Initialize port pins
   
   while(1)                        // Loop forever
   {
     enable();                     // Enable data entry
     send_byte(0xC3);              // Dig 5,4,3,2 HEX decode. Dig 1 special. Display ON
     disable();                    // Write value into config register

     Y ^= N;                       // Toggle Y bit 3 to toggle colon
     enable();                     // Enable data entry
     send_nib(0x00);               // DIM display, no DP's
     send_byte(Time_Now.hr);       // Send hours to display digits 5/4
     send_byte(Time_Now.min);      // Send minutes to display digits 3/2
     send_nib(Y);                  // Toggle colon ON/OFF
     disable();                    // Write time data into display registers
     delay_ms(1000);               // Set clock minutes tick time here
     clock();                      // Pseudo clock function
   }
}

void send_byte(int DAT)            // Shift out the 8-bit value in DAT MSB first
{
   int n;
   for(n=0; n<8; n++)              // Shift out 8-bits
   {
     output_bit(DOUT,DAT & 0x80);  // Output MSB of 8-bit value first
     output_bit(CLK, 1);           // Clock pin = 1
     output_bit(CLK, 0);           // Clock pin = 0
     DAT = DAT << 1;               // Shift lower bits into position
   }
}

void send_nib(int NIB)             // Shift out the lower 4-bit nibble in NIB MSB first
{
   int n;
   for(n=0; n<4; n++)              // Shift out only 4 bits
   {
     output_bit(DOUT,NIB & 0x08);  // Output MSB of 4-bit value first
     output_bit(CLK, 1);           // Clock pin = 1
     output_bit(CLK, 0);           // Clock pin = 0
     NIB = NIB << 1;               // Shift lower bits into position
   }
}   

void enable(void)                  // Take enable pin to SLED4C low
{
   output_bit(EN,0);
}

void disable(void)                 // Take enable pin to SLED4C high
{
   output_bit(EN,1);
}

void init(void)                    // Initialize port
{
    port_b_pullups(FALSE);         // Pull-ups off
    set_tris_b(0x00);              // All outputs
    output_bit(EN,1);              // Enable idles HIGH
    output_bit(CLK,0);             // Clock idles LOW
    disable_interrupts(GLOBAL);    // all interrupts OFF
}

void clock(void)
{  
  Time_Now.min +=1;                    // Increment minutes time count
      
  if ((Time_Now.min & 0x0F) > 0x09)    // Is 1's minutes digit > 9h..?
  {                                    // 0x0A + 0x06 = 0x10
     Time_Now.min +=0x06;              // Increment 10's minutes digit by 1
     if ((Time_Now.min & 0xF0) > 0x50) // If > 59 minutes
     {
       Time_Now.hr = Time_Now.hr +1;   // Increment hours
       Time_Now.min = 0;               // Roll over minutes 59 to 00 here
     }
  }
      
  if ((Time_Now.hr & 0x0F) > 0x09)     // Is 1's hours > 9h..?
  {                                    // 0x0A + 0x06 = 0x10
    Time_Now.hr +=0x06;                // Increment 10' hours digit by 1
  }

  if (Time_Now.hr > 0x23)              // If Time > 23
  {
    Time_Now.hr = 0x00;                // Roll over from 23 to 00 hours
  }  
}

Until the next project - have fun - and don't blow anything up...;o]

Regards,

-Bruce


Back to the PicBasic Projects Section

* NEW ** NEW *
MicroCode Studio Plus ICD
In-Circuit Debugger For PicBasic Pro Compiler
** Available HERE **

Copyright © 1999-2007 Reynolds Electronics

| Contact Information |