-         

Ergebnis 1 bis 2 von 2

Thema: GrafikLCD an mega32

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.10.2006
    Ort
    Detmold
    Alter
    26
    Beiträge
    106

    GrafikLCD an mega32

    Anzeige

    hallo zusammen.
    ich hab die gleiche frage auch schon bei mikrocontroller.net gestellt, ich weiß das gehört sich nicht^^ aber es antwortet keiner

    ich habe mir ein glcd mit HD61830 Controller (Datenblatt:
    http://www.mikrocontroller.net/attac...64/hd61830.pdf )
    ersteigert.
    der text, den ich mit lcd_puts ausgebe soll natürlich nur 1 mal und zwar in der ersten zeile erscheinen. er erscheint aber in jeder zeile, insgesamt 12 mal.
    woran kann das liegen ?? das datenblatt hab ich schon einige male
    durchkämmt, ich finde keinen hinweis, vllt hab ich auch einfach ein
    brett vorm kopf ... kann mir jemand helfen ?

    Code:
    #define DATAPORT	PORTC
    #define DATADDR		DDRC
    #define DATAPIN		PINC
    #define CTRLPORT	PORTB
    #define CTRLDDR		DDRB
    #define RS			0
    #define RW			1
    #define E			2
    #define CS			3
    #define F_CPU		12000000
    
    #include <util/delay.h>
    #include <stdint.h>
    #include <avr/io.h>
    
    void lcd_enable(void){
    	// Erzeugt eine fallende Flanke am Enable-Pin
    
    	CTRLPORT |= (1<<E);
    	_delay_us(2);
    	CTRLPORT &= ~(1<<E);
    	_delay_us(2);
    }
    
    #define lcd_busy()	_delay_us(3)
    /*void lcd_busy(void) {
    	// Wartet bis der Controller wieder Daten verarbeiten kann
     
    	unsigned char tmp;
     
    	DATAPORT = 0x00;		// Datenport wird gelöscht
    	DATADDR = 0x00;			// Datenport wird als Eingang deklariert
    
    	CTRLPORT |= (1<<RW);	// R/W auf logisch 1 -> R 
    	CTRLPORT |= (1<<RS);	// RS auf logisch 1 -> aktiv
    	
    	do{
    	CTRLPORT |= (1<<E);		// Steigende Flanke am Enable-Pin
    	_delay_us(2);
    	tmp = DATAPIN;			// Datenport wird eingelesen
    	CTRLPORT &= ~(1<<E);	// Fallende Flanke am Enable-Pin
    	_delay_us(2);
    	}while(tmp & (1<<7));	// Schleife bis Busy Flag logisch 0 wird
    	
    	DATADDR = 0xff;			// Datenport wird wieder als Ausgang deklariert
    }*/
     
    void lcd_writecommand(uint8_t command) {
    	// Kommandobyte -> HD61830
     
    	lcd_busy();
    	CTRLPORT &= ~(1<<RW);	// R/W auf logisch 0 -> W 
    	CTRLPORT |= (1<<RS);	// RS auf logisch 1 -> aktiv
    	DATAPORT = command;		// übergebenes Kommandobyte wird ausgegeben
    	lcd_enable();
    }
     
    void lcd_writedata(uint8_t data) {
    	// Datenbyte -> HD61830
    	
    	lcd_busy();
    	CTRLPORT &= ~(1<<RW);	// R/W auf logisch 0 -> W 
    	CTRLPORT &= ~(1<<RS);	// RS auf logisch 0 -> inaktiv
    	DATAPORT = data;		// übergebenes Datenbyte wird ausgegeben
    	lcd_enable();
    }
    	
    void lcd_send(uint8_t command, uint8_t data) {
    	// Kombination aus Kommando- und Datenbyte
    
    	lcd_writecommand(command);
    	lcd_writedata(data);
    }
    
    void lcd_init(unsigned char modus){
    	// Initialisiert das Display
    
    	DATADDR = 0xff;		// Datenport wird als Ausgang deklariert
    	CTRLDDR|= (1<<RW)|(1<<RS)|(1<<E)|(1<<CS);		// Kommandoport wird als Ausgang deklariert
    	
    	CTRLPORT &= ~(1<<CS);	// CS auf logisch 0 -> aktiv
    	
    	if(modus == 'c'){
    	// Charaktermodus
    	
    	lcd_send(0x00, 0x30);	// Mode Control
    	lcd_send(0x01, 0x75);	// Set Character Pitch
    	lcd_send(0x02, 0x27);	// Set Number of Characters
    	lcd_send(0x03, 0x0a);	// Set Number of Time Divisions
    	lcd_send(0x04, 0x07);	// Set Cursor Position
    	}
    	else{
    	// Grafikmodus
    	
    	lcd_send(0x00, 0x32);	// Mode Control
    	lcd_send(0x01, 0x07);	// number of bits of 1-byte display data to be displayed
    	lcd_send(0x02, 0x1d);	// number of horizontal bytes
    	lcd_send(0x03, 0x0a);	// Set Number of Time Divisions 
    	}
    	
    	lcd_send(0x08, 0x00);	// Set Display Start Low Order Address
    	lcd_send(0x09, 0x00);	// Set Display Start High Order Address
    
    }
    
    void lcd_clear(unsigned char modus){
    	// Löscht das Display
    
    	lcd_gotoxy(modus, 0, 0);		// Cursor an den Anfang setzen
    	
    	if(modus == 'c'){
    	// Charaktermodus
    	
    	for(uint16_t i=0; i<320; i++)	// Alle Chars durchlaufen und löschen
    		lcd_send(0x0c, 0x20);
    	}
    	else{
    	// Grafikmodus
    	
    	for(uint16_t i=0; i<1920; i++)	// Alle Bytes durchlaufen und löschen
    		lcd_send(0x0c, 0x00);
    	}
    
    	lcd_gotoxy(modus, 0, 0);		// Cursor an den Anfang setzen
    }
    
    void lcd_gotoxy(unsigned char modus, uint8_t x, uint8_t y){
    	// Setzt den Cursor an eine bestimmte Position
    	
    	uint16_t adress;
    	
    	if(modus == 'c'){
    	// Charaktermodus
    	
    	adress = (y * 40) + x;
    	}
    	else{
    	// Grafikmodus
    	
    	adress = (y * 30) + x;
    	}
    	
    	lcd_send(0x0a, (uint8_t)(adress));			// Set Cursor Address (Low Order)
    	lcd_send(0x0b, (uint8_t)(adress >> 8));	// Set Cursor Address (High Order)
    }
    
    void lcd_setdot(uint8_t x, uint8_t y){
    	// Setzt ein Pixel an einer bestimmte Position
    
    	lcd_gotoxy('g', (x >> 3), y);
    	lcd_send(0x0f, (x & 0x07));
    }
    
    void lcd_cleardot(uint8_t x, uint8_t y){
    	// Löscht ein Pixel an einer bestimmte Position
    
    	lcd_gotoxy('g', (x >> 3), y);
    	lcd_send(0x0e, (x & 0x07));
    }
    
    void lcd_puts(char *string){
    	#define lcd_putc(c)	lcd_send(0x0c,c)
    	uint8_t i=0;
    	char c = string[0];
    	
    	while(c != 0) {
    	/*	if(c == '\n')
    			lcd_newline(font.height, startx);
    		else*/
    			lcd_putc(c);
    		c = string[++i];
    	}
    }
    
    int main(void){
    	_delay_ms(10);
    	lcd_init('c');
    	lcd_puts("Hallo ! Test XY Test XY Test XY Test XY");
    	while(1);
    }
    im grafik modus passiert genau das gleiche... wenn ein paar bytes sende, erscheinen sie nicht nur einmal sondern immer gleich 12 mal immer im abstand von je 10 pixeln untereinander.
    ich weiß echt nicht mehr weiter...

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.10.2006
    Ort
    Detmold
    Alter
    26
    Beiträge
    106
    hat sich schon erledigt. falls es irgendwen interessiert:
    man kann zwar das tastverhältnis (duty cycle) digital regeln, doch wenn man vom vorgabewert abweicht, kann es sein (so wie bei mir) das am display nur müll rauskommt. den passenden duty cycle wert entnimmt man dem datenblatt des displays.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •