Forum: Compiler & IDEs AVR Studio 4: TWI Display einbinden


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Peter_Michael (Gast)


Lesenswert?

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.

von Peter_Michael (Gast)


Lesenswert?

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.

von Horst (Gast)


Lesenswert?

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.

von Peter_Michael (Gast)


Angehängte Dateien:

Lesenswert?

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?

von Peter_Michael (Gast)


Lesenswert?

Niemand mehr eine Idee dazu?

von jo mei (Gast)


Lesenswert?

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.

von jo mei (Gast)


Angehängte Dateien:

Lesenswert?

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)

von Oliver S. (oliverso)


Lesenswert?

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

von Peter_Michael (Gast)


Lesenswert?

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?

von Hugo H. (hugohurtig1)


Lesenswert?

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
von Peter_Michael (Gast)


Lesenswert?

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.

von Peter_Michael (Gast)


Lesenswert?

Hugo H. schrieb:
> 15.10.2020 18:16:
>     Bearbeitet durch User
Ah, wir haben uns überschnitten.

von Hugo H. (hugohurtig1)


Lesenswert?

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
von pegel (Gast)


Lesenswert?

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

von Peter_Michael (Gast)


Lesenswert?

Ihr seid super, vielen Dank! :)))

Beitrag #6445938 wurde vom Autor gelöscht.
von Peter_Michael (Gast)


Angehängte Dateien:

Lesenswert?

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?

von pegel (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Oliver S. (oliverso)


Lesenswert?

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

von Peter_Michael (Gast)


Lesenswert?

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

von Peter_Michael (Gast)


Lesenswert?

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.

von Joachim B. (jar)


Lesenswert?

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
von Peter_Michael (Gast)


Lesenswert?

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

von Oliver S. (oliverso)


Lesenswert?

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

von Peter_Michael (Gast)


Lesenswert?

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.

von Oliver S. (oliverso)


Lesenswert?

;)

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

von Thomas Z. (usbman)


Lesenswert?

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.

von Joachim B. (jar)


Lesenswert?

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

von pegel (Gast)


Lesenswert?

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.

von pegel (Gast)


Lesenswert?

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.

von pegel (Gast)


Lesenswert?


von Peter_Michael (Gast)


Lesenswert?

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:

von Peter_Michael (Gast)


Lesenswert?

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)

von pegel (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.