Martin George

SPI to HC595 and LCD

Discussion created by Martin George on Mar 16, 2006
Latest reply on Mar 17, 2006 by Mark Hotchkiss
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.
#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
    c = EN; // Write 
 PTT = c; // Tell LCD command or display
 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*/
 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