hallo Euch allen,... Ich habe auch ein Problem mit meinem I2C-Bus. Mein ATmega16 ist Master und hat einen MAX6956 (LED Treiber von Maxim) als Slave. Das programm wird komplett ausgeführt, so dass keine Fehlermeldung kommt. Jedoch bleiben trotzdem alle Leds dunkel. Verdrahtet ist alles wie auf der vorletzten seite im Datenbaltt beschrieben Leider ist das datenblatt mit seinen zig registern etwas unduchsichtig gestaltet, finde ich jedenfalls. Kannst du mir jemand dabei helfen, da ich den Treiber tringend bräuchte. Vielen Danke martin
Keine Panik die vielen Register schrecken erstmal ab, aber man braucht nur die wenigsten. Der Baustein ist eine "eierlegende Wollmilchsau". Wo hast du den Baustein denn her (Distributor)? Also du willst den Baustein als LED Treiber einsetzen, also mußt du erstmal die Ports dementsprechend konfigurieren. Dazu werden im Register 0x09..0x0F (alles auf 0x00 setzen) sowie 0x24..0x3F (alle auf 0x01) die Ports ensprechend konfiguriert. Jetzt muß du noch die Betriebsmodi konfigurieren. Du kannst dir aussuchen, ob du den Strom für alle LEDs gleichzeitig (Bit 6 im Register 0x04). Wenn du den Strom global regelst, solltest du in Register 0x02 einen Wert zw. 0..16 eintragen. Wenn du die Werte einzeln regelst, kannst du über die Register 0x12..0x1F auf jeweils 2 Ports (45,67,..) zugreifen. Die oberen 4 Bits sind der Wert für den einen Port, die untern 4 Bits für den anderen Port. Jetzt mußt du nur noch im Register 0x04 den Baustein aus dem Shutdown-Modus holen (Bit 0 auf eins). Also nochmal kurz: Jeder Port wird einzeln geregelt: Reg. 0x09..0x0F auf 0x00: LED-Treiber-Modus Reg. 0x24..0x3F auf 0x01: LED-Treiber-Modus (Register Bit) Reg. 0x12..0x1F auf 0xXY: X=0..16, Y=0..16 -> Strom einstellen Reg. 0x04 auf 0x41: Einzel-Strom + Normal-Mode Strom wird global geregelt: Reg. 0x09..0x0F auf 0x00: LED-Treiber-Modus Reg. 0x24..0x3F auf 0x01: LED-Treiber-Modus (Register Bit) Reg. 0x02 auf 0x0X: X=0..16 -> globalen Strom einstellen Reg. 0x04 auf 0x01: Globaler-Strom + Normal-Mode fertig...viel Spaß ;)
Hallo... also ich hab es wie im anhang dargestellt angeschlossen. Ich muss noch dazu sagen ich beschäftig mich erst seit kurzer Zeit Mit Microcontrollern und auch nur mit der Programmierung in C. danke erst mal
dir fehlen: - Schematic - Sourcecode damit dir irgendjemand helfen kann auf den ersten blick tipp ich mal du hast die I2c nicht richig implementiert, vl. auch nur eine falsch I2C Addresse. lg
Könnt Ihr mal über mein Programm drüberschauen, ob die Programmierung des I2C überhaut richtig ist. Ich hab den Quellcode aus dem Datenblatt vom ATmega16 auf seite 185 übernommen. Außerdem hatte ich Probleme mit den Variablen char START =0x08; char MT_SLA_ACK =0x18; char MT_DATA_ACK =0x28; die werte hab ich dann in einem anderem Forum gefunden.
Der Code ist ganz oben in meinem ersten Beitrag ... aber hier nochmal im anhang
Poste doch mal die Inititalisierungsroutine direkt in den Beitrag, z.B. so
1 | Hier deine Routine... |
Ich hab hier keine Rar-entpacker... Gruß Mario
1 | #include <avr/io.h> |
2 | #include <inttypes.h> |
3 | #include "belegung.h" |
4 | |
5 | //##########################################################
|
6 | char START =0x08; |
7 | char MT_SLA_ACK =0x18; |
8 | char MT_DATA_ACK =0x28; |
9 | int Fehler =0; |
10 | |
11 | //---------------------------------------------------------
|
12 | void ERROR(void) |
13 | {
|
14 | AnzeigePORT |= (1<<Fehler); |
15 | Fehler++; |
16 | }
|
17 | //#########################################################
|
18 | DATENPORT_DDR = 0b11111111; |
19 | AnzeigePORT_DDR = 0b11111111; |
20 | AnzeigePORT = 0b00000000; |
21 | DATENPORT = 0b11111111; |
22 | //-----------------------------------------------
|
23 | void I2CWrite(unsigned int SLA_W, unsigned int COMMAND, unsigned int |
24 | DATA) |
25 | {
|
26 | TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); |
27 | while (!(TWCR & (1<<TWINT))) |
28 | ;
|
29 | |
30 | if ((TWSR & 0xF8) != START) |
31 | {
|
32 | ERROR(); |
33 | }
|
34 | //---------------------------------------------SLAVE Adress
|
35 | TWDR = SLA_W; |
36 | while (!(TWCR & (1<<TWINT))) |
37 | ;
|
38 | if ((TWSR & 0xF8) != MT_SLA_ACK) |
39 | { ERROR(); |
40 | }
|
41 | //---------------------------------------------COMMAND
|
42 | TWDR = COMMAND; |
43 | TWCR = (1<<TWINT) | (1<<TWEN); |
44 | while (!(TWCR & (1<<TWINT))) |
45 | ;
|
46 | if ((TWSR & 0xF8) != MT_DATA_ACK) |
47 | {
|
48 | ERROR(); |
49 | }
|
50 | //-----------------------------------------------DATA
|
51 | TWDR = DATA; |
52 | TWCR = (1<<TWINT) | (1<<TWEN); |
53 | while (!(TWCR & (1<<TWINT))) |
54 | ;
|
55 | |
56 | if ((TWSR & 0xF8) != MT_DATA_ACK) |
57 | {
|
58 | ERROR(); |
59 | }
|
60 | TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); |
61 | }
|
62 | |
63 | //-------------------------------------------------------
|
64 | Programmschleife
|
65 | while(1) |
66 | {
|
67 | I2CWrite(0x80, 0x12, 0x07); // Set a half port P4 constant current |
68 | I2CWrite(0x80, 0x09, 0xA8); // Set P4 to LED drive mode |
69 | I2CWrite(0x80, 0x04, 0x01); // Set the shutdown/run |
70 | }
|
71 | }
|
Ich überblicke die I2C-Routine nicht so schnell, es sieht aber sehr nach "Spaghetti-Code" aus. Als erstes empfehle ich dir auf eine I2C-library zurückzugreifen, z.b. von Peter Fleury (http://jump.to/fleury). Unter "AVR Software - libraries" findest du das "I2C Master Interface". Einfach runterladen, twimaster.c und i2cmaster.h einbinden. Online Manual durchlesen und fertig. Danch würde ich schauen ob die I2C-slave-Adresse des Bausteins richtig ist (Pin AD0 und AD1 nachmessen). AD0 und AD1 müßten bei beide auf GND sein laut deinem Code (Adresse 0x80). Ein bisschen komisch ist, das du in der Hauptschleife den Baustein immer wieder initialisierst, Normalerweise läuft das so ab:
1 | void main() |
2 | {
|
3 | I2CWrite(0x80, 0x12, 0x07); // Set a half port P4 constant current |
4 | I2CWrite(0x80, 0x09, 0xA8); // Set P4 to LED drive mode |
5 | I2CWrite(0x80, 0x04, 0x01); // Set the shutdown/run |
6 | |
7 | while(1) |
8 | {
|
9 | // mach irgendwas oder auch nicht...
|
10 | }
|
11 | }
|
Gruß Mario
Du hattest außerdem gefragt was char START =0x08; char MT_SLA_ACK =0x18; char MT_DATA_ACK =0x28; bedeuten. Mit diesen defines setzt man die Start-condition bzw. das Acknowledge bzw. fragt das slace acknowledge ab. In der library brauchst du dich darum nicht mehr kümmern. Das würde man dann so machen:
1 | I2CWrite(uint8_t ADDR, uint8_t CMD, uint8_t DATA) |
2 | {
|
3 | i2c_start_wait(ADDR+I2C_WRITE); // set device address and write mode |
4 | i2c_write(COMMAND); // write command |
5 | i2c_write(DATA); // write data |
6 | i2c_stop(); // set stop conditon = release bus |
7 | }
|
8 | |
9 | void main() |
10 | {
|
11 | i2c_init(); // initialize I2C library |
12 | |
13 | I2CWrite(0x80, 0x12, 0x07); // Set a half port P4 constant current |
14 | I2CWrite(0x80, 0x09, 0xA8); // Set P4 to LED drive mode |
15 | I2CWrite(0x80, 0x04, 0x01); // Set the shutdown/run |
16 | |
17 | while(1) |
18 | {
|
19 | // tu was
|
20 | }
|
21 | }
|
Ob die Register richt gesetzt mußt noch mal in meinen oberen Post gucken... Gruß Mario
ohne jetzt deinen ganzen Code durchzuschauen, überprüfe mal ob du die LEDs überhaupt angeschaltet hast. Ich habe mal mit dem MAX6957 gemacht (der gleiche Baustein mit SPI) und hatte auch alles schön initialisiert, hatte aber vergessen die LEDs anzuschalten. Du musst demnach die Ausgänge als LEDs initialisieren, einen Wert für die LED Helligkeit setzen UND die LEDs einschalten Gruß Kai
@Kai Franke und Martin Juha, wo habt ihr denn die Bausteine bezogen? Samples?
Also ich denke richtig wäre die Initialisierung so:
1 | // Port 12..21 als LED-Treiber konfigurieren
|
2 | I2CWrite(0x80, 0x0A, 0x00); // Port 12..15 als LED-Treiber |
3 | I2CWrite(0x80, 0x0B, 0x00); // Port 16..19 als LED-Treiber |
4 | I2CWrite(0x80, 0x0C, 0xA0); // Port 20..21 als LED-Treiber (22..23 Input) |
5 | |
6 | // Port 12..21 einschalten (Register bit)
|
7 | I2CWrite(0x80, 0x2C, 0x01); // LED Port 12 einschalten |
8 | I2CWrite(0x80, 0x2D, 0x01); // LED Port 13 einschalten |
9 | I2CWrite(0x80, 0x2E, 0x01); // LED Port 14 einschalten |
10 | I2CWrite(0x80, 0x2F, 0x01); // LED Port 15 einschalten |
11 | I2CWrite(0x80, 0x30, 0x01); // LED Port 16 einschalten |
12 | I2CWrite(0x80, 0x31, 0x01); // LED Port 17 einschalten |
13 | I2CWrite(0x80, 0x32, 0x01); // LED Port 18 einschalten |
14 | I2CWrite(0x80, 0x33, 0x01); // LED Port 19 einschalten |
15 | I2CWrite(0x80, 0x34, 0x01); // LED Port 20 einschalten |
16 | I2CWrite(0x80, 0x35, 0x01); // LED Port 21 einschalten |
17 | |
18 | // Port 12..21 Strom einstellen
|
19 | I2CWrite(0x80, 0x16, 0x88); // Strom Port 12..13 auf Mitte (13.5mA) |
20 | I2CWrite(0x80, 0x17, 0x88); // Strom Port 14..15 auf Mitte (13.5mA) |
21 | I2CWrite(0x80, 0x18, 0x88); // Strom Port 16..17 auf Mitte (13.5mA) |
22 | I2CWrite(0x80, 0x19, 0x88); // Strom Port 18..19 auf Mitte (13.5mA) |
23 | I2CWrite(0x80, 0x1A, 0x88); // Strom Port 20..21 auf Mitte (13.5mA) |
24 | |
25 | // Global Settings
|
26 | I2CWrite(0x80, 0x04, 0x41); // Einzel Strom + Normal Mode |
27 | |
28 | // fertig...
|
so müsste es gehen...
ja, ich habe die Treiber gesampled, war allerdings nicht wirklich zufrieden damit. Die ganzen Register machen einem das Leben sehr schwer, das Programm langsam und wenn man sie kaufen will (digikey) kann man auch gleich einen Goldesel mitbestellen... Ich bin daher auf die TLC5922 umgestiegen, die wesentlich billiger sind und auch viel einfacher und SCHNELLER anzusteuern sind. Dort gibt es keine Register, man schiebt einfach immer alle Helligkeitswerte in das Register. Noch ein großer Vorteil ist, dass man bei den TLCs mit dem Helligkeitswert 0 die LED tatsächlich auch ausschaltet. Bei den MAX6956/57 ist das nicht so! Die Helligkeit 0 ist dort 1/16 der maximalen Helligkeit, was mir ebenfalls nicht gefallen hat... Gruß Kai PS: Die Initialisierung scheint vollständig
@Kai Franke: Kannst du mal kurz beschreiben wie du den Baustein ansteuerst?
Hallo und erst mal vielen Danke für die schnelle hilfe und werd das heut abend noch alles probieren. Ich wollt keine fertige library nehmen, da ich ja uach verstehen will was das program macht und all die funktionn, die ich nicht brauch muss ich ja nicht mit auf den MC schieben... ist ja unnötiger speicher verbrauch. Der COde von mir ist der AUs dem ATmega16 datenblatt seite 184. aber gut ich versuch das mal mit der library. kann mir das zur Sicherheit noch jemand fertig reinstellen, damit ich was zum vergleichen hab? Als zip datei oder so? Wär super. VIelen Dank Martin
@Martin: Nimm lieder die Library, ist keine Schande. Die Lib ist sehr schlank und universell einsetzbar. Der Code steht doch schon in den vorigen Posts. Du mußt nur in deinem Hauptprogramm die i2cmaster.h includen, die twimaster.c deinem Projekt hinzufügen. Dann als erstes im Hauptprogramm die i2c_init() aufrufen und dann alles initialisieren, danach Endlosschleife oder was auch immer. Bei der I2C-Lib ist auch ein Bsp dabei welches du entsprechend abändern kannst. Ich finde die Hilfe geht schon sehr weit, ich möchte aber nicht dein Programm schreiben. Einfach mal Datenblatt in Ruhe lesen (vielleicht mal ausdrucken) und dann versteht man das auch. Sonst ist ja kein Lerneffekt dabei... :) btw, wo hast du die Bausteinchen her, auch gesampelt? @Kai Franke: wenn du den gesampleten MAX6956 nicht mehr brauchst, könntest du mir den überlassen (ich würd Brief mit Rückporto schicken...)
den abustein hab ich auch gesampelt... und da ich nicht dachte das das funktioniert, da der mir nen fehler angezeigt hat, hab ich jetzt 4 mal von denen post bekommen mit je 4 bausteinen... also ich denk die reichen für die nächsten 10 projekte ;-) vielen dank für alles
>>@Kai Franke: >>Kannst du mal kurz beschreiben wie du den Baustein ansteuerst? Klar! Der IC hat einen Modus Pin. Je nachdem ob dieser HIGH oder LOW ist kann man entweder die Helligkeit der LEDs verändern oder bestimmen welche LEDs an sein sollen und welche aus. Wenn man AN/AUS einstellen will schiebt man einfach 16 Bit (ein Bit pro LED) in den Treiber rein, wobei eine 1 die LED anschaltet und eine 0 die LED ausschaltet. Sollte man die Helligkeit verändern wollen muss man 112 Bit reinschieben. Diese setzen sich zusammen aus 16 LEDs mit je 7 Bit (128 Stufen) also 16*7. Das wars auch schon. Das tolle ist, dass man mit diesen 112 Bit bzw 14 Byte die Helligkeit aller LEDs verändert hat. >> gibt es den auch mit I2C? da bin ich überfragt, was spricht gegen SPI? >> wenn du den gesampleten MAX6956 nicht mehr brauchst, könntest du mir den >> überlassen (ich würd Brief mit Rückporto schicken...) wie aus meinem obigen Post erkennbar sein sollte, habe ich nur mit dem MAX6957 herumexperimentiert, diesen kann ich aber gerne weiterverschenken Gruß Kai
Wegen dem MAX6956 einfach auf die seite ... http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3503/t/al und dort unter Samples bestellen. Dauert ca. 1,5 wochen. Am besten mehrmals bestellen, da es nicht immer angenommen wird. Es gibt den Max6956 einmal mit 28pins und mit 36pins. Für die Bestellung wird eine anmeldung benötigt, die aber nur die Lieferadresse erfordert. Viel Erfolg
leuchtet immernoch keine LED? wenn das so ist könnte der IC kaputt sein oder die LEDs falsch herum angeschlossen... das sind doch Common Anode LEDs oder? Der Treiber kann nämlich nur nach GND regeln
@Kai + Martin: Ich hab jetzt auch Samples bestellt bei Maxim, mal sehen wie viele ich bekomme (hab 20 bestellt :) Mir schwebt da nämlich schon länger ein Projekt im Kopf rum: Eine große Wand aus LEDs (16 x 20), die sich wie ein Display ansprechen lassen (Animationen, Arcade-Spiele). Wurde alles schon gebaut... finds aber trotzdem lustig. Da könnt ich mir den MAX6956 gut vorstellen. Bei 16 MAX6956 á 20 LEDs komme ich auf ca. 7.2ms max. Wiederholrate, sollte also ausreichen. So schnell muß man ja eh nicht sein, da die LED eben durch den Baustein aktiv angesteuert werden und die viele Bilder (zm. teilweise) quasistatisch sind. I2C scheint mir irgendwie einfach als SPI, weiß auch nicht warum. Ein kollege von mir hatte kürzlich große Probleme SPI ans laufen zu kriegen. Ist vielleicht aber auch einfach nur irgendwie so ein Gefühl... @Kai: wie schiebst eigentlich immer 7 Bit raus. Ich dachte das SPI Register ist auch 8 Bit und die werden dann auch ad hoc rausgeschoben. Ich stelle es mir schwierig vor das als kontinuierlichen Datenstrom hinzubekommen....
wieso 7 Bit? 16*7 Bit = 112Bit 112Bit / 8 = 14 Byte ich schiebe also immer nur 14 Byte raus solange du die "Wand" mit einfarbigen LEDs machst, könnte das reichen, sollten es jedoch RGB werden, wird das ganze sehr knapp vom Timing her... Ich verstehe jetzt jedoch nicht warum du die MAX6956 nimmst und nicht die TLC. Wenn du das nur machst, weil du die MAX umsonst bekommst, wirst du dich spätestens bei der Ansteuerung ärgern, wenn du dich mit den Registern herumschlagen musst und immer abfragen musst ob die LED nicht vielleicht doch aus ist und du dann auch noch die AN/AUS Werte verändern musst. Ich verstehe es wenn man sich ICs sampled und damit Testaufbauten macht um mal etwas auszuprobieren, aber wenn man sich ein ganzes Projekt zusammensampled ist das nur noch Schmarotzen. Naja... meine Meinung Wünsche dir trotzdem viel Spaß beim Basteln Kai
Ich hab jetzt weiter rum probiert und die Library vom Peter mit eingebunden... aber es geht trotzdem nichts. Es kommen zwar Signale am SCL SDA an aber diese werde nicht weiter verarbeitet. Was auch immer das heißen mag. Vielleicht kann ja mal von euch einer das programm durch probieren oder auf einem Max6956 zum laufen bringen, mir ist egal was am ende leuchtet hauptsache es funktioniert!!! Vielen dank. Achso wegen Format problemen diesmal als.... zip Dateí
das hatte ich erst , aber geht auch nicht... also wenn du die adresse aus dem datenblatt nimmst, hast du ja die 0x40 und wenn du dann noch das R/W Bit dazu nimmst... wird die 0x80 daraus! i2c_start_wait(ADDR+I2C_WRITE); oder seh ich das falsch?
wenn ich das compiliere, beim erstellen der eep datei folgender ausdruck, be allen anderen datein verläuft alles normal! Creating load file for EEPROM: MAXSteuerung.eep avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ --change-section-lma .eeprom=0 -O ihex MAXSteuerung.elf MAXSteuerung.eep c:\Programme\Atmel\bin\avr-objcopy.exe: there are no sections to be copied! c:\Programme\Atmel\bin\avr-objcopy.exe: --change-section-lma .eeprom=0x00000000 never used make.exe: [MAXSteuerung.eep] Error 1 (ignored)
du erzeugst ein EEPROM-file. legst du irgendweelche Daten im EEPROM ab? zu der 0x80, suche mal in der Forumsuche nach "MAX6956" und dann der erste Forumslink ("I2C & ATmega16 & MAX6956"), da stehts. Ich habe leider noch keine Hardware zum ausprobieren. Mir ist noch was in deinem Schaltplan aufgefallen. Für I2C brauchst du noch Pull-up Widerstände in der SDA und SCL - Leitung (4.7kOhm sollte gehen).
wenn du willst kann ich dir auch so einen max zu schicken ,dann hast du ihn schon morgen... daten leg ich nicht drin ab, aber bei den anderen programmen kam da nie der fehler... ok ich probiers mal mit der 0x80 die widerstände mach ich auch noch dazwischen
gehn auch 5,1 KOhm hab grad nix anderes hier... warum steht von den dirngern nirgends was auf den schaltplänen? hab bisher noch keinen plan mit diesen widerstnden gefunden
@Martin: Ich habe mir grad selbst Samples bestellt (s. obiger Post). dann kann ich auch praktisch mitreden :) Mein Problem ist eher die Zeit zum basteln... 5,1k geht auch, üblicherweise nimmt man irgendwas zwischen 4,7k und 10k, je nach Leitungslänge + kapazität. Die Pull-ups sind aber unbedingt notwendig, da die I2C-Schnittstelle Open-Drain ist. Steht übrigens auch im Atmega16 Datenblatt (auf S.172 und Tabelle S.294 (Rp - Value of Pull-up Resistor))... @Kai: Wenn es mit den MAX6956 nicht klappt, komm ich nochmal auf den TLC5922 zurück. Der Weg ist das Ziel... :) Nochmal zu deiner Ansteuerung: Die 16*7 Bit = 14 Byte mußt du ja aber vorher irgendwie bündig in einem Array zusammenbauen, oder? Kannst du mir mal die Funktion dafür posten? So interessehalber...
funktionieren tut nix ... aber was soll ich machen bin immer noch in der selben situation wie im vorletzten Post. aber ich gebs langsam auf obwohl ich das ding dringend für in projekt brauch!
trotz den widerständen hat sich nix geändert achso die bestellung der samples dauert ca 2 wochen wenn nicht sogar noch länger
dann schick mir doch mal so einen baustein, ich versuchs dann mal auf dem steckbrett...
hallo an alle, ich benutze den TLC5922 für eine RGB Propellerclock aus 40 RGB LEDs. Für das Umrechnen in ein Array habe ich ein Visual Basic Programm geschrieben in das ich ein Bitmap laden kann, den richtigen Teilausschnitt aussuchen kann und dann das ganze in eine compilierte Hex Datei umforme, die mein SD Card Bootloader frisst. Das Programm ist fertig, allerdings noch nicht getestet, da ich noch auf die Platinen für den Prototyp warte. Wenn das ganze fertig ist, werde ich alle Dateien mal hochladen, wenn du es eilig hast kann ich dir auch die noch nicht getestete Version zuschicken. Die TLCs hab ich übrigens bei digikey bestellt Ich habe auch schon ein Codebeispiel in der Codesammlung hochgeladen, einfach mal nach TLC5922 suchen. Da ist eine Lauflichtfunktion und ein sanfter Farbübergang dabei. Gruß Kai
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.