Interfacing the LCD on the MCU project board with CSM12C32

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Interfacing the LCD on the MCU project board with CSM12C32

2,913 Views
justinr2
Contributor I
All,

I the Freescale project board (PBMCUSLK) and the CSM12C32 development module. The version of the board I have came populated with an 8x2 LCD display. According to the documentation, it is the DMC-50448N. The interface from the MCU to the LCD is via SPI and an HC595 serial-to-parallel shifter.

There's no documentation for the LCD, other than the pin designations in the user's guide and on the schematic. I've managed to piece together enough to use the SPI to write data to the HC595, and I've found the recommended startup sequence for the LCD. But when I hook it up, nothing happens with the LCD.

The SPI connects to the HC595 and the 8-bit output is connected as:

Q0 LCD_D4
Q1 LCD_D5
Q2 LCD_D6
Q3 LCD_D7
Q4 --
Q5 --
Q6 RS
Q7 EN

the R/W* pin on the LCD is tied low (presumably because this is a write-only connection)

I've stepped through the code (see below), and after each SPI write, the expected values show up on the right pins of the LCD. The sequence I'm going for is:

SPI write the Data and the EN low
SPI write the Data and the EN high
SPI write the Data and the EN low

This should cause the LCD controller to pick up the nibble. But nothing happens with the LCD.

I've looked all over for more documentation, and I haven't found anything. My code is below. If someone has any tips, or can point me to an application note or other documentation for the LCD on the project board, I would be greatful.


#include /* common defines and macros */
#include /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12c32"


#define EN_BIT 0x80

void spiWrite(volatile unsigned char data);
void LCDShortWrite(volatile unsigned char data);
void sleep(unsigned long ms);


void main(void) {

EnableInterrupts;

//set up SPI to write to LCD
//01011110
SPICR1 = 0x5E;
//00010000
SPICR2 = 0x10;
//baud rate = 8 MHz / 640 = 12.5 KHz
//0100 0110
//baud rate = 8 MHz / 8 = 1 MHz
//0111 0000
SPIBR = 0x70;

LCDShortWrite(0x03);
sleep(5);
LCDShortWrite(0x03);
sleep(1);
LCDShortWrite(0x03);
LCDShortWrite(0x02);
//LCDShortWrite(0x08);
//set N and F
LCDShortWrite(0x02);
LCDShortWrite(0x08);
sleep(1);
//set Display OFF
LCDShortWrite(0x00);
LCDShortWrite(0x08);
sleep(1);
//set clear display
LCDShortWrite(0x00);
LCDShortWrite(0x01);
sleep(16);
//set entry mode
LCDShortWrite(0x00);
LCDShortWrite(0x06);
sleep(1);
//set display on (w / cursor and blink)
LCDShortWrite(0x00);
LCDShortWrite(0x0F);

for(;:smileywink: {} /* wait forever */
/* please make sure that you never leave this function */
}

void LCDShortWrite(volatile unsigned char data) {
//unsigned char newdata;

//spiWrite(0x00); //clear en
spiWrite(data & ~EN_BIT);

spiWrite(data | EN_BIT); //set en and data

spiWrite(data & ~EN_BIT); //clear the high bit but leave the data

}

void spiWrite(volatile unsigned char data) {
// unsigned char readval;

while (!(SPISR & 0x20)) { } //wait for SPTEF = 1
SPIDR = data; //write value to data reg

//to receive
//while (!(SPISR & 0x80)) { } //wait for SPIF = 1
//readval = SPIDR; // read value

}

void sleep(unsigned long ms) {
char i;

for (i=0;i
asm {
PSHX
LDX #$640
sleepLoop:
NOP
NOP
DBNE X, sleepLoop
PULX
}
}

}
Labels (1)
0 Kudos
5 Replies

548 Views
bigmac
Specialist III
Hello justinr2,
 
When using the HC595, and following each byte being sent by the SPI, the RCK input at pin 12 is pulsed to transfer the byte to the output latches.  I assume this is occurring, but it is not clear from your code.
 
Have a look at AN1774, where the initialisation sequence for 4-bit data transfer is detailed.
 
Regards,
Mac
 
0 Kudos

548 Views
justinr2
Contributor I
Thank you both for the input. I resolved the issue, so I thought I would post the solution in case someone else has a a similar issue.

The problem turned out to be with the SPI interface to the HC595 chip. The way the HC959 parallel outputs are interfaced with the LCD, 4 bits are data and two bits are the EN and RS inputs. Note that the W*/R is always low (this is a write-only interface). In order to get the LCD to read the data bits, there must be an pulse on the EN line. This requires three successive writes to the HC595 via the SPI interface:

4BDATA = whatever data you want in bits 3:0
ENABLE_BIT = 0x00;

Write:
4BDATA & ~ENABLE_BIT
4BDATA | ENABLE_BIT
4BDATA & ~ENABLE_BIT

This is supposed to create a pulse on enable bit. However, I put a scope on the enable and found that it wasn't being asserted because the SPI writes were coming too close together (basically the first two values were immediately overwritten by the third) so there was no ENABLE pulse.

By inserting a 100us delay after every SPI write, I solve the problem.

Hope this helps anyone who has similar problems.
0 Kudos

548 Views
peg
Senior Contributor IV
Hi Justin,
You may have got it to work, but I believe you may have mis-interpreted the reason.
I use BSET, BCLR on adjacent lines in assembler to toggle E successfully. (With a direct connected LCD)
You would have E set for an entire byte time of the SPI at least.
Are you sure these lines are not being optimised away without the intervening delays?
Regards
David
 

Message Edited by peg on 2006-09-21 07:52 AM

0 Kudos

548 Views
bigmac
Specialist III
Hello Justin,
 
Further to what Peg has said, if the latch has been initialised so that EN is a low state, when generating a pulse, you do not really need the first of your three operations.  I wonder if its omission might prevent the unintended "optimisation" by the compiler.
 
Regards,
Mac
 
0 Kudos

548 Views
peg
Senior Contributor IV
Hi justin,
 
Your LCD is an Optrex 8 char x 2 line display.
It, like almost all character LCD's uses the de-facto standard Hitachi LSI HD44780 or equivalent.
I have many paper manuals for these so have never looked on the web, but I am sure if you search for the above part number you will find what you need.
The problem is that before you see anything you have to initialise the display with a few setup bytes (or nibbles in your case, this is part of the setup)
There is also some relatively slow timing involved.
You usually make a few functions to write setup bytes and data bytes that include the timing. Then they become fairly easy to use. If you find some code it may be for a direct connection where MCU i/o is connected directly to the display, but using a '595 is also a fairly popular arangement.
 
Hope this helps
Regards David
 
 
0 Kudos