Beginners: please read this post and this post before posting to the forum.
0 Members and 1 Guest are viewing this topic.
I noticed in the datasheet when I was building it that the LCD has a duty cycle of 1/16. I'm not sure what that means (1/16th of what? What time scale? LCD being on, or the controller to change the display?)
/***************************************************************************** File: lcd.c* Date: 05/3/2010* Auth: K. Loux****************************************************************************/// Local headers#include "lcd.h"#include "utilities.h"// Initialization function for the LCD display// After calling this function, text can be sent to the displayvoid init_lcd(void){ // Configure the required ports as outputs CTRL_DDR |= (1 << READ_WRITE) | (1 << REG_SELECT) | (1 << ENABLE); DATA_DDR = 0xFF; // Initialize outputs to OFF CTRL_PORT &= ~((1 << READ_WRITE) | (1 << REG_SELECT) | (1 << ENABLE)); DATA_PORT = 0x00; // =============== Begin display start-up sequence =============== SET_BIT_LOW( CTRL_PORT, ENABLE ); _delay_ms(45);// Wait >40 msec after power is applied lcd_init_cmd(0x30, 8000); // Command 0x30 = Wake up (wait >5 msec) lcd_init_cmd(0x30, 200); // Command 0x30 = Wake up #2 (wait >160 usec) lcd_init_cmd(0x30, 200); // Command 0x30 = Wake up #3 (wait >160 usec) // Configure LCD display lcd_cmd(0x38); //Function set: 8-bit/2-line/5x8 pixel characters lcd_cmd(0x10); //Set cursor lcd_cmd(0x0c); //Display ON; Cursor OFF lcd_cmd(0x06); //Entry mode set // Clear the screen and return home lcd_clear(); return;}// Sends a command to the lcd display, but pauses for the specified interval// (in usec) instead of checking for the busy flagvoid lcd_init_cmd(char i, double delay){ // Put the data on the port DATA_PORT = i; // Select "instruction mode" and "write mode" CTRL_PORT &= ~((1 << REG_SELECT) | (1 << READ_WRITE)); // Create falling edge on enable pin SET_BIT_HIGH( CTRL_PORT, ENABLE ); _delay_us(1); SET_BIT_LOW( CTRL_PORT, ENABLE ); // Delay the specified number of usec _delay_us(delay); return;}// Sends a command to the lcd display (register select is low)// Waits for busy flag to drop before continuingvoid lcd_cmd(char i){ // Put the data on the port DATA_PORT = i; // Select "instruction mode" and "write mode" CTRL_PORT &= ~((1 << REG_SELECT) | (1 << READ_WRITE)); // Create falling edge on enable pin SET_BIT_HIGH( CTRL_PORT, ENABLE ); _delay_us(1); SET_BIT_LOW( CTRL_PORT, ENABLE ); // Pause to allow command to process wait_for_lcd(); return;}// Sends data to the lcd display (register select is high)void lcd_data(char i){ // Put the data on the port DATA_PORT = i; // Select "data mode" SET_BIT_HIGH( CTRL_PORT, REG_SELECT ); // Select "write mode" SET_BIT_LOW( CTRL_PORT, READ_WRITE ); // Create falling edge on enable pin SET_BIT_HIGH( CTRL_PORT, ENABLE ); _delay_us(1); SET_BIT_LOW( CTRL_PORT, ENABLE ); // Pause to allow command to process wait_for_lcd(); return;}// Prints null terminated strings to the LCD display// Calls lcd_data() to write each charactervoid lcd_string(const char *s){ const int max_len = 32;// 16x2 display can hold maximum of 32 characters unsigned int i = 0; // Parse the string, adding each character to the display while (i < max_len && s[i] != '\0') { // Print the next character lcd_data(s[i]); // Increment the index i++; } return;}// Clears the lcd screen and returns homevoid lcd_clear(void){ lcd_cmd(0x01); // Clear the screen lcd_cmd(0x02); // Return home // Pause to allow the command to complete wait_for_lcd(); // Wait for another 2 msec // FIXME: Not sure why this is needed, but without it, text is jumbled _delay_ms(2); return;}// Checks to see if the LCD has finished processing the previous command// Returns 0 for not busy and 1 for busy// Returns 0 when busy flag is not available during start-up, toounsigned char lcd_busy(void){ // Set the data port to input DATA_DDR = 0x00; DATA_PORT = 0x00; // Select "instruction mode" SET_BIT_LOW( CTRL_PORT, REG_SELECT ); // Select "read mode" SET_BIT_HIGH( CTRL_PORT, READ_WRITE ); // Create falling edge on enable pin SET_BIT_HIGH( CTRL_PORT, ENABLE ); _delay_us(1); SET_BIT_LOW( CTRL_PORT, ENABLE ); // The MSB on the data port is the busy flag int busy = (DATA_PORT >> 7); // Set the data port back to output DATA_DDR = 0xff; return busy;}void lcd_hex(unsigned char i){ unsigned char h, l; h = i / 16; l = i - h * 16; lcd_string("0x\0"); lcd_data(char_to_hex(h)); lcd_data(char_to_hex(l)); return;}// Puts cursor on second linevoid lcd_newline(void){ // Send the command to move the cursor to the next line lcd_cmd(0xC0); return;}char char_to_hex(unsigned char i){ switch (i) { case 0: return '0'; break; case 1: return '1'; break; case 2: return '2'; break; case 3: return '3'; break; case 4: return '4'; break; case 5: return '5'; break; case 6: return '6'; break; case 7: return '7'; break; case 8: return '8'; break; case 9: return '9'; break; case 10: return 'A'; break; case 11: return 'B'; break; case 12: return 'C'; break; case 13: return 'D'; break; case 14: return 'E'; break; case 15: return 'F'; break; } return 'X';}// Waits for the LCD to not be busy (examines busy flag)void wait_for_lcd(void){ while (lcd_busy()) _delay_us(50); return;}
void update_clock_display(void){ // Talk to the DS1307 and get the current time TIME_STRUCT time; unsigned char error; error = get_clock_time(&time); // Update the global seconds variable m_seconds = time.sec; ... // some stuff removed for brevity // create XXX_string variables, null terminated, representing hours, min, sec, etc. ... // Clear the LCD display lcd_clear(); // Update the display with the current time lcd_string(hour_string); lcd_data(':'); lcd_string(min_string); lcd_data(':'); lcd_string(sec_string); lcd_data(' '); if (time.am) lcd_string("AM \0"); else lcd_string("PM \0"); send_time_zone_string(time_zone); // Second line lcd_newline(); send_dotw_string(time.dotw); lcd_data(' '); send_month_string(time.month); lcd_data(' '); lcd_string(day_string); lcd_string(", \0"); lcd_string(year_string); return;}
You didn't change anything in the code after it ran?