1
votes

I'm trying to get an arduino running C Code for a LCD display. Compiling and transmitting and executing C code works fine, tried some LED flashing. All wires should be OK too, when using the 'native' Arduino Library for LCD displays, everything works great, so it must be a code error I can't find :(

I'm trying to communicate with the LCD via 4 data-wire mode. Control and data pins are on the same port.

Here's the code:

//CPU-Clock Frequency
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

// Definitions:

#define LED_PIN PB5 //PB5 = Arduino Pin 13 (with LED)

#define COMPARE_REG OCR0A
#define TIMER_PIN OC0A
#define TIMER_CONTROL_REGISTER TCCR0A

#define LCD_PORT PORTD
#define LCD_PORTDIR DDRD
//controlpins:
#define RS_PIN PD0
#define RW_PIN PD1
#define ENABLE_PIN PD2
//datapins:
#define DB_7 PD7
#define DB_6 PD6
#define DB_5 PD5
#define DB_4 PD4

//Defined command parameters
#define CLEAR 0x01

// Methods
void sleep(uint16_t sleepTime){
for(;sleepTime>0;sleepTime--){ _delay_ms(1);}
}
void lcd_enable(){
LCD_PORT |= (1<<ENABLE_PIN);
//TODO: wait for busy?
sleep(5);
LCD_PORT &= !(1<<ENABLE_PIN);
sleep(5);
}

void lcd_pushOut(unsigned int data){
LCD_PORT &= (0x0F);
LCD_PORT |= (data & 0xF0);
lcd_enable();
LCD_PORT &= (0x0F);
LCD_PORT |= (data & 0x0F) << 4;
lcd_enable();
}

void lcd_command(unsigned int command){
unsigned short int tmp = (LCD_PORT & 0x0F); //speichere alte Steuerleitungen
LCD_PORT &= !(1<<RS_PIN);
lcd_pushOut(command);
LCD_PORT |= (1<<RS_PIN);
LCD_PORT |= tmp; //setze Steuerleitungen zurück
}

void lcd_init(){
sleep(15); //wait for LCD init
LCD_PORTDIR = 0xFF; //make port of LCD output.
LCD_PORT &= !(1<<RW_PIN); //write, dont read.
LCD_PORT |= (3<<4); //write '3' to port.
LCD_PORT &= !(1<<RS_PIN); //we give commands, not data!
lcd_enable();
sleep(1);
lcd_enable(); //write '3' to port 2nd time.
LCD_PORT &= 0x0F; //behalte steuersignale bei, setze daten'port' zurück.
LCD_PORT |= (2<<4); //write '2' to port.
lcd_enable();
//from now on LCD is in 4 bit mode.
lcd_pushOut(0x28); // 4 bit, 5x7 pix, 2 line mode
lcd_pushOut(0x06); //cursor rückt weiter, display scrollt
lcd_pushOut(0x0F); //display ein, cursor aus, blinken aus
lcd_pushOut(0x80); //we will write to DDRAM
lcd_pushOut(0x01); //clear display
//begin test writing zeroes.

LCD_PORT |= (1<<RS_PIN); //give data, not commands!
}

void timer_init(){
//DDRA |= (1<<TIMER_PIN); //make timerpin output.
TIMER_CONTROL_REGISTER = 0b10000000; //set timerpin high @bottom, on compare match clear. (0x80)
COMPARE_REG = 256/2; // dutycycle= 50%
}

void setTimerPower(unsigned int percent){   //set PWM Output (high) in %
COMPARE_REG = (percent/100) * 256;
}

int main (void)
{
//INIT
lcd_init();
//timer_init();
while(1){
lcd_command(CLEAR);
}
//now ready to write! let's write 3 zeroes!
lcd_pushOut('0');
lcd_pushOut('0');
lcd_pushOut('0');
/*
sleep(5000);
char c = '0';
while (1) {
lcd_clear();
lcd_pushOut(c++);
sleep(969); // 3x lcd_enable + 1 ms bearbeitungszeit? ... ziemlich großzügig
if(c > 0x7A) //entspricht c > 'z'
c='0';
}
*/
return 0;
}

EDIT: most of the time, LCD just makes black squares all over the first line.

1
You should include your code in your question instead of in a link.skrrgwasme

1 Answers

4
votes

All instances of !(1<<BIT_NUMBER) should be converted to ~(1<<BIT_NUMBER) as ! is a boolean NOT and you're essentially doing !(true) so you get 0 as a result.

Example showing the problem (on x86):

int main( int argc, char* argv[] )
{
    printf( "%8.8X %8.8X\n", !(1<<2), ~(1<<2) );
    return 0;
}

And output is:

00000000 FFFFFFFB

Change that and you'll at least be further ahead. You should also state which controller is on the LCD to help any further.