PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : GrafikLCD an mega32



_maddin
24.02.2008, 21:09
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/attachment/27964/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 ?



#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...

_maddin
27.02.2008, 14:19
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.