Hallo! Bei einem älteren Projekt, das noch im AVR Studio 4 erstellt würde, möchte ich ein TWI-Display (I2C-Display) einbinden. Welche Lib kann dafür im AVR Studio benutzt werden und wo findet man die Steuerbefehle für diese Lib, gibt es dafür dann eine Doku oder Beispielcode? Das Programm ist in C geschrieben und das Display hat zwei Zeilen mit jeweils 16 Zeichen.
Vielleicht noch wichtig zu erwähnen, der Controller ist ein M328P und das Display, das am Controller angeschlossen werden soll, hat vier Anschlüssen: +5V, GND, SDA, SCL.
Da es nur einen Typ I2C-Display gibt, wird Dir sicher gleich jemand die passende LIB posten. Das AVR-Studio ist keine Arduino IDE, die eine Lib für die eine Hardware gibt es nicht. Schau Dir die Schaltung des Displays an und sieh nach wie die Bauteile angesprochen werden. Wenn Du das verstanden hast, ist es nicht schwer Dir selbst eine passende Lib zu schreiben.
Unter Arduino läuft das Display problemlos. Der Sketch dort ist sehr übersichtlich:
1 | //YWROBOT |
2 | //Compatible with the Arduino IDE 1.0 |
3 | //Library version:1.1 |
4 | #include <Wire.h> |
5 | #include <LiquidCrystal_I2C.h> |
6 | |
7 | LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display |
8 | |
9 | void setup() |
10 | { |
11 | lcd.init(); // initialize the lcd |
12 | lcd.init(); |
13 | // Print a message to the LCD. |
14 | lcd.backlight(); |
15 | lcd.setCursor(3,0); |
16 | lcd.print("Hello, world!"); |
17 | lcd.setCursor(1,3); |
18 | lcd.print("123456789012345"); |
19 | } |
20 | |
21 | void loop() |
22 | { |
23 | } |
Würde es dann reichen, die <Wire.h> und die <LiquidCrystal_I2C.h> ins AVR-Studio-Projekt zu includieren?
Peter_Michael schrieb: > Der Sketch dort ist sehr übersichtlich: Weil die ganzen Fähigkeiten in den Libs stecken. Peter_Michael schrieb: > Würde es dann reichen, die <Wire.h> und die <LiquidCrystal_I2C.h> ins > AVR-Studio-Projekt zu includieren? Nein. Du stellst dir das zu einfach vor. Denn die beiden Libs sind wiederum Klassen die auf dem Arduino-Framework aufbauen. Man kann sie nicht einfach nehmen und ins eigene Projekt einbinden. (genau genommen bräuchtest du natürlich <Wire.cpp> und <LiquidCrystal_I2C.cpp> aus der Arduino Umgebung) Ich habe mir mal die Mühe gemacht und eine Arduino-Klasse in normales C zu überführen, aber ich schätze das ist nichts was du so auf die Schnelle schaffst.
Wen man ein bisschen sucht findet man ganz nette Kleinode. Für I2C zum Beispiel das hier im Anhang. Das ist so ziemlich alles was man braucht um über TWI zu kommunizieren. (für dich relevante Teile im Archiv sind twi.c und twi.h)
Peter_Michael schrieb: > Niemand mehr eine Idee dazu? google? LCD-"Libs" in C für AVR gibt es durchaus, und die lassen sich auch finden. Hier im Forum links oben die Artikelsammlung wäre ein guter Startpunkt. Oliver
Da finde ich z.B. das hier: https://www.mikrocontroller.net/articles/AVR_TWI#Benutzung_des_TWI Aber nichts mit Display. Ich kann ja mal kurz sagen, was bei dem Projekt passieren soll. Es soll im Prinzip nur eine 10bit-Variable auf der ersten Zeile des Displays angezeigt werden. Normalerweise mache ich das immer über den UART, aber die RX/TX-Pins sind belegt. Mit der üblichen lcd.h geht es auch nicht weiter, weil keine Pins mehr für die 4bit-Ansteuerung eines HD44780 übrig sind. I2C/TWI ginge über einen PCF8574T zum LCD. Unter Arduino funktioniert das auch. Jetzt müsste man das nur unter AVR Studio angesteuert bekommen. Vorrausgesetzt, der TWI läuft mit #include <util/twi.h> Wie teilt man dann dem PCF8574T-LCD die 10-Bit-Zahl zur Anzeige in dezimaler Schreibweise mit?
Peter_Michael schrieb: > das Display hat zwei Zeilen mit > jeweils 16 Zeichen Gibt es davon nur eine Sorte/Ausführung? Hat das Teil auch eine Bezeichnung? Das kann alles mögliche sein ... entsprechend vielfältig sind die Möglichkeiten. Je genauer ein Problem beschrieben ist, desto zielführender sind die Antworten :-) Ich sehe gerade: Peter_Michael schrieb: > Wie teilt man dann dem PCF8574T-LCD Das gibt es nicht - wenn es aber ein Peter_Michael schrieb: > HD44780 ist, dann wäre das Beitrag "I2CLCD Library für HD44780 LCDs" eine gute Wahl.
:
Bearbeitet durch User
Hugo H. schrieb: > Je genauer ein Problem beschrieben ist, desto zielführender sind die > Antworten :-) Schau mal in den Beitrag direkt über deinem ;) Beitrag "Re: AVR Studio 4: TWI Display einbinden" Da sollte alles stehen. Wenn nicht, antworte ich zeitnah auf offene Fragen. Das Display ist wie dort gesagt eins mit zwischengeschaltetem PCF8574T.
Peter_Michael schrieb: > Ah, wir haben uns überschnitten. Ja :-) schau Dir den Link mal an, der passt sicher. Für HD44780 und Port-Expander (danach googlen) gibt es viele "Librarys" - Falk ist "ein Guter" :-)
:
Bearbeitet durch User
Habe es mangels Hardware nicht getestet, sieht nach guter Minimal Version aus: https://www.youtube.com/watch?v=Uhq3Hp_P2xQ Dateien: https://github.com/Jose-Manuel34/LCD_I2C_h
Beitrag #6445938 wurde vom Autor gelöscht.
Irgendwie klappt es nicht. Auf dem Display wird nichts angezeigt (es funktioniert aber, habe es mit Arduion I2C Display getestet). Video: ATmega328p LCD using I2C: https://www.youtube.com/watch?v=Uhq3Hp_P2xQ Software: Jose-Manuel, Github Lib.: https://github.com/Jose-Manuel34/LCD_I2C_h Mein Code (aus dem Video übernommen):
1 | int main () |
2 | {
|
3 | |
4 | //***I2C-INIT//////////////////////////////////////////////
|
5 | i2c_init(); |
6 | i2c_start(); |
7 | i2c_write(0x70); //dirrectión del modulo I2C = Richtung oder Adresse? |
8 | lcd_init(); |
9 | #include <util/delay.h> |
10 | |
11 | |
12 | while(1) |
13 | {
|
14 | lcd_cmd(0x80); |
15 | lcd_msg("Welt Hallo"); |
16 | lcd_cmd(0xC3); |
17 | lcd_msg("1234567890123456"); |
18 | }
|
19 | |
20 | }
|
Statt
1 | lcd_cmd(0xC3); |
habe ich auch
1 | lcd_cmd(0x27); |
probiert, weil das verwendete 16x2 I2C-Display als Adresse 0x27 hat, aber auch damit funktioniert es nicht. Die beiden dazugehörenden h-Dateien sind im Anhang. So richtig klar ist mir nicht, wo man die Adresse des Displays einträgt. Weiter unten in LCD_I2C.h befindet sich jedenfalls folgende Sequenz:
1 | void lcd_init() |
2 | {
|
3 | lcd_cmd_hf(0x30); //-----Sequence for initializing LCD |
4 | lcd_cmd_hf(0x30); //----- " " " " |
5 | lcd_cmd_hf(0x20); //----- " " " " |
6 | lcd_cmd(0x28); //-----Selecting 16 x 2 LCD in 4Bit mode |
7 | lcd_cmd(0x0C); //-----Display ON Cursor OFF |
8 | lcd_cmd(0x01); //-----Clear display |
9 | lcd_cmd(0x06); //-----Cursor Auto Increment |
10 | lcd_cmd(0x80); //-----1st line 1st location of LCD |
11 | }
|
Kann man daraus ableiten, welche I2C-Adresse das Display haben muss, wenn man den Code so verwendet, wie er ist?
Hast Du ein Datenblatt vom verwendeten Display? Wenn es ein PCF8574 oder die A Version ist: siehe Anhang Ich vermute Ardu Dingens schiebt die Adresse durch das R/W Bit noch eine Stelle nach links. Also für die nicht A Version muß 0x4X gesendet werden.
Peter_Michael schrieb: > Kann man daraus ableiten, welche I2C-Adresse das Display haben muss, > wenn man den Code so verwendet, wie er ist? Nein. Die Adresse muß in den lcd-Funktionen stecken, die die gezeigten Kommandos in TWI umsetzten. Oliver
pegel schrieb: > Wenn es ein PCF8574 oder die A Version ist: siehe Anhang Danke Pegel! Ich hole mal die Lupe raus. Der IC ist ein PCF8574T. Auf dem Modul sind drei Lötbrücken, darunter steht A0 A1 A2. pegel schrieb: > Also für die nicht A Version muß 0x4X gesendet werden. Muss man dann hier
1 | lcd_cmd(0xC3); |
statt 0xC3 die 0x4X eintragen und das X aus dem Datenblatt nehmen? Oliver S. schrieb: > Nein. Die Adresse muß in den lcd-Funktionen stecken, die die gezeigten > Kommandos in TWI umsetzten. Hallo Oliver, meinst du mit lcd-Funktionen die .h-Dateien hier? https://www.mikrocontroller.net/attachment/476732/i2c.h https://www.mikrocontroller.net/attachment/476733/LCD_I2C.h
Peter_Michael schrieb: > Der IC ist ein PCF8574T. Auf dem Modul sind drei Lötbrücken, darunter > steht > A0 A1 A2. Zusatzinfo, die drei Lötbrücken sind offen. Das ist sicher wichtig zu wissen.
Peter_Michael schrieb: > Unter Arduino läuft das Display problemlos. > LiquidCrystal_I2C lcd(0x27,16,2); weil A0 bis A7 offen sind = high Basis Adresse ist also 0x20 und A0-A2 offen +7 also 0x27 Aber das ist Arduino zählweise! (ohne R/W bit 0) unter Atmel Studio wird aber ohne shift right gearbeitet also Basis 0x40 und weil A0 bis A7 offen sind = high also 0x4E der Code müsste also so laufen Peter_Michael schrieb: > i2c_write(0x4E); //dirrectión del modulo I2C = Richtung oder Adresse? switch(address<<1) { case 0x40: case 0x42: case 0x44: case 0x46: case 0x48: case 0x4A: case 0x4C: case 0x4E: #ifdef I2C_TASTATUR_8574 i2c_test_flags|=(1<<I2C_TASTATUR_8574); _i2c_key=' '; i2c_tastatur_address=(address); #endif // #ifdef I2C_TASTATUR_8574 DEBUG_PRINTLN(F("PCF8574 Tastatur")); break; case 0x70: case 0x72: case 0x74: case 0x76: case 0x78: //#pragma message"I2C SCAN: 0x78 -> I2C_OLED || I2C_TASTATUR_8574A" case 0x7A: case 0x7C: case 0x7E: also ist bewiesen das dein PCF ein 8574 ohne a ist und das T für irgendwas gehäusemäßiges steht, Plastic vermute ich
:
Bearbeitet durch User
Danke Joachim! Wenn ich in der Zeile mit den drei *** einfach nur die Adresse in von 0x70 in 0x4E tausche, wird auf dem Display leider immer noch nichts angezeigt.
1 | //***I2C-INIT//////////////////////////////////////////////
|
2 | i2c_init(); |
3 | i2c_start(); |
4 | i2c_write(0x4E); // *** ehemals 0x70 |
5 | lcd_init(); |
6 | #include <util/delay.h> |
7 | |
8 | |
9 | while(1) |
10 | {
|
11 | lcd_cmd(0x80); |
12 | lcd_msg("Welt Hallo"); |
13 | lcd_cmd(0xC3); |
14 | lcd_msg("1234567890123456"); |
15 | }
|
Hier auf Seite 5 und 6 sieht man ja, dass die Software wohl ursprünglich für einen PCF8574 A geschrieben wurde (weil write-Adresse = 0x70): https://www.mouser.de/datasheet/2/302/PCF8574_PCF8574A-1127673.pdf Kann es sein, dass in den beiden h-Dateien auch noch jede Menge Adressen von Hand geändert werden müssen? https://www.mikrocontroller.net/attachment/476732/i2c.h https://www.mikrocontroller.net/attachment/476733/LCD_I2C.h
Peter_Michael schrieb: > Kann es sein, dass in den beiden h-Dateien auch noch jede Menge Adressen > von Hand geändert werden müssen? copy&paste-Programiererei hat nunmal Grenzen, die du einfach akzeptieren musst. Du hast zwei Möglichkeiten: a) verstehen, was das LCD und die Software macht, und es dann zum laufen zu bringen b) eine andere Copy&Paste-Quelle suchen und ausprobieren. Danach weiter mit a) oder b) Oliver
Mir ist auch noch etwas anderes aufgefallen. Unter dem Video selber https://www.youtube.com/watch?v=Uhq3Hp_P2xQ hat ein gewisser Bad Behaviour vor 1 Monat gepostet: "Hi. Im trying to use this library but it doesnt work. It get stucked in the lcd_init program when it calls lcd_cmd_hf(0x30) (twice)" Eventuell könnte es also noch andere Probleme mit dem Code geben.
;) Oliver S. schrieb: > Du hast zwei Möglichkeiten: > a) verstehen, was das LCD und die Software macht, und es dann zum laufen > zu bringen > b) eine andere Copy&Paste-Quelle suchen und ausprobieren. Danach weiter > mit a) oder b) Oliver
Du könntest aber einfach auch mal dein komplettes main Programm hier zeigen. Ich sehe zum Beispiel nicht wo du i2c.h und lcd_i2c.h inkludierst. Zusätzlich wäre der Compiler und Linkeroutput noch von Interesse. Generell Code in Header Files ist zwar ok aber zumindest in c nicht so toll. In den Header Files fehlen auch include guards.
Peter_Michael schrieb: > Welche Lib kann dafür im AVR Studio benutzt werden probiere http://www.peterfleury.epizy.com/avr-software.html?i=1 damit hatte ich die ersten Erfolge ausserhalb der Arduino IDE & Libs. http://www.peterfleury.epizy.com/i2cmaster.zip http://www.peterfleury.epizy.com/lcdlibrary.zip aber ohne lernen und Verständnis wird das auch nichts! Trotzdem kann man das Gelernte durchaus auch in Arduino nutzen und sogar wahlweise einbinden, mit Abfrage auf Arduino im #preprozessor
Peter_Michael schrieb: > Eventuell könnte es also noch andere Probleme mit dem Code geben. Hmm. Ich habe leider keine Atmel Hardware mehr, aber findest Du nicht es wird Zeit die paar Befehle in den Libs zu entschlüsseln? Am Besten als Kommentare in die Libs schreiben, dann sollte die Logik dahinter erkennbar sein.
Noch etwas: wenn es in der Simulation funktioniert und im echten Leben nicht, könnte es daran liegen, dass das Display ein gewisses Timing braucht, die Simulation wohl nicht.
pegel schrieb: > es wird > Zeit die paar Befehle in den Libs zu entschlüsseln? Das ging mir heute morgen auch durch den Kopf. > könnte es daran liegen, dass das Display ein gewisses Timing > braucht, die Simulation wohl nicht. Interessanter Ansatz. Im einfachsten Fall könnte man vielleicht einfach die Div/8-Fuse setzen und schauen, was passiert. Zu den Libs:
1 | /* Heder file for I2C */
|
2 | |
3 | #include <avr/io.h> |
4 | |
5 | #define F_CPU 8000000UL
|
6 | |
7 | void i2c_init(){ |
8 | TWBR = 0x62; // Baud rate is set by calculating |
9 | TWCR = (1<<TWEN); //Enable I2C |
10 | TWSR = 0x00; //Prescaler set to 1 |
11 | |
12 | }
|
13 | //Start condition
|
14 | void i2c_start(){ |
15 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA); //start condition |
16 | while (!(TWCR & (1<<TWINT))); //check for start condition |
17 | |
18 | }
|
19 | //I2C stop condition
|
20 | void i2c_write(char x){ //Cpn esta funcion se escribe en el bus de TWDR |
21 | TWDR = x; //Move value to I2C |
22 | TWCR = (1<<TWINT) | (1<<TWEN); //Enable I2C and clear interrupt |
23 | while (!(TWCR &(1<<TWINT))); |
24 | }
|
25 | |
26 | char i2c_read(){ |
27 | TWCR = (1<<TWEN) | (1<<TWINT); //Enable I2C and clear interrupt |
28 | while (!(TWCR & (1<<TWINT))); //Read successful with all data received in TWDR |
29 | return TWDR; |
30 | }
|
In dieser Lib hier springt mir nichts Verdächtiges ins Auge. Abgesehen von > #define F_CPU 8000000UL und > TWBR = 0x62; // Baud rate is set by calculating offensichtlich nichts timing-Relevantes. Und nichts, was mit der I2C-Adresse des Display-Treiber-ICs zu tun hat. (man darf mich gerne korrigieren, wenn ich falsch liege)
Wie auf Seite 46 zu sehen, muss das Delay zwischen die gesendeten Bytes. 15ms, 5ms, >100µs bzw 1ms. Peter_Michael schrieb: > Im einfachsten Fall könnte man vielleicht einfach > die Div/8-Fuse Reicht nicht. Es braucht Millisekunden. So lahm ist der Atmel nicht. Im einfachsten Fall ein ms-Delay nutzen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.