_maddin
24.02.2008, 22: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...
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...