PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD will keine Strings die länger als 3 Zeichen sind ausgebe



Squatmario
13.01.2006, 14:51
Ich benutze einen ATmega 32...mit einer Taktfrequenz von 3,6864 MHz
main.c:


#include<avr/io.h>
#include<avr/delay.h>
#include "lcd.h" // eigene lcd lib getester mit atm16 alle ports



int main (void)
{
char text[]="Keb";
char text2[]="Keb";

init();
boot('.',1,1,1); // zeichen'a' / wie oft0-255 / nur zeile 1 (bug)/ pos spalte 1-24
run(2);
boot('.',1,1,1); // zeichen'a' / wie oft0-255 / pos zeile 1 (bug)/ pos spalte 1-24
run(2);
boot('.',1,1,1); // zeichen'a' / wie oft0-255 / pos zeile 1 (bug)/ pos spalte 1-24
clear(); // löscht aktuelle eingabe / pos 1,1


pos(1,1);
print(text);
//drucken(text, 1,1); // ausgabe string
pos(2,1);
run(20);
//drucken(text, 2,1); // ausgabe string
run(20);


for(;;){ } //endlosschleife

}


lcd.h:


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

#define ddrx DDRA
#define portx PORTA
#define db4 PINA0
#define db5 PINA1
#define db6 PINA2
#define db7 PINA3
#define rs PINA4
#define rw PINA5
#define en PINA6
#define led PINA7


void delay(void); // 3 takte verzvgerung
void delay5ms(void); // 5 ms verzögerung
void enable(void); // erzeugen des enable puls
void buisy(void); // warten bis bereit(nur durch zeitverzvgerung)
void comm(unsigned char comm); // schreibt commando
void data(unsigned char data); // schreibt daten
void init(void); // initialisiert display
void clear(void); // löscht display
void pos(unsigned char l,unsigned char p); // zeile spalte 1/2 1-24
void print(char buffer []); // gibt string aus
void drucken(char buffer2 [],int x,int y);
void boot(unsigned char zeichen,unsigned char zahl
,unsigned char zeile,unsigned char sp);
//zeichen /anzahl durchgänge / zeile / spalte)
void run(char ms100);


// drei takte warten
void delay(void)
{
asm volatile( "nop\n\t"
"nop\n\t"
"nop\n\t"::);}

//enable ein aus
void enable(void)
{
portx |= (1 << en); // setzt bit
delay();
portx &= ~(1 << en); // lvscht Bit
}


void delay5ms(void)
{
// inline asm warteschleife
asm volatile(

"push R16" "\n\t"
"push R17" "\n\t"
"ldi R16, 0x25" "\n\t"
"WGLOOP0:""\n\t" "ldi R17, 0xA5" "\n\t"
"WGLOOP1:""\n\t" "dec R17" "\n\t"
"brne WGLOOP1" "\n\t"
"dec R16" "\n\t"
"brne WGLOOP0" "\n\t"

"pop R16" "\n\t"
"pop R17" "\n\t"::);}





// wartet bis lcd bereit
void buisy(void)
{
_delay_ms(15);

}


// sendet comando --- rs nicht gesetzt

void comm(unsigned char comm)
{
buisy();
unsigned char comm1 = comm;
portx = (0x0f & (comm>>4));
enable();
portx = (0x0f & (comm1));
enable();

}



// sendet daten -- rs gesetzt


void data(unsigned char data)
{
buisy();
unsigned char data1 = data; // daten geseichert
portx = (0x1f & (data>>4)|(1 << rs)); // rechtschieben
enable();
portx = (0x1f & ((data1))|(1 << rs)); // ausgabe sicherung
enable();
}

void init(void){

ddrx = 0xff;
portx = 0xff;

// 15 ms warten

unsigned char d= 10;
do{ --d;
delay5ms();

}while(d != 0 );


// drei mal 8 bit initialisieren
portx = (0b00000011);
enable();
delay5ms();
enable();
delay5ms();
enable();

// 4 bit modus aktivieren
delay5ms();
portx = (0b00000010);
enable();
delay5ms();

// sachen einstellen
comm(0b00101000); //2zeilig 5*8
delay();
comm(0b00001000);
delay();
comm(0b00000001);
delay();
comm(0b00000010);
delay();
comm(0b00001100);
// display lvschen
}



void clear(void)
{
comm(0b00000001);
pos(1,1);
}


void pos(unsigned char l,unsigned char p)
{
unsigned char pos = 0b10000000;
if(l==1){
pos |= p-1;
}
if(l==2){
p =+40;
pos |= p;
}
comm(pos);


}



//
void print(char buffer [])
{
for ( int i = 0; buffer [i] !='\0'; i++)
data(buffer[i]);
}

void boot( unsigned char zeichen,unsigned char zahl,
unsigned char zeile,unsigned char sp)
{
do{
unsigned char spalte= sp;
zahl = zahl-1;
_delay_ms(100);
pos(zeile, spalte);
print(" ");
pos(zeile,spalte);
_delay_ms(100);
data(zeichen);
_delay_ms(100);
data(zeichen);
_delay_ms(100);
data(zeichen);
_delay_ms(100);
data(zeichen);
_delay_ms(100);
data(zeichen);

}while(zahl != 0);

}

void drucken(char buffer2 [],int x,int y)
{
pos(x,y);
int i=0;
while(i<=strlen(buffer2))
{

print(buffer2[i]);
y=y+1;
pos(x,y);
i=i+1;
}
}


/*void drucken(unsigned char *p)
{
do
{
data(*p);
p++;
}
while (*p!='\0');

}
*/

void run(char ms100)
{
unsigned char d= ms100;
do{ --d;
_delay_ms(100);

}while(d != 0 );
portx |= (1 << led); // setzt bit
d= ms100;
do{ --d;
_delay_ms(100);

}while(d != 0 );
portx &= ~(1 << led); // löscht Bit

}


Problem:

Ich kann mit diesem Programm nur Strings die 3 Symbole lang sind ausgeben. Will ich mehr als 3 ausgeben gibt das Display nur Blödsinn aus.
Schreibe ich den Text hingegen direkt in die print funktion hinein gibt er den ganzen Text aus. z.B: print("Test");
Um dem Problem aus dem Weg zu gehen habe ich eine Funktion geschrieben die den String auf dessen einzelnen Symbole aufspalltet und einzel ausgibt.
mit:
char text[5];

text[0]='T';
text[1]='e';
text[2]='s';
text[3]='t';
text[0]='\0';

Habe auch schon versucht den String in die oben stehende Form umgewandelt und dann ausgegeben.
Das führte aber auch zu keinem Ergebnis


EDIT:
Kollege, ich hab' dir ein paar CODE-Tags spendiert. Die kosten nix
Dein Moddy

PicNick
13.01.2006, 15:02
Dadurch sind die Längen von
char text[]="Keb";
char text2[]="Keb";

auf drei Byte beschränkt. Hast du das berücksichtigt ?

saschisch
17.01.2006, 12:44
Naja, wenn ich ehrlich bin weiß ich nicht was du meinst...
Sollte es nicht so sein, dass diese Deklaration 3 Buchstaben und ein endofsting Symbol in den String text schreibt?

wie sollte ich das dann anders machen? und wie erklärst du dir dannn das es funktioniert wenn man die Funktion direkt anspricht??

Toastbrot
18.01.2006, 09:22
Du musst in den eckigen Klammern die anzahl der Elemente des Arrays abgeben.
Also so in etwa:
char text[10]="Keb";
char text2[10]="Keb";

Toastbrot
19.01.2006, 15:37
Wie hast du das LCD eigentlich an deinen Atmega angeschlossen? Direkt an die I/O Ports, oder per RS232,I2C... hätte gerne mal ein Schaltplan ;)