PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Atmega 16x2 LCD Ansteuerung über TWI



D3nni5
05.08.2015, 21:26
Hallo,
ich möchte, wie es der Titel sagt, über ein Atmega32 ein 16x2 LCD über TWI ansteuern. Es gibt im rn-wissen bereich und bei microcontroller.de schon ein paar Erklärungen zu den Registern und dem Code. Allerdings komme ich damit nicht weiter. Der, wahrscheinlich sehr falsche, Code den ich bis jetzt habe sieht so aus:
#include <avr/io.h>

int main(void)
{
TWBR = 0b00000010;
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWDR = 0x00;
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
while (!(TWCR & (1<<TWINT)));
while(1)
{

}
}

ich benutze momentan die interne Frequenz von 1Mhz und habe dafür bei atmel TWBR = 2(0b00000010) gefunden. Die erste Codezeile ist mir noch klar, also da wo TWCR gesetzt wird. Bei der while überprüfung weiß ich nur, dass dort überprüft wird ob keine fehler auftreten(?). Mit TWDR sendet man,so wie ich das verstanden habe, die Daten. Dann stoppt man das Ganze und überprüft nochmal ob das funktioniert hat(?).

021aet04
05.08.2015, 21:55
Ich bin mir nicht sicher ob die Register bzw der Ablauf zum Atmega passt. Müsste im Datenblatt nachschauen. Aber grundsätzlich steht im Datenblatt ein kleines Beispiel (im jeweiligen Kapitel).

Aber bei while wird nicht auf Fehler geprüft sondern ob das TWINT gesetzt ist, das wird gesetzt wenn die letzte Übertragung abgeschlossen ist. Das ist nötig damit man nicht versehentlich Daten die noch nicht gesendet wurden überschreibt.

Bin mir nicht sicher aber ich glaube das du zuerst das twcr Register beschreiben musst (aber ohne sta), danach while(...), twda register beschreiben und dann erst sta im twcr register. Die letzte while ist nicht nötig weil du nichts mehr sendest.

An deiner stelle würde ich aber wie im Datenblatt beschrieben (bzw in fertigen musterprogrammen im Internet) schauen wie der Ablauf ist.


Und das nächste mal ein Programm mit den Code Tags im Post integrieren, ist übersichtlicher.

MfG Hannes

D3nni5
05.08.2015, 22:27
Erstmal danke für die Antwort.
Hab das Kapitel über TWI im Datenblatt gefunden. Es fängt auf Seite 169 an falls du es selbst lesen willst. Jetz steht dort aber "TWDR = SLA_W;". Wenn ich das im Atmel Studio eingebe bekomme ich da aber kein Vorschaufenster. Ist das jetzt eine feststehende Variable die irgendwo definiert wurde oder muss ich die selbst definieren oder ist das was ganz anderes? Dann steht da noch "TWDR = DATA". Ich geh mal davon aus, dass man das vorher definieren muss. Ist Data hier ein Hexadezimalbefehl oder kann das irgendein string sein um den an den LCD zu senden?

021aet04
06.08.2015, 05:51
Sla_w ist die schreibadresse des slave. Das ist eine variable. Diese ist für jedes Bauteil unterschiedlich und steht im Datenblatt des jeweiligen Bauteils.
Data ist die variable mit den Daten die du dem Bauteil senden willst.

MfG Hannes

Unregistriert
06.08.2015, 07:47
Such mal nach "Modulares Board". Dort wir die Ansteuerung komplett mit Hardware gezeigt. Bei mir hat es damit sofort geklappt

D3nni5
06.08.2015, 11:41
Das LCD war bei einem Fundinoset dabei hab jetzt als Slaveadresse 0x27 gefunden. Was muss in Data drinstehen? Wenn ich beispielsweiße TWDR = 0x01 eingebe müsste er das Display dann löschen. In den Headerdateien sehe ich jetzt aber nicht, dass es einen speziellen Befehl gibt um Text auf an das Display zu senden. Reicht es dann wenn ich DATA = string setze?

Hab auch mal Modulares Board gegoogelt bei der Seite von microcontroller werden da irgendwelche headerdateien verwendet, die ich nicht finden konnte oder irgendwas übersehen habe.

Unregistriert
06.08.2015, 13:13
Die Haederdatein stehen nicht auf dieser Seite. Am Ende hat der Autor seine Adresse drin. Habe mir das komplette Programm mit allen Datein geholt. Habe alles ohne Probleme bekommen. Programme sind C und laufen mit AVR Studio 6. Habe auch nur die Software genommen, in der Hardware stehen einiges zu Adressen drin
Paule

D3nni5
06.08.2015, 14:18
Das mit den Headerdatein funktioniert nicht so richt.
Hab jetzt den Code etwas geändert:


#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
while (!(TWCR & (1<<TWINT)));
TWBR = 0b00000010;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWDR = 0x27;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWDR = 0x02;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
_delay_ms(5000);
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);


while(1)
{

}
}


Da ich immer noch nicht weiß wie ich chars übertragen kann hab ich einen Befehl übertragen der normalerweiße den Courser zeigen sollte,was allerdings nicht funktioniert. Was ist hier an den Code falsch? Hat vielleicht jemand ein Codebeispiel für ein 16x2 LCD?

021aet04
06.08.2015, 15:10
Zuerst musst du die slaveadresse senden (bei dir 0x27). Diese Adresse ist aber die leseadresse. Lies einmal im Internet über die Grundlagen nach. Z.b. http://www.timmermann.org/ralph/index.htm?http://www.ralph.timmermann.org/elektronik/i2c.htm oder www.i2c-bus.org

Dort steht alles genau beschrieben. Also wenn du etwas schreiben willst.
Slave Adresse schreiben
Register
Kommando

MfG Hannes

D3nni5
06.08.2015, 15:58
Kannst du vielleicht,wenn es nicht allzu viele Umstände macht, eine Übertragung als Code schreiben? Ich weiß nicht ob ich mir das zu kompliziert mache. Ich suche schon die ganze Zeit in den Headerdateien die Befehle um ein Wort auf dem LCD anzuzeigen. Die Headerdateien benutzen aber auch noch Headerdateien wie beispielsweiße die "Wire.h" Datei vom Arduino um Strings zu senden.

021aet04
06.08.2015, 16:53
Hast du dich schon einmal über die Grundlagen des I2C informiert? Bei i2c wird immer byteweise übertragen. Du kannst deshalb nicht einfach schreiben twdr='hallo';.

Was du bis jetzt noch nicht geschrieben hast ist was das für ein LCD ist. Ein normales LCD Display hat kein I2C sondern eine 4 bzw 8bit paralellschnittstelle.

Im Datenblatt steht alles drinnen was du benötigst.

MfG Hannes

D3nni5
06.08.2015, 20:36
Entschuldigung hab beibdem ganzen code die hardware vergessen hab ein lcd 1602 mit einem pcf85741 dran. Wie gesagt das ist das LCD von einem Funduinoset am LCD ist eine platine dran mit allem drauf man muss dann nur Vcc Masse SDA und SCL anschließen das Datasheet hat mich leider nicht weitergebracht. Natürlich hast du recht,dass man nicht einfach so einen string senden kann. Ich hab aber sehr lange die Headerdatein durchsucht wie man die Daten überträgt und da man dort nur einen string eingibt und die funktion in der cpp datei das automatisch macht hatte ich da einen kleinen Denkfehler

021aet04
06.08.2015, 21:43
Über das Display findet man nicht besonders viel. Ich habe aber eine Header Datei gefunden (die du vermutlich auch gefunden hast). Ich würde am Anfang einmal versuche die Hintergrundbeleuchtung einzuschalten. Wenn ich das Richtig aus der Dateien herausgelesen habe sollte es so funktionieren:

TWBR = 0b00000010;
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
while (!(TWCR & (1<<TWINT)));
TWDR = 0x26;
while (!(TWCR & (1<<TWINT)));
TWDR = 0x00;
while (!(TWCR & (1<<TWINT)));
TWDR = 0xff;
while (!(TWCR & (1<<TWINT)));
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

Das erste TWDR ist die Slave Adresse für schreiben, das zweite ist das Register für Kommandos und das dritte ist das Kommando selbst (hier Hintergrundbeleuchtung ein).

Hast du eine Anleitung zu dem Display?

Ich bin mir nicht sicher ob ich die Headerdatei richtig verstanden habe, könnte aber so hinkommen. Hast du noch andere Bauteile für I2C oder nur das Display?

Der Programmteil kommt dort hin wo du die I2C Verbindung hast (zwischen int main{ und while(1); )

MfG Hannes

D3nni5
06.08.2015, 21:58
Danke für die Antwort. Ist das erste TWDR ein Schreibfehler oder ist die richtige Adresse 0x26? Dieses Kommando war etwas ungünstig gewählt, weil die Hintergrundbeleuchtung dauerhaft an ist. Ich versuche mal andere Kommandos. Hab leider keine Anleitung zum Display und ist auch leider das einzige Bauteil für I2C. Wenn du mir allerdings etwas einfacheres empfehlen kannst solls dann auch nicht am Geld liegen. Falls du die Headerdatei LiquidCrystal_I2C.h und .cpp hast und vielleicht etwas Zeit und Lust hättest könntest du vielleicht nach dem Kommando suchen um einfach ein A ans Display zu senden so, dass es angezeigt wird?
Außerdem wollt ich nochmal danke sagen. Hat mich bis jetzt schon einiges vom Verständis her weitergebracht.

021aet04
06.08.2015, 22:45
Die 0x26 ist schon richtig. Hier (http://rn-wissen.de/wiki/index.php/I2C)steht z.B. das das LSB (niederwertigstes Bit => ganz rechtes Bit) für Schreibe bzw Lesezugriff steht. Bei Schreibzugriff ist das Bit 0 und bei Lesezugriff ist das Bit 1. Somit hast du bei Schreibzugriff 0x26 und bei Lesezugriff 0x27.

Wenn du die Lib von hier (http://jaredstemen.blogspot.co.at/2014/01/getting-funduino-1602-lcd-to-print.html) hast, dann haben wir die gleiche. Du hast gesagt das du ein 16x2 LCD hast, somit musst du die LCD Lib nehmen. Ich schaue morgen noch genauer, aber im "docs" Ordner sollten Anleitungen zu finden sein.

Ich würde, wenn ich mit I2C anfange, mit einfachen Bauteilen anfangen (z.B. Porterweiterung PCF8574). Dort kannst du an den Ausgängen direkt Leds (mit Vorwiderstand) anschließen. Somit sieht man sofort ob es funktioniert hat oder nicht. Beim LCD Modul kann es sein das es am Programm, I2C Verbindung oder am LCD liegt.

MfG Hannes

D3nni5
06.08.2015, 23:00
Alles klar vielen Dank. Ich werde dann in der Datei nachschauen und auch nach dem ic schauen. Möchte aber trotzdem noch das LCD zum laufen bringen. Die Porterweiterung werd ich mir dann wahrscheinlich nächste Woche anschauen, da der ic diese Woche wohl nicht gesendet werden kann.