CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

uPD7225 routines

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Testicky



Joined: 22 Nov 2003
Posts: 12
Location: South Africa / Taiwan

View user's profile Send private message Send e-mail Visit poster's website

uPD7225 routines
PostPosted: Mon Nov 24, 2003 12:29 pm     Reply with quote

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
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 24, 2003 12:40 pm     Reply with quote

Can you get the National MM5453 ?
If so, I have a driver for that one.
Testicky



Joined: 22 Nov 2003
Posts: 12
Location: South Africa / Taiwan

View user's profile Send private message Send e-mail Visit poster's website

MM5453
PostPosted: Mon Nov 24, 2003 1:01 pm     Reply with quote

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
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 24, 2003 1:40 pm     Reply with quote

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
Testicky



Joined: 22 Nov 2003
Posts: 12
Location: South Africa / Taiwan

View user's profile Send private message Send e-mail Visit poster's website

THANK YOU VERY MUCH
PostPosted: Mon Nov 24, 2003 2:04 pm     Reply with quote

Your code is so nicely done and commented.
I will get this going in the morning.
Thank you again for your help.

Jacques
_________________
Testicky
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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