|
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. |
||||||||||||||
|
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 Rt = R1 x R2 /
R1 + R2. To set the approximate maximum current at 18mA per segment, use an
external resistor value of 2K.
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.
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.
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.
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.
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;
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
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. 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:
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:
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
* NEW *
|