PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Pollin Display, Softwareproblem/Darstellung



daywalker008
19.04.2009, 16:32
Hallo Leute ich habe ein PollinDisplay TG12864B-03 auf meinen Atmega32
laufen, nur leider sieht das das Display so aus wie im angehängten Bild.
Hier mal mei n Quellcode vom main.c


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

#include "ks0108.h"
#include "font12x16.h"
#include "font6x8.h"

const char pgmString[] PROGMEM = "http://www.apeTech.de\n\naffe.t@gmx.de";

int main(void) {
volatile uint16_t i;
struct font largeFont, smallFont;

for(i=0; i<15000; i++);


largeFont.width = FONT12X16_WIDTH;
largeFont.height = FONT12X16_HEIGHT;
largeFont.charData = Font12x16;

smallFont.width = FONT6X8_WIDTH;
smallFont.height = FONT6X8_HEIGHT;
smallFont.charData = Font6x8;

ks0108Init();

ks0108GotoXY(20,0);
ks0108PutString("Ha", largeFont);


while(1);



habe DB0 -7 an Port A und die Controlleitungen an Port B angeschlossen:
hier der Quellcode:


#include <inttypes.h>
#include <avr/pgmspace.h>

#ifndef KS0108_H
#define KS0108_H

// Ports
#define LCD_CMD_PORT PORTB // Command Output Register
#define LCD_CMD_DIR DDRB // Data Direction Register for Command Port

#define LCD_DATA_IN PINA // Data Input Register
#define LCD_DATA_OUT PORTA // Data Output Register
#define LCD_DATA_DIR DDRA // Data Direction Register for Data Port

// Function Parameters
#define INCREMENT_X 0
#define NO_INCREMENT_X 1

// Command Port Bits
#define D_I 0x00 // D/I Bit Number
#define R_W 0x01 // R/W Bit Number
#define EN 0x02 // EN Bit Number
#define CSEL1 0x03 // CS1 Bit Number
#define CSEL2 0x04 // CS2 Bit Number

// Chips
#define CHIP1 0x00
#define CHIP2 0x01

// Commands
#define LCD_ON 0x3F
#define LCD_OFF 0x3E
#define LCD_SET_ADD 0x40
#define LCD_SET_PAGE 0xB8
#define LCD_DISP_START 0xC0

// Fill Modes
#define BLACK 0xFF
#define CLEAR 0x00

// Uncomment for slow drawing
// #define DEBUG

struct displayPos {
uint8_t x;
uint8_t y;
uint8_t page;
};

struct font {
uint8_t width;
uint8_t height;
PGM_P charData;
};

// Function Prototypes
void ks0108Enable(void);
void ks0108Fill(uint8_t mode);
void ks0108GotoXY(uint8_t, uint8_t);
void ks0108Init(void);
void ks0108SetDot(uint8_t, uint8_t);
void ks0108ClearDot(uint8_t, uint8_t);
void ks0108PutChar(char c, struct font font);
void ks0108NewLine(uint8_t fontHeight, uint8_t offset);
void ks0108PutString(char *string, struct font font);
void ks0108PutStringP(PGM_P string, struct font font);
char ks0108ReadData(uint8_t incXAdd);
void ks0108WriteCommand(uint8_t cmd, uint8_t chip);
void ks0108WriteData(uint8_t data);

#endif

Das ganze ist von hier:http://www.mikrocontroller.net/topic/12202#new leider hat dort schon lange niemnad mehr hingeschaut.
Wie ihr auf dem Bild sehen könnt passt irgendwas mit den Pages nicht, kann es ein verkabelungsproblem sein? habe aber alles schon 2 mal kontrolliert.
Für eure Hilfe wäre ich sehr dankbar.

linux_80
19.04.2009, 21:54
Kannst Du die
void ks0108Init(void);
auch reinstellen, interessant ist wie es genau initialisiert wird.

Ich mach das unter Bascom mit diesen Commandos: $3F, $C0, $40, $B8

daywalker008
19.04.2009, 22:58
kein Problem:


void ks0108Init(void) {
pos.x = 0;
pos.y = 0;
pos.page = 0;

LCD_CMD_DIR = 0xFF; // command port is output
ks0108WriteCommand(LCD_ON, CHIP1); // power on
ks0108WriteCommand(LCD_ON, CHIP2);

ks0108WriteCommand(LCD_DISP_START, CHIP1); // display start line = 0
ks0108WriteCommand(LCD_DISP_START, CHIP2);
ks0108Fill(CLEAR); // display clear
ks0108GotoXY(0,0);
}

und nochmal die Putstring Funktion:

hoffe an irgendwas liegts, hatte das Display auch mit Bascom am laufen da funktionierte auch alles, musste aber auf c umsteigen.
void ks0108PutString(char *string, struct font font) {
uint8_t startx=pos.x, i=0;
char c = string[0];

while(c != 0) {
if(c == '\n')
ks0108NewLine(font.height, startx);
else
ks0108PutChar(c, font);
c = string[++i];
}
}

linux_80
20.04.2009, 19:08
Schreib die anderen beiden Werte auch noch ans LCD, damit alle Register des KS0108 initialisiert werden, wer weiss was da nach dem Reset drinsteht.
Von den vieren die ich angegeben habe, sinds nur die ersten zwei bis jetzt.

daywalker008
20.04.2009, 19:11
kannst du mir mal auf die Sprünge helfen, was du mit den anderen zwei werten meinst? Steh da jetzt aufm Schlauch...

linux_80
20.04.2009, 19:23
Ich hab in dem Post von gestern Abend vier Werte angegeben, wie das LCD initialisiert wird. In Deinem Programm werden davon aber nur die ersten beiden verwendet, gehen also noch die andern 2 ab.

daywalker008
20.04.2009, 19:32
Meinst du das so ungefähr?


void ks0108Init(void) {
pos.x = 0;
pos.y = 0;
pos.page = 0;

LCD_CMD_DIR = 0xFF; // command port is output
ks0108WriteCommand(LCD_ON, CHIP1); // power on
ks0108WriteCommand(LCD_ON, CHIP2);

ks0108WriteCommand(LCD_DISP_START, CHIP1); // display start line = 0
ks0108WriteCommand(LCD_DISP_START, CHIP2);

ks0108WriteCommand(LCD_AN3, CHIP1);
ks0108WriteCommand(LCD_AN3, CHIP2);

ks0108WriteCommand(LCD_AN4, CHIP1);
ks0108WriteCommand(LCD_AN4, CHIP2);
ks0108Fill(CLEAR); // display clear
ks0108GotoXY(0,0);
}




// Commands
#define LCD_ON 0x3F
#define LCD_OFF 0x3E
#define LCD_SET_ADD 0x40
#define LCD_SET_PAGE 0xB8
#define LCD_DISP_START 0xC0
#define LCD_AN3 0x40
#define LCD_AN4 0xB8


Da seh ich grad, B8 wird schon für setpage verwendet ???

linux_80
20.04.2009, 20:00
Ja das macht ja nix, den andern gibts ja auch schon, deswegen wollte ich die Init-Routine sehen was daraus gemacht wurde.
Und schon probiert, ändert sich was ?

daywalker008
20.04.2009, 20:08
leider kan ichs heut nichtmehr testen weil heut nichtmehr ans board komme, ich kann nur hoffen das es funktioniert und melde mich wieder wenn ja oder nein.
Aber danke dir bis hierher für deine Mühe mit mir.

daywalker008
01.05.2009, 17:29
So ich habe meinen Dataport an Port B gehängt und es funzt alles Prima...

Ich habe noch ein kleines Problemchen, ich möchte das mir das Display die Zeichen ausgibt, die ich über die serielle Schnittstelle sende, wenn ich nur einen Buchstaben sende, funktioniert das auch, aber wenn ich mehrere hintereinander sende also ins Terminalprogramm(hTerm) eingebe und dann senden drücke, dann gibt es mir nur den letzten aus, was muss ich verändern?

Hier der Quellcode:




unsigned char daten;
.
.
.

// LCD Initialisieren
uint8_t loop;
lcd_init();
lcd_clear();


anweisungen:
daten = USART_Receive();

lcd_set_cursor(0,LINE1);

lcd_putc(small_font,daten);
lcd_putc(small_font,daten);


USART_Transmit(daten);
goto anweisungen;

Wie kann ich auf die einzelnen Zeichen zugreifen? Sollte ich lieber ein Array anlegen?
Es müssen bis zu 20 Zeichen auf einmal empfangen werden, welche ich dann einzeln verwenden möchte

daywalker008
01.05.2009, 19:48
Hat sich erstmal erledigt, habs hinbekommen

daywalker008
02.05.2009, 09:16
So ich hab jetzt doch ein Problem:
ich verwende folgenden Code um Daten von der seriellen zu empfangen:


void usart_gets( char* Buffer, uint8_t MaxLen )
{
uint8_t NextChar;
uint8_t StringLen = 0;

NextChar = usart_getc(); // Warte auf und empfange das nächste Zeichen

// Sammle solange Zeichen, bis:
// * entweder das String Ende Zeichen kam
// * oder das aufnehmende Array voll ist
while( NextChar != '\n' && StringLen < MaxLen - 1 )
{
*Buffer++ = NextChar;
StringLen++;
NextChar = usart_getc();
}

// Noch ein '\0' anhängen um einen Standard
// C-String daraus zu machen
*Buffer = '\0';
}


Da liest er solange Zeichen ein bis "\n" kommt.
Die Steuerung die von der ich Daten empfange sendet aber nicht ein solches Endzeichen dort hört der Datensatz einfach mit der Checksumme ihrer Daten auf. Wie kann ich das jetzt gestalten, das er mir den Datensatz einliest und ihn mir in meiner Variable daten zurück gibt.
Jetzt wartet er ja vergeblich bis mal zufällig so ein Steuerzeichen kommt

daywalker008
02.05.2009, 10:41
Ich habe mich geirrt, die Steuerung sendet die Daten ohne irgendeinen abschluss, hört nach einen Datensatz einfach auf und will dann die Antwort haben.
Wie bring ich nun meiner Routine bei das der Datensatz zu Ende ist?

Vielleicht durch eine definierte Wartezeit? Wie schreib ich das?

vklaffehn
02.05.2009, 10:57
Moin!
Wenn die Datensätze immer gleich lang sind, kannst Du evtl. enfach mitzählen, ansonsten leiße sich das Ganze evtl. über ein Timeout lösen, wenn die Lücke zwischen zwei Datensätzen lang genug ist.
MfG
Volker

daywalker008
02.05.2009, 11:06
Kannst du mir sagen wie ich das mit den Timeouts hinbekomme? Die Datensätze sind nämlich unterschiedlich lang.

linux_80
02.05.2009, 11:22
Hallo,

weisst Du wie die Datensätze aufgebaut sind, also was die Daten bedruten ?
Evtl. ist darin dann die länge enthalten.
Das muss aber nicht unbedingt heissen, das die genaue länge drin vorkommt, sondern das der Empfänger einfach wissen muss wann was wielange sein sollte.
zB wenn das 1.Byte einen Befehl darstellt, ist damit schon festgelegt wieviel danach noch zu kommen hat.
:-k

KR-500
02.05.2009, 11:29
HI

das selbe problem hatte ich auch mit HTerm. Ich hab dann einfach die Zeichen gezählt aber du kannst die strings einfach z.B. immer mit ";" beenden
dann schreibst du statt:
while( NextChar != '\n' && StringLen < MaxLen - 1 )
einfach:
while( NextChar != ';' && StringLen < MaxLen - 1 )

KR-500

daywalker008
02.05.2009, 11:35
In Hterm kann ich ja einstellen das er die Zeichenkette mit \n abschließt. Aber das sollte nur zum probieren sein ob die Routine so erstmal funktioniert. Aber ich kann der Steuerungnicht sagen das sie da ein zeichen dranpacken soll.

Also ich weis was die Zeichen bedeuten aber ne Checksumme kann ich da nicht finden, am besten also über nen Timeout aber wie geht das?
Hier mal ein Auszug aus den Daten:
Senden:4d 41 01 01 00 90 MA...
Empfangen: e9 4d 41 0c 49 00 1c 07 2b 5a 75 73 74 61 6e 64 éMA.I...+Zustand