PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD routinen in C



_maddin
28.01.2007, 18:42
nabend
ich hab den halben tag damit verbracht, die AssemblerLCDroutinen von mikrocontroller.net in C zu "übersetzen". das klingt vllt blödsinnig, aber ich möchte keine vorgefertigten funktionen nehmen, um das ganze besser zu verstehen. ich weiß, das programm was ich geschrieben hab, ist programmiertechnisch ziemlicher schrott, aber ich versteh einfach nicht, wieso es nicht funktioniert. hängt es damit zusammen, wie ich die nibbles "vertausche" (ich versteh nich ganz wie das mit dem inline assembler läuft, deshalbt hab ich mir diese "methode" ausgedacht)
kann mir irgendjemand helfen ???
MfG maddin



#include <avr/io.h>
//EVALUATION BOARD
#define Taster1 2
#define Taster2 3
#define Taster3 4
#define LED1 5
#define LED2 6
//LCD
#define LCD_PORT PORTB
#define LCD_E 5
#define LCD_RS 4

#define LCD_CLEAR 0b00000001
//

//Prototypen
void delay_ms(unsigned int);
void io_init(void);
//LCD
void lcd_data(unsigned char);
void lcd_command(unsigned char);
void lcd_enable(void);
void lcd_init(void);
void lcd_clear(void);

//

//
void main(void) {
ioinit();
lcd_init();
lcd_data("T");
lcd_data("e");
lcd_data("s");
lcd_data("t");
}
}


// Initialisierung
void ioinit(void){//0EINGANG 1AUSGANG
DDRD=0b11100011;
DDRB=0b00111111;
}

void delay_ms(unsigned int ms){
unsigned int zaehler;

while (ms) {
zaehler = F_CPU / 5000;

while (zaehler) {
asm volatile("nop");
zaehler--;
}
ms--;
}
}


void lcd_init(){
LCD_PORT=0xFF;
delay_ms(31);
LCD_PORT=0b00000011;//zur initialisierung
lcd_enable();
delay_ms(5);
lcd_enable();
delay_ms(5);
lcd_enable();
delay_ms(5);
LCD_PORT=0b00000010;//4bit
lcd_enable();
delay_ms(5);
lcd_command(0b00101000);//4bit,2Zeilen
delay_ms(5);
lcd_command(0b00001100);//Display on, Cursor off
delay_ms(5);
lcd_command(0b00000100);
}

void lcd_enable(){
LCD_PORT |= (1 << LCD_E);//1
delay_ms(1);
LCD_PORT &=~(1 << LCD_E);//0
delay_ms(1);
}

void lcd_data(unsigned char data){
unsigned char nibble;
nibble=data/0b00010000; //ersatz für "swap"
LCD_PORT=nibble&&00001111;
LCD_PORT |= (1 << LCD_RS);//1
lcd_enable();
LCD_PORT=data&&00001111;
LCD_PORT |= (1 << LCD_RS);//1
lcd_enable();
delay_ms(1);
}

void lcd_command(unsigned char data){
unsigned char nibble;
nibble=data/0b00010000;
LCD_PORT=nibble&&00001111;
lcd_enable();
LCD_PORT=data&&00001111;
lcd_enable();
delay_ms(1);
}


EDIT verwende 4*20 zeichen, Hitachi HD44irgendwas oder zumindest kompatibel dazu.

izaseba
28.01.2007, 20:07
Hallo, was warteschleifen in C angeht, mußt Du nicht unbedingt was eigenes erfinden, guck mal unter util/delay.h


nibble=data/0b00010000;


data / 16 einfacher zu lesen wäre es mit 4 mal rechts schieben


nibble=data>>4;

Aber der Fehler liegt wohl hier:


LCD_PORT=nibble&&00001111;

&& ist eine logische UND Verknüpfung bitweise UND macht man mit einem &


LCD_PORT=nibble&00001111;


Vielleicht hilft es weiter
Gruß Sebastian

_maddin
28.01.2007, 20:48
vielen dank, habs gleich in die tat umgesetzt, funzt jedoch immer noch nicht.
](*,)

das programm sieht jetzt so aus:



(definitionen......)

//Prototypen
void delay_ms(unsigned int);
void io_init(void);
//LCD
void lcd_data(unsigned char);
void lcd_command(unsigned char);
void lcd_enable(void);
void lcd_init(void);
void lcd_clear(void);

//

//
void main(void) {
ioinit();
lcd_init();
lcd_data("T");
lcd_data("e");
lcd_data("s");
lcd_data("t");
while(1);
}



// Initialisierung
void ioinit(void){//0EINGANG 1AUSGANG
DDRD=0b11100011;
DDRB=0b00111111;
}

void delay_ms(unsigned int ms){
unsigned int zaehler;

while (ms) {
zaehler = F_CPU / 5000;

while (zaehler) {
asm volatile("nop");
zaehler--;
}
ms--;
}
}


void lcd_init(){
LCD_PORT=0xFF;
delay_ms(31);
LCD_PORT=0b00000011;//zur initialisierung
lcd_enable();
delay_ms(5);
lcd_enable();
delay_ms(5);
lcd_enable();
delay_ms(5);
lcd_command(0b00000010);//4bit
lcd_enable();
delay_ms(5);
lcd_command(0b00101000);//4bit,2Zeilen
delay_ms(5);
lcd_command(0b00001100);//Display on, Cursor off
delay_ms(5);
lcd_command(0b00000100);
}

void lcd_enable(){
LCD_PORT |= (1 << LCD_E);//1
delay_ms(1);
LCD_PORT &=~(1 << LCD_E);//0
delay_ms(1);
}

void lcd_data(unsigned char data){
unsigned char nibble;
nibble=data>>4; //ersatz für "swap"
LCD_PORT=nibble&00001111;
LCD_PORT |= (1 << LCD_RS);//1
lcd_enable();
LCD_PORT=data&00001111;
LCD_PORT |= (1 << LCD_RS);//1
lcd_enable();
delay_ms(1);
}

void lcd_command(unsigned char data){
unsigned char nibble;
nibble=data>>4;
LCD_PORT=nibble&00001111;
lcd_enable();
LCD_PORT=data&00001111;
lcd_enable();
delay_ms(1);
}


wenn ich das programm auf den mega32 lade, kommt nur mist raus.
beim compilen kommen diese warnings hier :

ZumExperimentieren.c:44: warning: passing argument 1 of 'lcd_data' makes integer from pointer without a cast
ZumExperimentieren.c:45: warning: passing argument 1 of 'lcd_data'
......

was bedeutet das ???
mfg maddin

izaseba
28.01.2007, 20:57
lcd_data("T");
lcd_data("e");
lcd_data("s");
lcd_data("t");

Geht es sich um diese Zeilen ?

versuch mal 'T' 'e' 's'.....
Du übergibst einen Zeiger an die lcd_data ( steht doch in der Warnung)

Gruß Sebastian

uwegw
28.01.2007, 21:05
welche Zeilen sind das? Die Test-Ausgabe in main?
Wenn du die Zeichen mit " " schreibst, werden sie als String interpretiert, und der Funktion wird ein Zeiger auf diesen String übergeben. Um nur ein einzelnes Zeichen als unsigned char zu übergeben, musst du es mit ' ' schreiben:
lcd_data('T');
lcd_data('e');
lcd_data('s');
lcd_data('t');

_maddin
28.01.2007, 21:06
danke.
so ein mist es funzt immer noch nicht. egal was ich mache es kommt immer das gleiche raus. ich kann sogar enable und rs im programm vertauschen: das LCD zeigt immer den gleichen scheiß an.

izaseba
28.01.2007, 21:21
Wird das Display den richtig initialisiert ?



verwende 4*20 zeichen, Hitachi HD44irgendwas oder zumindest kompatibel dazu.


Darüber ist schon der eine oder andere gestolpert, kompatibel != HDblabla

Stimmen die Pins den überein ? was hast Du mit den Pins gemacht, die Frei sind ? An GND gehängt uder frei ?
Ich hatte schon LCD's , da ging nichts, wenn sie an GND hingen :-k
Hat das ganze denn schon mit asm, basic funktioniert ?



Gruß Sebastian

_maddin
28.01.2007, 21:27
asm und basic funzt.

_maddin
28.01.2007, 21:29
ich idiot hätte lieber 8bit modus wählen sollen das ist für nen anfänger einfacher und im moment hab ich noch nen paar portpins frei.... naja hab jetzt aber keine lust alles noch mal auseinanderzunehmen