Hallo Leute!
Wir arbeiten mit dem ATmega 32 mit der Taktfrequenz von 3,6864 Mhz und versuchen ein Display Powerdip Pc1602d a anzusteuern. Dazu haben wir uns ein Testprogramm heruntergeladen.
Wir lassen folgendes im Main.c ausgeben:
LCD_Print(0,0,"Servas");
_delay_ms(5000);
das ist das C File dazu
Die Header DAtei zum festelgen der Ports und soCode:/* Copyright: Radig Ulrich mailto: mail@ulrichradig.de Author: Radig Ulrich Remarks: known Problems: none Version: 28.05.2004 Description: Programm zur Ansteuerung eines Standart LCD (HD44870),(SED1278F) und kompatible */ #include <lcd.h> //Prototypes void Write_LCD (char,char); char Read_LCD (char); void LCD_Init (void); void LCD_Clear (void); void LCD_Print (char,char,char *Buffer,...); void LCD_Init (void) { char tmp = Init_LCD_Zeilen; //Set Port Direction Register to Output for LCD Databus und LCD Steuerbus LCD_Port_DDR = LCD_DataOutput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E); //Wait a short Time afer Power on for (int a=0;a<3000;a++) { } Write_LCD (0x22,0); //Init in 4 Bit Mode //Wait a short Time afer Power on for (int a=0;a<3000;a++) { for (int b=0;b<100;b++); } Write_LCD (0x22,0); //Init in 4 Bit Mode (Zur Sicherheit nochmal) if (tmp == 1) { Write_LCD (0x20,0); //1 Zeilen } else { Write_LCD (0x28,0); //mehrere Zeilen } Write_LCD (0x0C,0); //Display On Write_LCD (0x80,0); //Set DD-Ram Adresse = 0 } void Write_LCD (char Data,char CD) { //Set Port Direction Register to Output for LCD Databus und LCD Steuerbus LCD_Port_DDR = LCD_DataOutput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E); //Soll ins Seuer oder Datenregister geschrieben werden? if (CD == 0) { cbi(LCD_Port_Write,LCD_RS); //RS = 0 Steuerregister } else { sbi(LCD_Port_Write,LCD_RS); //RS = 1 Dataregister } //Schreibsignal setzen cbi(LCD_Port_Write,LCD_RW); //Zum Schreiben RW-Pin = Low //Schreiben der 1. 4Bit an das LCD Display LCD_Port_Write = (LCD_Port_Write&0xF0) + ((Data&0xF0)>>4); //Write Nibbel MSB sbi(LCD_Port_Write,LCD_E); cbi(LCD_Port_Write,LCD_E); //Schreiben der 2. 4Bit an das LCD Display LCD_Port_Write = (LCD_Port_Write&0xF0) + (Data&0x0F); //Write Nibbel LSB sbi(LCD_Port_Write,LCD_E); cbi(LCD_Port_Write,LCD_E); } char Read_LCD (char CD) { char Data; //Set Port Direction Register to Output for LCD Databus und LCD Steuerbus LCD_Port_DDR = LCD_DataInput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E); //Lesesignal setzen sbi(LCD_Port_Write,LCD_RW); //Zum Lesen RW-Pin = High //Soll ins Seuer oder Datenregister geschrieben werden? if (CD == 0) { cbi(LCD_Port_Write,LCD_RS); //RS = 0 Steuerregister } else { sbi(LCD_Port_Write,LCD_RS); //RS = 1 Dataregister } sbi(LCD_Port_Write,LCD_E); //Daten stehen an wenn Enable = High for (int a=0;a<100;a++) //Wartet ein bisschen bis daten anliegen { } Data = (LCD_Port_Read&0x0F)<<4; //Lesen des 1. Nibble (MSB) cbi(LCD_Port_Write,LCD_E); sbi(LCD_Port_Write,LCD_E); //Daten stehen an wenn Enable = High for (int a=0;a<100;a++) //Wartet ein bisschen bis daten anliegen { } Data += (LCD_Port_Read&0x0F); //Lesen des 2. Nibble (LSB) cbi(LCD_Port_Write,LCD_E); return(Data); } void LCD_Print (char zeile,char spalte,char *Buffer,...) { // Hilfsvariable zum Zählen der ausgegebenen Zeichen char nFieldWidth = 0; struct { char fLeftJust:1; // Feldausrichtung links oder rechts char fNegative:1; // Auszugebende Zahl ist negativ. } flags; #define SCRATCH 16 unsigned char scratch[SCRATCH]; unsigned char format_flag; unsigned int u_val=0, base=0; unsigned char *ptr; char hexA = 'a'; char *p; int n; int nLen; va_list ap; va_start (ap, Buffer); //Berechnet Adresse für die Zeile und schreibt sie ins DD-Ram if (zeile >= Init_LCD_Zeilen) //wurden mehr Zeilen angegeben als Initialisiert { zeile = Init_LCD_Zeilen - 1; } zeile = 0x80/Init_LCD_Zeilen*zeile; zeile += spalte; if (zeile >= 0x80) //ist der Wert ausserhalb des DD-Ram Adresse { zeile = 0x7F; } zeile += 0x80; Write_LCD (zeile,0); while (*Buffer != 0) { if (*Buffer == '%') { *Buffer++; switch (format_flag = *Buffer++){ case 'c': format_flag = va_arg(ap,int); Write_LCD (format_flag++,1); case 'i': case 'd': case 'u': base = 10; goto CONVERSION_LOOP; case 'o': base = 8; goto CONVERSION_LOOP; case 'X': hexA = 'A'; // Weiter wie 'x' case 'x': base = 16; } CONVERSION_LOOP: u_val = va_arg (ap, int); n = u_val; flags.fNegative = 0; if (format_flag == 'd' || format_flag == 'i') { // Negative Werte auswerten if (((int) u_val) < 0) { flags.fNegative = 1; u_val = -u_val; } } // Der Scratchpuffer wird von rechts nach links aufgefüllt // beginnend mit dem niederwertigsten Digit. ptr = scratch + SCRATCH; *--ptr = 0; // Abschliessendes NULL-Byte eintragen do { char ch = u_val % base + '0'; if (ch > '9') ch += hexA - '9' - 1; *--ptr = ch; u_val /= base; } while (u_val); if (n < base) *--ptr = '0'; if (flags.fNegative) *--ptr = '-'; // Länge bestimmen p = ptr; nLen = 0; while (*p++) nLen++; // Feld bei Bedarf links auffüllen if (!flags.fLeftJust) { for (n=nLen; n < nFieldWidth; n++) Write_LCD (' ',1); } // Pufferinhalt schreiben for (n=0; n < nLen; n++) Write_LCD (*ptr++,1); // Feld bei Bedarf rechts auffüllen if (flags.fLeftJust) { for (n=nLen; n < nFieldWidth; n++) Write_LCD (' ',1); } } Write_LCD (*Buffer++,1); } va_end(ap); } void LCD_Clear (void) { Write_LCD (1,0); //Clear Display Write_LCD (0x80,0); //Set DD-Ram Adresse = 0 }
Code://LCD_D0 - LCD_D3 connect to GND //Im 4Bit Mode LCD_D4-->PORTx.0 ........ LCD_D7-->PORTx.3 //LCD_RS --> PORTx.4 | LCD_RW --> PORTx.5 | LCD_E --> PORTx.6 | PORTx.7-->NotConnect #define Init_LCD_Zeilen 2 //Anzahl der Zeilen 1,2 oder 4 #define LCD_Port_DDR DDRA //Port an dem das Display angeschlossen wurde #define LCD_Port_Write PORTA #define LCD_Port_Read PINA #define LCD_RS 4 //Pin für RS #define LCD_RW 5 //Pin für Read/Write #define LCD_E 6 //Pin für Enable #define LCD_DataOutput 0x0f #define LCD_DataInput 0x00 #define BusyBit 7
Das Programm funktioniert soweit, dass wir am Display was sehen, aber es gibt folgendes aus:
evs<--<--0_HxWWt0__Unterstrich
<-- ist ein Zeichen und ein Pfeil nach links
_ist ein Abstand am Display
Unterstrich ist ein Unterstrich am Display
Danke für eure Hilfe
MfG
saschisch







Zitieren

Lesezeichen