I need some help with this, I am a completely new to programing MCU's but I am trying my best to get this working and I could relay use some help. I am using the Sparkfun Basic 16x2 Character LCD along with a atmega32 MCU. Basically, the bottom row is full with black boxes and I cannot figure out why!

Here is my code:

 * LCD.c
 * Created: 11/29/2014 5:12:36 PM
 *  Author: John August

#define F_CPU 16000000UL // 16 MHz clock speed
#include <avr/io.h>
#include <util/delay.h>

// Define LCD I/O Pins (8 Bit Mode)

// Define LCD Command Pins
#define RS PINC7 // Register Select
#define RW PINC6 // Read = 1 and Write = 0
#define EN PINC5 // Enable 

void isBusy_LCD(void);
void Awaken_LCD(void);
void Send_CMD (unsigned char command);
void Send_CHAR (unsigned char character);

int main(void)
LCD_CMD_DDR |= 1<<RS | 1<<RW | EN<<1; 

Send_CMD(0x01);  // Clear the screen 0x01 = 00000001
Send_CMD(0x38); // Put LCD in 8-bit mode
Send_CMD(0b00001110); // Control Cursor 
Send_CHAR(0x41); // Display "A"


// Check if the LCD is busy
void isBusy_LCD(void)
LCD_CMD |= 1<<RW;
LCD_CMD &= ~1<<RS;

while(LCD_PORT >= 0x80) //D7 is "HIGH" when busy, D7=0b1000000 (check read busy flag)

LCD_PORT_DDR = 0xFF; // 0xFF = 0b11111111

void Awaken_LCD(void)
LCD_CMD |= 1<< EN;
asm volatile ("nop"); // asm = Inline low level assembler
asm volatile ("nop"); // "nop" = NoOperation (for delay)
LCD_CMD &= ~1<<EN;

// Send a command to the LCD
void Send_CMD (unsigned char command)
LCD_PORT = command;
LCD_CMD &= ~(1<<RW); // Set R/W to 0 (write)
LCD_CMD &= ~(1<<EN);  // Set Enable to 0

void Send_CHAR (unsigned char character)
LCD_PORT = character;
LCD_CMD &= ~(1<<RW);  // Set R/W to 0 (write)
LCD_CMD |=  (1<<RS);  // Set Enable to 1

I messed around with the V0 contrast pin, but adjustments will either turn the black boxes "transparent" or turn the whole screen full of black boxes. I think this is a code issue.

Here is a picture of the circuit: LCD Circuit

Basically it follows this schematic. With the exception that I am using port C for RS, RW, and Enable. Port D is for DB0 through DB7 of the LCD.

AVR        LCD
PC7-------> RS
PC6-------> RW
PC5-------> EN

PD0-------> DB0
PD1-------> DB1
PD2-------> DB2
PD3-------> DB3
PD4-------> DB4
PD5-------> DB5
PD6-------> DB6
PD7-------> DB7
  • \$\begingroup\$ I mean, without a wiring diagram, we can't entirely conclude that its a code issue. You don't even state how you have it wired up....but assuming you followed a wiring diagram provided by sparkfun, I'd say its a code issue. \$\endgroup\$
    – Funkyguy
    Commented Nov 30, 2014 at 7:00
  • \$\begingroup\$ Could you specify whether you're connecting to this display with a serial connection vs parallel, or maybe give the part number? (I suppose that could be gleaned from your code, but it would be nice to start with). There are several different 16x2 character displays. \$\endgroup\$
    – krs013
    Commented Nov 30, 2014 at 8:04
  • \$\begingroup\$ You have two lines like LCD_CMD &= ~1<<RS;. Try LCD_CMD &= ~(1<<RS); instead (in isBusy and Awaken). After that, a next step could be adding an LED for some debugging info, or looking with a scope on the lines. \$\endgroup\$
    – user17592
    Commented Nov 30, 2014 at 8:10
  • \$\begingroup\$ Hey guys, I updated my original post with more details. The LCD is the sparkfun.com/products/255 and is based on the HD44780 parallel interface chipset. So I assume that means I am connected parallel. \$\endgroup\$ Commented Nov 30, 2014 at 14:55
  • \$\begingroup\$ Putting all left shifts in parentheses like LCD_CMD &= ~(1<<RS); did not work. Black boxes remain. \$\endgroup\$ Commented Nov 30, 2014 at 15:11

2 Answers 2


Your initialization looks completely wrong. Check some HD44780 datasheet. There is always a follow path for 8-bit mode and 4-bit mode initialization. Remember that you are not allowed to check 'Busy Flag' during the first three operations of initialization.


Is the LCD initialized correctly ? I don't see any initialization commands in your code. Plus check your circuit wiring as Funkguy said in his comment.

The traditional HD44780 LCD (not sure of your model) has to be initialized with some sequence of commands: Function set [Interface, font size, etc], display type, cursor shift, and some other info. Without these commands and the proper delay used the LCD won't work correctly.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.