PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RN KEY LCD-Ansteuerung über I2C



roboguy
05.05.2006, 09:30
Von Zeit zu Zeit komme ich dazu, mich mit meinem privaten Mega128-Projekt zu beschäftigen. Das Board ist soweit fertig und funktioniert. Für die Visualisierung und lokale Eingabe möchte ich das RN KEY&LCD-Modul verwenden. Auch das läuft soweit.
Ich habe die beigefügten Ansteuerroutinen unter BASCOM mit meinem eigenen Board ausprobiert - alles klappt wunderbar. Ich kann die Displayinhalte löschen, Cursor ein-/ausschalten und positionieren, Texte schreiben usw.
Jetzt bin ich daran gegangen, das Ganze unter C zu programmieren.
Ich habe (versucht), die BASCOM-Prozeduren ín C umzusetzen. In meinem Hauptptogramm wird zuerst die I2C initialisiert, dann das RNKEYLCD-Display gelöscht und ein String hineingeschrieben. Das schien auch zu funktionieren, im Display erschien mein String - bis mir dann auffiel, dass einiges, was ich eigentlich wollte, nicht passierte: die Displaybeleuchtung blieb an, der Cursor sollte nicht angezeigt werden, blinkte aber fröhlich vor sich hin.

Ich habe mir daraufhin eine Routine für das Positionieren des Cursors genauer angesehen und damit herumgespielt: es klappt einfach nicht und ich habe keine Idee, woran es liegt.
Unter BASCOM sieht die Cursorpositionierung so aus:


Sub Rnlcd_cursor(byval Spalte As Byte , Byval Zeile As Byte)
Local Befehle As String * 4
Befehle = Chr(27) + Chr(79) + Chr(spalte) + Chr(zeile)
I2csend Rnkeylcd_slaveid_write , Befehle , 4
End Sub
Unter WINAVR habe ich folgendes Konstrukt erstellt:


#define RNKEYLCD_CTRL_CHAR 0x1B
#define RNKEYLCD_GOTO_CHAR 0x4F
...
...
static void rnlcd_gotoxy(uint8_t col, uint8_t row)
{
uint8_t command[4];

command[0] = RNKEYLCD_CTRL_CHAR;
command[1] = RNKEYLCD_GOTO_CHAR;
command[2] = col + 48; //convert digit to ascii value
command[3] = row + 48; //convert digit to ascii value
i2cMasterSendNI(RNKEYLCD_SLAVEID_WRITE, 4, command);
}
Die i2cMasterSendNI(..) entstammt der normalen I2C.h, die bei WINAVR mit installiert wird. Diese Routine funktioniert auch prinzipiell, denn diese Abfolge


uint8_t vers_info[] = "Version 0.1 ";
...
static void rnlcd_write(uint8_t stringlength, uint8_t *string)
{
i2cMasterSendNI(RNKEYLCD_SLAVEID_WRITE, stringlength, string);
}

int main(void)
{
uint8_t i;
...
i = (uint8_t) strlen(vers_info);
rnlcd_write(i,vers_info);
...
}
schreibt mir brav in mein Display den String mit der Versionsinfo, d.h. die I2C-Kommunikation scheint zu funktionieren.
Ich bin mit meinem Latein am Ende.
Hat jemand eine Idee?

Frank
05.05.2006, 09:49
Hi,
zu der Avr C-Lib kann ich wenig sagen da ich die nicht nutze. Aber ein genereller Fehle rist in deinem Quellcode noch.
Bei den Befehlen werden die Parameter nicht im Ascii Code sondern Binär übertragen, da liegt offenbar dein Fehler.
Du darfst also die 48 nicht hinzuaddieren. Wenn du folgendes änderst sollte es gehen:



command[2] = col + 48; //convert digit to ascii value
command[3] = row + 48; //convert digit to ascii value


in



command[2] = col; //NOT convert digit to ascii value :-)
command[3] = row ;



Gruß Frank

roboguy
05.05.2006, 09:57
Vielen Dank für den Tip!
Muss ich heute abend ausprobieren, da ich momentan nicht an mein Board komme.
Dennoch verstehe ich die Sache nicht so ganz. In der BASCOM-Routine wird doch mittels CHR(spalte) der ASCII-Wert der Zahl "spalte" genommen, oder nicht?
Die BASCOM-Hilfe schreibt dazu
"Convert a numeric variable or a constant to a string with a length of 1 character. The character represents the ASCII value of the numeric value."
Wo liegt da meine Denkblockade?
Volkhard

Frank
05.05.2006, 10:04
Geht sicher.
In Basic sind Strings keine Byte-Arrays. In C kann man einfach den Bytewert anhängen, in Basic muss man den Bytewert erst in ein Zeichen umwandeln. Diese Umwandlung macht CHR, dabei wird aber der Zahlenwert nicht verändert. Die Spalte 5 wird nur zu dem Zeichencode 5.
Und 5 ist auch ein ASCII-Code, auch wenn es nicht der "5" (Dez 53) entspricht.

Gruß Frank

Green Hell
07.05.2006, 18:16
Hallo zusammen,
ich habe ebebfalls Probleme das RNKey-LCD über I²C anzuschließen, aber bei mir funktioniert auch die Ausgabe eines einfachen Strings auf dem Display noch nicht.
Werde leider aus den Code-Schnipseln von oben kaum schlau. :-s Hat vielleicht irgendwer eine Routine um Strings auf dem Display anzuzeigen???
Danke im Vorraus.

Gruß Green Hell

roboguy
07.05.2006, 19:58
Hallo Frank!
Vielen Dank nochmals für deine Erläuterungen. Ich habe es dann abends ausprobiert und es hat in der Tat genauso funktioniert.

@Green Hell:
Bist du denn sicher, das dein I2C-Master prinzipiell überhaupt funktioniert?
Würde dir empfehlen, dafür auf jeden Fall einmal die bei RNKey-LCD mitgelieferten BASCOM-Programmbeispiele zu testen, die haben bei mir auf Anhieb geklappt. Alles weitere war dann ein klein wenig nachdenken und probieren (und natürlich im Zweifelsfall hilfreiche Leute fragen, deshalb gibt es ja diesen Thread).
Roboguy

Frank
08.05.2006, 16:42
@roboguy: Na dacht e ich´s mir doch ;-) Fein das es klappt, vielleicht kannste bei Gelegenheit ja mal ein komplettes C-Demo posten weil ich nur Basic Beispiele habe.

@Green Hell:
Wenn Du die Möglichkeit hast erst mal ein Bascom Beispiel zu testen ist´s am einfachsen, die liegen ja fertig bei. Wenn die nicht klappen musst du die I2C-Adresse vergleichen/überprüfen, ansonsten gibts eigentlich keine größere Hürde.


Gruß frank

Green Hell
18.05.2006, 08:02
Hallo alle zusammen,
ich hab jetzt mein rnkey-lcd richtig angeschlossen und es funktioniert auch. Ich habe jetzt nur das Problem, dass ich den inhalt einer int-variable(messwert vom ultraschallsensor srf10) auf dem display anzeigen will. Der Sensor misst auch die richtige länge und gibt sie ans controllerboard, aber wenn ich dem lcd einfach den int-wert gebe wird das der zahl entsprechende ascii-zeichen ins display geschrieben.
Ich brauch also eine funktion, die einen int-wert erst in einen string umwandelt und dann muss ich die zeichen des strings einzeln über den I²C-Bus ans lcd senden. Weiß vielleicht jemand eine solche funktion, die diese Typenumwandlungen in C macht? (Habs schon mit explizitem casten versucht, aber entweder hab ich was falsch gemacht oder so kanns nicht funktionieren. Beim googlen hab ich ne funktion namens
"sprintf" gefunden, aber das hat auch nicht so richtig geklappt)

Danke im Vorraus
Gruß Green Hell

Pascal
18.05.2006, 08:16
für solche Sachen gibts die Funktion itoa (also "integer to ascii")
Wenn ich mich jetzt nicht täusche, erwartet die Funktion drei Argumente, als erstes einen Zeiger auf das chararray, wo der String stehen soll, dann als zweites die Variable mit der Zahl, die gewandelt werden soll, und als drittes die Basis des zu verwendenten Zahlensystems(also für "normales" Zehnersystem 10).
Dieses chararray musst du dann nur noch an das Display senden.