![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Testicky
Joined: 22 Nov 2003 Posts: 12 Location: South Africa / Taiwan
|
uPD7225 routines |
Posted: Mon Nov 24, 2003 12:29 pm |
|
|
Does any one has a driver or routines written in CCS for the uPD7225 LCD driver IC? ( or know where to find one )
I can't found anything around, and this is supposed to be a popular LCD driver.
Thanks a lot in advance.
Jacques[/b] _________________ Testicky |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Nov 24, 2003 12:40 pm |
|
|
Can you get the National MM5453 ?
If so, I have a driver for that one. |
|
![](templates/subSilver/images/spacer.gif) |
Testicky
Joined: 22 Nov 2003 Posts: 12 Location: South Africa / Taiwan
|
MM5453 |
Posted: Mon Nov 24, 2003 1:01 pm |
|
|
Yes, this would also be more than acceptable for my project. I actually need only 30 segments for this project. It seems quick and easy to cascade them anyway.
Thanks a lot.
Jacques _________________ Testicky |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Nov 24, 2003 1:40 pm |
|
|
Code: |
// lcd5453.c --
// Routines to display numbers on the 4 1/2 digit LCD
// that is driven by the National MM5453 LCD driver chip.
//--------------------------------------------
// Display a number from 0 to 9999 on the LCD.
void display_number_on_lcd(int16 value)
{
bin2seg(value, gca_lcd_segment_data);
send_lcd_data(gca_lcd_segment_data);
}
//------------------------------------------
// Display "----" on the LCD.
void display_dashes_on_lcd(void)
{
gca_lcd_segment_data[3] = DASH_SEGMENT_CODE;
gca_lcd_segment_data[2] = DASH_SEGMENT_CODE;
gca_lcd_segment_data[1] = DASH_SEGMENT_CODE;
gca_lcd_segment_data[0] = DASH_SEGMENT_CODE;
send_lcd_data(gca_lcd_segment_data);
}
//------------------------------------------
// Display "OFF" on the LCD.
void display_OFF_on_lcd(void)
{
gca_lcd_segment_data[3] = O_SEGMENT_CODE;
gca_lcd_segment_data[2] = F_SEGMENT_CODE;
gca_lcd_segment_data[1] = F_SEGMENT_CODE;
gca_lcd_segment_data[0] = BLANK_SEGMENT_CODE;
send_lcd_data(gca_lcd_segment_data);
}
//-----------------------------------------
// Clear LCD shift register.
void init_lcd(void)
{
send_zero_bits_to_lcd_driver(40);
}
//-------------------------------------
// Convert a 16-bit value, from 0 to 9999
// to the 4 bytes of segment data necessary
// to display the value on the LCD, in decimal.
// This routine uses subtraction instead of
// division, in order to save ROM space.
void bin2seg(int16 value, char *gca_lcd_segment_data)
{
char digit;
char leading_zeros;
// Do a range check.
if(value > 9999)
value = 9999;
leading_zeros = 0;
// Do the 1000's digit.
digit = 0;
while(value >= 1000)
{
value -= 1000;
digit++;
}
gca_lcd_segment_data[3] = gca_numeric_segment_codes[digit];
// Check if we need to suppress a leading zero for the 2nd digit.
if(digit == 0)
{
leading_zeros++;
gca_lcd_segment_data[3] = BLANK_SEGMENT_CODE;
}
// Do the 100's digit.
digit = 0;
while(value >= 100)
{
value -= 100;
digit++;
}
gca_lcd_segment_data[2] = gca_numeric_segment_codes[digit];
// Check if we need to suppress a leading zero for the 2nd digit.
if(digit == 0)
leading_zeros++;
if(leading_zeros == 2)
gca_lcd_segment_data[2] = BLANK_SEGMENT_CODE;
// Do the 10's digit.
digit = 0;
while(value >= 10)
{
value -= 10;
digit++;
}
gca_lcd_segment_data[1] = gca_numeric_segment_codes[digit];
// Check if we need to suppress a leading zero for the 3rd digit.
if(digit == 0)
leading_zeros++;
if(leading_zeros == 3)
gca_lcd_segment_data[1] = BLANK_SEGMENT_CODE;
// Do the 1's digit.
gca_lcd_segment_data[0] = gca_numeric_segment_codes[value];
}
//-------------------------------------
// This function translates segment data so that
// it fits the actual board layout. Ie., the circuit
// board connects between the MM5453 lcd driver chip
// and the LCD may have been wired to produce the
// best layout, but are not wired in the proper order.
// This routine fixes that.
// The data array, which consists of 5 bytes, holds
// the 33 bits of data which is shifted out to the
// MM5453 chip. The data is shifted out lsb-first.
// Ie., bit 0 of byte 0 goes first, and bit 0 of byte 4
// goes out last. (That's 4 x 8, +1 = 33 bits).
// We need 5 bytes in the output array because we have
// 33 bits that have to be shifted out.
// The data, before it's remapped, is ordered with
// 7 segments per byte (using bits 0-6), with byte 0
// of the input array corresponding to the LSB digit
// on the LCD. Bit 7 of each byte is 0.
void remap_lcd_data(char *segment_data)
{
// Zero the output array.
gca_output_data[0] = 0;
gca_output_data[1] = 0;
gca_output_data[2] = 0;
gca_output_data[3] = 0;
gca_output_data[4] = 0;
// This is the mapping for the Rev 2 board.
if(bit_test(segment_data[0], 0)) // Segment 1G
bit_set(gca_output_data[0], 6);
if(bit_test(segment_data[0], 1)) // 1F
bit_set(gca_output_data[0], 4);
if(bit_test(segment_data[0], 2)) // 1E
bit_set(gca_output_data[0], 7);
if(bit_test(segment_data[0], 3)) // 1D
bit_set(gca_output_data[0], 1);
if(bit_test(segment_data[0], 4)) // 1C
bit_set(gca_output_data[0], 5);
if(bit_test(segment_data[0], 5)) // 1B
bit_set(gca_output_data[0], 3);
if(bit_test(segment_data[0], 6)) // 1A
bit_set(gca_output_data[0], 2);
if(bit_test(segment_data[1], 0)) // Segment 2G
bit_set(gca_output_data[1], 4);
if(bit_test(segment_data[1], 1)) // 2F
bit_set(gca_output_data[1], 2);
if(bit_test(segment_data[1], 2)) // 2E
bit_set(gca_output_data[1], 5);
if(bit_test(segment_data[1], 3)) // 2D
bit_set(gca_output_data[1], 3);
if(bit_test(segment_data[1], 4)) // 2C
bit_set(gca_output_data[1], 1);
if(bit_test(segment_data[1], 5)) // 2B
bit_set(gca_output_data[0], 0);
if(bit_test(segment_data[1], 6)) // 2A
bit_set(gca_output_data[1], 0);
if(bit_test(segment_data[2], 0)) // Segment 3G
bit_set(gca_output_data[2], 4);
if(bit_test(segment_data[2], 1)) // 3F
bit_set(gca_output_data[2], 2);
if(bit_test(segment_data[2], 2)) // 3E
bit_set(gca_output_data[2], 3);
if(bit_test(segment_data[2], 3)) // 3D
bit_set(gca_output_data[2], 1);
if(bit_test(segment_data[2], 4)) // 3C
bit_set(gca_output_data[1], 7);
if(bit_test(segment_data[2], 5)) // 3B
bit_set(gca_output_data[1], 6);
if(bit_test(segment_data[2], 6)) // 3A
bit_set(gca_output_data[2], 0);
if(bit_test(segment_data[3], 0)) // Segment 4G
bit_set(gca_output_data[3], 4);
if(bit_test(segment_data[3], 1)) // 4F
bit_set(gca_output_data[3], 2);
if(bit_test(segment_data[3], 2)) // 4E
bit_set(gca_output_data[3], 1);
if(bit_test(segment_data[3], 3)) // 4D
bit_set(gca_output_data[2], 7);
if(bit_test(segment_data[3], 4)) // 4C
bit_set(gca_output_data[2], 5);
if(bit_test(segment_data[3], 5)) // 4B
bit_set(gca_output_data[2], 6);
if(bit_test(segment_data[3], 6)) // 4A
bit_set(gca_output_data[3], 0);
// These are the 3 decimal points and colon.
bit_clear(gca_output_data[3], 3); // 4DP
bit_clear(gca_output_data[3], 5); // 3DP
bit_clear(gca_output_data[3], 7); // 2DP
bit_clear(gca_output_data[4], 0); // COLON
bit_clear(gca_output_data[3], 6); // NC
}
//-------------------------------------
void send_lcd_data(char *lcd_segment_data)
{
char value;
char digit;
char segment;
// Rearrange the segment data so that it fits
// the way the PCB board is actually wired
// (between the LCD and the LCD driver chip).
remap_lcd_data(lcd_segment_data);
// Send the start bit.
output_high(SDATA_PIN_A0);
lcd_clock_pulse();
// Send 32 bits in the first 4 bytes of the output array.
for(digit = 0; digit < NUM_LCD_DIGITS; digit++)
{
value = gca_output_data[digit];
for(segment = 0; segment < 8; segment++)
{
if(value & 0x01)
output_high(SDATA_PIN_A0);
else
output_low(SDATA_PIN_A0);
lcd_clock_pulse();
value >>= 1;
}
}
// Send the 33rd bit (the final one).
if(gca_output_data[4] & 0x01)
output_high(SDATA_PIN_A0);
else
output_low(SDATA_PIN_A0);
lcd_clock_pulse();
// Send out 2 more clock pulses after that, with data low, to
// finish up the sequence. See MM5453 data sheet for details.
output_low(SDATA_PIN_A0);
lcd_clock_pulse();
lcd_clock_pulse();
}
//--------------------------------------------------
void send_zero_bits_to_lcd_driver(char count)
{
char i;
output_low(SDATA_PIN_A0); // Set data low
for(i = 0; i < count; i++)
lcd_clock_pulse();
}
//-------------------------------------------------
void lcd_clock_pulse(void)
{
output_high(SCLK_PIN_A3); // Positive clock pulse
output_low(SCLK_PIN_A3);
} |
Code: | // lcd5453.h
// 16F628 pins
#define SDATA_PIN_A0 PIN_A0
#define SCLK_PIN_A3 PIN_A3
#define NUM_LCD_DIGITS 4
#define NUM_LCD_SEGMENTS_PER_DIGIT 7
// This table translates numbers 0-9 into their segment codes.
// These codes are sent to the LCD to display the corresponding
// number, 0-9. In each code byte, a "1" bit indicates a segment
// which is lit up (ie. displayed). Example: The number zero
// uses segments A-F, which is coded as 0x3F. Six segments are
// lit up to display it.
// Bit numbers assigned to segments:
//
// 6
// -----
// 1 | | 5
// | 0 |
// -----
// 2 | | 4
// | |
// -----
// 3
char const gca_numeric_segment_codes[10] =
{0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B};
// 0 1 2 3 4 5 6 7 8 9
// Dash code, used to display "----"
#define DASH_SEGMENT_CODE 0x01
// Blank
#define BLANK_SEGMENT_CODE 0x00
// Various letters
#define A_SEGMENT_CODE 0xF7
#define u_SEGMENT_CODE 0x1c
#define t_SEGMENT_CODE 0x0F
#define o_SEGMENT_CODE 0x1d
#define F_SEGMENT_CODE 0x47
#define O_SEGMENT_CODE 0x7E
//--------------------------------------------
// GLOBALS
char gca_lcd_segment_data[NUM_LCD_DIGITS];
char gca_output_data[NUM_LCD_DIGITS +1];
//--------------------------------------------
// FUNCTION PROTOTYPES
void init_lcd(void);
void clear_lcd(void);
void remap_lcd_data(char *segment_data);
void display_number_on_lcd(int16 value);
void display_dashes_on_lcd(void);
void display_OFF_on_lcd(void);
void send_lcd_data(char *lcd_segment_data);
void bin2seg(int16 value, char *gca_lcd_segment_data);
void send_zero_bits_to_lcd_driver(char count);
void lcd_clock_pulse(void);
// End of File |
// Example of how to use the routines:
Code: | main()
{
int16 rpm;
// Init the LCD output pins.
output_low(SDATA_PIN_A0); // Output -- SDATA to LCD driver chip
output_low(SCLK_PIN_A3); // Output -- SCLK to LCD driver chip
// To display a number on the LCD, do this:
rpm = 5000; // Display 5000
display_number_on_lcd(rpm);
delay_ms(1000);
// To display pre-defined text on the LCD, call the appropriate routine.
display_OFF_on_lcd();
while(1);
} |
Last edited by PCM programmer on Mon Nov 24, 2003 2:17 pm; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
Testicky
Joined: 22 Nov 2003 Posts: 12 Location: South Africa / Taiwan
|
THANK YOU VERY MUCH |
Posted: Mon Nov 24, 2003 2:04 pm |
|
|
Your code is so nicely done and commented.
I will get this going in the morning.
Thank you again for your help.
Jacques _________________ Testicky |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|