SPI to HC595 and LCD

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

SPI to HC595 and LCD

8,181 Views
marti
Contributor I
Hi All,
 
I am attempting to output some measured values of frequency and power factor to an LCD module. I am using a 68hc12c32 with codewarrior, programming in C. I am using SPI to transmit the data (PORT M) and 2 general purpose channels (PORT T) for enable and reset bits. I am trying to shift the data through a hc595 serial to parallel shift register.
I think I may have set up the SPI incorrectly as it does not seem to be operating at all. I am relatively new to both microcontrollers and 'C' programming so have probably made an error somewhere. I have included the code any ideas would be greatly appreciated.
 
Martin
 
/*----Code---*/
#define Slave_Off 0x8 //For setting SS bit
#define CMD 0  // For command mode RST-low, EN-high
#define DISP 1  // For display mode RST-high, EN-high
#define LO 0x0 // Set all Enable and Reset bits low
#define EN 0x4 // Set Enable bit High
#define RST 0x8 // Set reset bit high
#define EN_RST 0xC // Set Enable and Reset bits high

/*--- Port direction and SPI setup ---*/
void SPI_Set(void){
 
 DDRM = 0x38; // Set PortM as output
 DDRT = 0xC;  // Set PortT as output
 SPICR1 = 0x52; // Set SPI control register 1
 SPICR2 = 0x10; // Set SPI control register 2
 PTT = 0; // LCD command mode no operation
 PTM = Slave_Off; // hc595 not listening
 
/*--- Delay Code ---*/
/*--- Needs to be configured to Bus clock, Boot 24Mhz, Run 4Mhz ---*/
 
void Delay(unsigned int sec){
 unsigned int i, j;
 for(i = 0; i < sec; i++){
   for(j = 0; j < 1000; j++){
   }
 }
 
/*-- Routine to send command or character to display --*/
 
void set_lcd(char n, char reg){
 char c;
/* First send the byte to the HC595 */
 PTM &= ~Slave_Off; // Listen up, slave
 SPIDR = n; // Send byte
 while((SPISR & 0x80) == 0); // Wait for SPI ready SPIF interrupt flag
 PTM = Slave_Off; // To HC595, latch it
 /* Now forward it to the LCD */
 if(reg == DISP){ // Command or write?
   c = EN_RST; // Command
   
   }else{
    c = EN; // Write 
   }
 PTT = c; // Tell LCD command or display
 Delay(100);
 PTT = LO; // Tell LCD to do it
 }
 
/*---- Main program ---*/
 
void main(void){
float freq = -50.56; // Abritary number, would come from freq measurement function
float PFactor = -0.75;
char confreq[11];
char conPF[8];
int count;
int len;
SPI_Set(); // Initialize serial port
set_lcd(0x38, CMD); // 8-bit, 2 lines
set_lcd(0x14, CMD); // Disp. on, cursor on, blink
set_lcd(0x6, CMD); // Cursor moves right space each char
/*Display static characters*/
set_lcd(0x46, DISP); // Display F
set_lcd(0x72, DISP); // Display r
set_lcd(0x65, DISP); // Display e
set_lcd(0x71, DISP); // Display q
set_lcd(0x3A, DISP); // Display :
set_lcd(0xC0, CMD); // Go to line 2
set_lcd(0x50, DISP); // Display P
set_lcd(0x46, DISP); // Display F
set_lcd(0x3A, DISP); // Display :

/*Display measured Frequency and Power Factor*/
for(;:smileywink:{
 
 sprintf(confreq, "%.2f Hz", freq); //Convert float freq to character string
 len = strlen(confreq); //String length
 set_lcd(0x86, CMD); //Set cursor position
   for(count = 0; count < len; count++){
   
     set_lcd(confreq[count], DISP); //Send 1 character of string to lcd
   }
 
 
 sprintf(conPF, "%.2f", PFactor); //Convert PFactor to character string
 len = strlen(conPF); //String length
 set_lcd(0xC4, CMD); //Set cursor position
   for(count = 0; count < len; count++){
   
     set_lcd(conPF[count], DISP); //Send 1 character of string to lcd
   }
 }
 
}
Labels (1)
0 Kudos
3 Replies

768 Views
marti
Contributor I

Thanks Mac;

I am indeed using a single S/R in 8 bit mode using SPI with seperate EN and RS connections to the LCD from the MCU. I have possibly got the SPI connections mixed up, at present I have the MOSI conncted to pin 14, SPI CLK connected to pin 11 and SS to pin 13 (Output Enable on the 595). I thought OE was used to latch the data into output of the S/R. You suggest to use pin 12 (master reset on the 595) is that correct as this may be my problem.

Martin

 

0 Kudos

768 Views
rocco
Senior Contributor II
Hi, Martin:

Yes, the 595 is your problem. You are not clocking the shift register into the output register.

OE (sometimes referred to as G) enables the HC595 to drive it's parallel I/O lines. It should be permanently tied low. You need to provide a positive edge on the register-clock pin (RCK, pin 12) after shifting the data into the HC595. This extra step is necessary because the HC595 has an output register in addition to the shift register, which you don't really need.

By the way, a simpler shift register to use would be the HC164, since you would not have to handle the redundant (in your application) holding register. You would tie MOSI to A and B (pins 1 and 2) and SPICLK to CLK (pin 8). You would also want to tie CLR high.
0 Kudos

768 Views
bigmac
Specialist III

Hello Martin,

Firstly I presume you are trying to interface with an alphanumeric LCD (not a graphical one).  I am not entirely clear on the hardware connections you are attempting to use.  So here are some possibilities for the interface between the HC595 and the LCD -

  • Connect display in "four-bit" mode to the HC595, and connect EN and RS also to the same S/R.
  • Connect display in 8-bit  mode to one S/R, and connect EN & RS to a second S/R device.
  • Connect display in 8-bit mode to a single S/R, and use separate output pins from the MCU for EN and RS lines.

I suspect you may be attempting the third method.  In all cases the RW line should be grounded.  For the interface between the MCU and the HC595, the following connections would be required.

HC595
Pin 10  SCLR = High
Pin 11  SCK = SPI CLK
Pin 12  RCK = Strobe - needs to be a separate MCU output.
Pin 13  /G = Low
Pin 14  SER = SPI MOSI

The strobe signal would be pulsed at the completion of each SPI transaction, assuming a single S/R.  The /SS output signal might be used as the strobe signal with a single S/R, because it outputs a positive edge at the conclusion of the transaction.  Either of the following SPI modes should be suitable for the HC595 -

CPHA = 0, CPOL = 0 or
CPHA = 1, CPOL = 1

Before trying to test the operation of the LCD, I would suggest that the SPI operation be separately tested to confirm that the S/R outputs operate in the intended manner.

You will most likely need to allow a sufficient delay for the LCD to power-up, before trying to initialise it - I would tend to allow something like 200 milliseconds.  Also, some LCD commands take much longer to execute than others.

Regards,
Mac

 

 

 

 

0 Kudos