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.