Hi Freaks,
I have limped along to a project that uses an HD44780 LCD and M48 with 8MHz external crystal. I am trying to display time on my LCD. I am starting with the seconds display to see if it works. The LCD code is Johann's code. Here is the program:
#include#include #include #include volatile unsigned char seconds,minutes,hours,days,months,years; #define LCD_DATA_PORT PORTD #define LCD_DATA_DDR DDRD /* Here are some defines for the control connections * (RS, R/W and E on the LCD display module). These can be wired * to any pins on any port A..D (all to the same port though). * You need to alter these to fit your wire up of your display. */ #define LCD_CTRL_PORT PORTD #define LCD_CTRL_DDR DDRD #define LCD_RS PD0 //2 #define LCD_RW PD1//3 #define LCD_E PD2//4 #define LCD_FUNCTION_SET 0x38 // 0b00110000 #define LCD_FUNCTION_SET_4BIT 0x28 // 0b00101000 #define LCD_DISPLAY_OFF 0x08 // 0b00001000 #define LCD_DISPLAY_ON 0x0F // 0b00001111 #define LCD_DISPLAY_CLEAR 0x01 // 0b00000001 #define LCD_ENTRY_MODE_SET 0x06 // 0b00000110 #define LCD_CURSOR_HOME 0x02 // 0b00000010 volatile unsigned char seconds,minutes,hours,days,months,years; //volatile unsigned char transmit_time[10]; void LcdSendNibble( uint8_t nibble ) { _delay_ms(20); // Output upper nibble on the data ports upper bits LCD_DATA_PORT = (nibble & 0xF0) | (LCD_DATA_PORT & 0x0F); // Toggle the E line LCD_CTRL_PORT |= (1<<LCD_E); // Going up.. LCD_CTRL_PORT &= ~(1<<LCD_E); // ..and down. } void LcdSendByte(uint8_t theByte) { // Send the high nibble LcdSendNibble(theByte); // Shift theByte to get lower nibble in upper part... theByte = theByte << 4; // ...and send it LcdSendNibble(theByte); } void LcdSendInstruction( uint8_t theInstruction ) { // RS low for instructions LCD_CTRL_PORT &= ~(1<<LCD_RS); // Send the instruction LcdSendByte(theInstruction); } void LcdSendCharacter(uint8_t theChar) { // RS high for characters to display LCD_CTRL_PORT |= (1<<LCD_RS); // Send the command LcdSendByte(theChar); } void LcdInitialize(void) { // initialize LCD control lines LCD_CTRL_PORT &= ~(1<<LCD_RS); // RS low LCD_CTRL_PORT &= ~(1<<LCD_RW); // R/W low LCD_CTRL_PORT &= ~(1<<LCD_E); // E low // initialize LCD control lines to output LCD_CTRL_DDR |= (1<<LCD_RS); LCD_CTRL_DDR |= (1<<LCD_RW); LCD_CTRL_DDR |= (1<<LCD_E); // initialize LCD data port to input LCD_DATA_DDR |= 0xF0; // Data on high four bits of port for now... _delay_ms(15); LcdSendNibble( LCD_FUNCTION_SET ); _delay_ms(5); LcdSendNibble( LCD_FUNCTION_SET ); _delay_us(100); LcdSendNibble( LCD_FUNCTION_SET ); // Now, still in 8-bit mode, set the display to 4-bit mode LcdSendNibble( LCD_FUNCTION_SET_4BIT ); // We are now in 4-bit mode. // Do the rest of the init sequence. LcdSendInstruction( LCD_FUNCTION_SET_4BIT ); _delay_ms(500); LcdSendInstruction( LCD_DISPLAY_OFF ); _delay_ms(500); LcdSendInstruction( LCD_DISPLAY_CLEAR ); _delay_ms(500); LcdSendInstruction( LCD_ENTRY_MODE_SET ); _delay_ms(500); LcdSendInstruction( LCD_DISPLAY_ON ); _delay_ms(500); } void timer_init() { TIMSK1 |= (1 << OCIE1A); //enable channel 1A interrupt sei(); //enable global interrupts TCCR1B |= (1 << CS12) | (0 << CS10) | ( 0 << CS11); //start timer at Fcpu/256 TCCR1B |= (1 << WGM12);//set up for CTC mode OCR1A = 2000; //Value that the micro will compare with current count; THIS HAS BEEN ADJUSTED FOR M48 WITH external 8MHz crystal with NO CAP FOR A BREADBOARD } void rtc_op() { seconds++; PORTB ^= (1 << PB0); LcdSendCharacter(seconds); LcdSendInstruction(LCD_CURSOR_HOME); if (seconds == 60) { seconds = 0; minutes++; } if (minutes == 60) { minutes=0; hours++; } if(hours == 24) { hours = 0; days++; } } void go_to_sleep() { sleep_cpu(); } int main(void) { DDRB = 0xFF; LcdInitialize(); timer_init(); for(;;) { } return 0; } ISR(TIMER1_COMPA_vect) { rtc_op(); }
I have an LED on PB0 pin for troubleshooting. The LED is blinking at 1s intervals.
Here is what I see on the LCD:
When I turn the power on, the LCD starts before the LED.
Then from 0 - 9 blinks, there is one dark cursor block on the first location (upper left) on the LCD. This does not appear to blink. I am also seeing a very faint cursor on the second location which blinks.
Then after 9 counts (which I am measuring based on the LED blinking), the cursor in first position starts blinking but shows a dark block blinking and no numbers. After 9 counts, the same cursor starts showing some random characters like +,/ and so on.
After 9 counts it then shows numbers from 0 - 9 but it shows 2,4,6,8 skipping the odd numbers. Then this cycle repeats.
I am sending chars to the LCD. Do I need to convert this into integers? I understand that I am displaying only numbers from 0-9 with one digit on the LCD, but why do I get this random behavior? Is this an LCD delay issue?
Thanks for any help.