PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD Display mit HD44780 steuern



Andy1988
22.05.2006, 19:06
Hallo,
ich hab mir so ein 4x27 zeichen LCD von pollin gekauft.
Das ganze angeschlossen und mit Bascom programmiert. Juhu es geht ^^

Nur will ich das ganze gerne in C schrieben.
Ich hab erstmal nur einen der beiden Controller genommen, weil ich den erstmal ans rennen kriegen will. Allerdings funtzt das nicht so wirklich. Entweder bleibt der schwarze Balken auf dem Display oder der text landet irgendwo im RAM (immer an einer anderen Stelle).

Könnt ihr da evtl. mal kurz drübergucken und mir sagen, was da nicht geht?

PS:
Der Code ist aus der nanovm. Hab ihn nur extrahiert und will ihn ein wenig anpassen.

Cybrix
24.05.2006, 12:32
Hast du dir das mal im editor angeguckt da hat man garkeine Lust sich das anzugucken poste das hier mal als Code damit das überscihtlicher ist! dann kann man dir bestimmt auch Helfen!

Gruß Cybrix

Andy1988
24.05.2006, 13:30
OK. Dann ist hier das ganze nochmal mit Code tags ;)


#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>

#include "config.h"
#include "main.h"

#define CLOCK 8000000UL
// quite acurate delay delay by active waiting ...
#define LCD_DELAY_MICROSEC(a) ((a)*CLOCK/6000000)
#define LCD_DELAY_MILLISEC(a) ((a)*CLOCK/6000)

void lcd_delay(unsigned long int ticks);

__asm__ (
"lcd_delay: \n"
" subi r22,lo8(1) \n" // 1 clk
" sbci r23,hi8(1) \n" // 1 clk
" sbci r24,hlo8(1) \n" // 1 clk
" sbci r25,hhi8(1) \n" // 1 clk
" brne lcd_delay \n" // 2 clk
" ret \n"
);


// hitachi hd44780 controller commands
#define LCD_CLEAR 0x01
#define LCD_SET_ENTRY_MODE 0x04
#define LCD_ENTRY_INCR 0x02
#define LCD_ON 0x08
#define LCD_DISPLAY_ON 0x04
#define LCD_DISPLAY 0x08

#define LCD_FUNCTION 0x20
#define LCD_8_BIT 0x10
#define LCD_DOUBLE 0x08
#define LCD_SET_DISP_ADDR 0x80

#define LCD_BUSY 0x80

int main(void)
{
_delay_ms(100);

lcd_init();

lcd_print("Hallo");

while(1)
{
}

return 0;
}


// disable LCD by asserting E
static inline void lcd_enable(void)
{
// enable LCD
LCD_CTRL_PORT |= _BV(LCD_CTRL_E1);
lcd_delay(LCD_DELAY_MICROSEC(10));
}

// disable LCD by deasserting E
static inline void lcd_disable(void)
{
LCD_CTRL_PORT &= ~_BV(LCD_CTRL_E1);
lcd_delay(LCD_DELAY_MICROSEC(10));
}

// switch LCD data port to input
static inline void lcd_data_input(void)
{
LCD_DATA_DDR = 0x00; // data lines are input
LCD_DATA_PORT = 0xff; // enable pull-ups
}

// access LCD by enabling and disabling E
static inline void lcd_write(unsigned char data)
{
LCD_CTRL_PORT &= ~_BV(LCD_CTRL_RW); // write

LCD_DATA_DDR = 0xFF; // set data I/O lines to output (8bit)
LCD_DATA_PORT = data; // output data, 8bits

lcd_enable();
lcd_disable();
lcd_data_input();
}

static void lcd_wait_while_busy(void)
{
// wait until LCD busy bit goes to zero
LCD_CTRL_PORT &= ~_BV(LCD_CTRL_RS); // ctrl access
lcd_data_input();
LCD_CTRL_PORT |= _BV(LCD_CTRL_RW); // read

lcd_enable();

/* wait for BUSY flag to be gone */
while(LCD_DATA_PIN & LCD_BUSY)
{
lcd_disable();
lcd_enable();
}

lcd_disable();
}

// write the control byte to the display controller
static void lcd_write_ctrl(unsigned char data)
{
lcd_wait_while_busy();

LCD_CTRL_PORT &= ~_BV(LCD_CTRL_RS); // ctrl access

lcd_write(data);
}

// write a data byte to the display
static void lcd_write_data(unsigned char data)
{
lcd_wait_while_busy();

LCD_CTRL_PORT |= _BV(LCD_CTRL_RS); // data access

lcd_write(data);
}

//Init lcd
void lcd_init(void)
{
// Controller 1
{
// make the three control lines outputs
LCD_CTRL_PORT &= ~(_BV(LCD_CTRL_RS) | _BV(LCD_CTRL_RW) | _BV(LCD_CTRL_E1) | _BV(LCD_CTRL_E2)); //everything to low
LCD_CTRL_DDR |= (_BV(LCD_CTRL_RS) | _BV(LCD_CTRL_RW) | _BV(LCD_CTRL_E1) | _BV(LCD_CTRL_E2)); //everything outgoing ports

// don't drive data lines
lcd_data_input();

// writing three times the config byte makes sure, that
// the interface is in 8 bit mode afterwards
lcd_write_ctrl(LCD_FUNCTION | LCD_8_BIT | LCD_DOUBLE);
lcd_write_ctrl(LCD_FUNCTION | LCD_8_BIT | LCD_DOUBLE);
lcd_write_ctrl(LCD_FUNCTION | LCD_8_BIT | LCD_DOUBLE);

lcd_write_ctrl(LCD_ON | LCD_DISPLAY_ON);
lcd_write_ctrl(LCD_SET_ENTRY_MODE | LCD_ENTRY_INCR);
}
}

//prints text to display
static void lcd_print(char *str)
{
while(*str)
lcd_write_data(*str++);
}

SprinterSB
24.05.2006, 16:43
Wo wird denn zB LCD_CTRL_PORT gesetzt?

Andy1988
25.05.2006, 18:01
Das wird in der config.h gesetzt:

#ifndef CONFIG_H
#define CONFIG_H

#define LCD_VIRTUAL_LINE_LENGTH 40 // byte offset between one line and the next
#define LCD_CTRL_PORT PORTC
#define LCD_CTRL_DDR DDRC
#define LCD_DATA_PORT PORTA
#define LCD_DATA_DDR DDRA
#define LCD_DATA_PIN PINA
#define LCD_CTRL_RS 0
#define LCD_CTRL_RW 3
#define LCD_CTRL_E1 1
#define LCD_CTRL_E2 2

#endif


Die Software geht ja. Ich kann Texte darstellen, aber die landen irgendwo im RAM. Ist ganz komisch irgendwie.
Oder muss ich den Address Pointer jedes mal auf eine bestimmte Stelle setzen?