Hallo zusammen, ich möchte mit einem tiny44 einen PT2257 Digitalpoti steuern. SDA, SCL laufen, die USI routine kommt bis zu dem Punkt, wo der Slave die Adresse ACKen soll - macht er aber nicht (laut Rückmeldung der Routine fehlt das ACK), weil auf dem Oszi ersichtlich nicht die im define angegebene 0x88 übertragen wird - habe ich bei der lib nach AVR-310 etwas verpasst? Klaus.
...wie man erkennt, ist bei den daten zml zu beginn ein kurzer peak - DAS scheint bereits die erste 1 zu sein von 0b10001000 - aber ist das korrekt? Müsste die routine nicht warten, bis clk = 0 ist und wieder auf 1 geht (also rising edge)? denn es kommen ja noch 8x clk HIGH für daten + 1x clk HIGH für ACK...? Leigt das an der recht geringen clk von 10kHz? Klaus.
Klaus R. schrieb: >Müsste die routine nicht warten, bis clk = 0 ist und wieder auf >1 geht (also rising edge)? Normalerweise schon. Zuerst die Startbedingung (die sieht noch OK aus) "The SCL is set to HIGH and SDA shifts from HIGH to LOW state." dann SCL->L, SDA->MSB(Adresse), SCL->H... > Leigt das an der recht geringen clk von 10kHz? lt. DB gibt es keine untere Grenze für fclk. Eventuell übersehen, den Standard-Modus im Programm zu aktivieren "The default setting is fast mode"? Und warum hat SCL nur 2V, während SDA 4V hat. Das liegt zwar noch knapp innerhalt der Spezifikation von Vih=1,6V (Vdd=4V), aber ich würde dennoch die Pullup-Widerstände prüfen - besonders, wenn die Vdd höher sein sollte. http://www.princeton.com.tw/Portals/0/Product/PT2257.pdf
hofa schrieb: > Und warum hat SCL nur 2V, während SDA 4V hat. Und warum hat SDA nur 2V, während SCL 4V hat? Und warum seh ich das erst nach dem Absenden?
@hofa: Weil die Bezugspotentiale vertikal verschoben sind auf dem Oszi? :) FastMode habe ich abgeschaltet, klar...SCL läuft mit 11kHz derzeit. Ich frage mich aber, wie es passieren kann, dass SDA schon kurz nach dem Startup auf high geht, "der" müsste doch bis zur ersten clock warten mit der Übertragung...hmmm. Klaus.
Hi >Ich frage mich aber, wie es passieren kann, dass SDA schon kurz nach dem >Startup auf high geht, "der" müsste doch bis zur ersten clock warten mit >der Übertragung...hmmm. High ist der Ruhepegel von SDA/SCL. MfG Spess
Teil doch mal deinen Code mit uns. Da wird man dann schon sehen wo es hakt
Hallo Max D., poste ich heute Abend gerne, habe ich aber direkt bei Atmel runtergeladen. Irgendwie reagiert die USI_Master.c nicht so, wie sie soll. @spess: Das ist mir schon klar, aber mit "high" versucht die funktion ja die erste 1 der Adresse 0x88 (10001000) des Potis zu übertragen - und das dürfte sie mMn erst beim darauf folgenden clockzyklus tun. Klaus.
Hi >@spess: Das ist mir schon klar, aber mit "high" versucht die funktion ja >die erste 1 der Adresse 0x88 (10001000) des Potis zu übertragen - und >das dürfte sie mMn erst beim darauf folgenden clockzyklus tun. Die Übertragung beginnt mit der Startcondition -> fallende Flanke von SDA bei High an SCL. MfG Spess
Hallo spess, aber der Nadelimpuls, der ja scheinbar die erste 1 der Adresse sein soll, ist der nicht auch deiner meinung nach an der falschen Position? Ich würde erwarten, dass SDA low bliebt bis SCL auf high geht und DANN das MSB übertragen wird, also um einen clk zyklus nach rechts verschoben - und vor allem nicht nur als kurzer impuls. der 9 clk zyklus, in dem der slave die adresse ACKen soll (SDA low ziehen), sieht man in dem bild nicht - der kommt aber auch noch. Klaus.
Der Nadelpuls ist ein Ack vom Slave... Das Bild ist nicht vollständig.... Wahrscheinlich bestätigt der Slave hier schon die Adresse. Gruß Marv
Hallo Marvin, die Adresse kommt danach - davor ist Ruhe und wenn ich diese auf 10101010 setze, sehe ich das Muster genau hier in dem screenshot. Das ACK muss (müsste?) mit dem 9 clk kommen, der ist aber rechts außen - und, der ACK kommt natürlich nicht, da die Adresse ja so nicht stimmt. Es geht mir primär darum, ob ich das richtig verstehe - ich werde das originale bsp mal so laufen lassen, wie ich es von avr runtergalden habe - nur um zu sehen, ob es sich dann auch so verhält...wobei es "eigentlich" auch nicht für einen tiny44 geschrieben wurde, ich musste es anpassen. Klaus.
Hi >aber der Nadelimpuls, der ja scheinbar die erste 1 der Adresse sein >soll, ist der nicht auch deiner meinung nach an der falschen Position? Das passt aber nicht zu dem H ( beim Senden von 0b10001000) in der Mitte. Das liegt im 4.Bit. Außerdem ist der Spike für mich kein Bit. SDA darf sich in der Low-Phase von SCL ändern. Wo der Spike genau liegt kann ich an Hand des Bildes nicht entscheiden. Hast du dir mal 'Atmel AVR310: Using the USI Module as a I2C Master http://www.atmel.com/Images/Atmel-2561-Using-the-USI-Module-as-a-I2C-Master_AP-Note_AVR310.pdf http://www.atmel.com/images/Atmel-2561-Using-the-USI-Module-as-a-I2C-Master_AP-Note_AVR310.zip angesehen? MfG Spess
Klaus2 schrieb: > @hofa: Weil die Bezugspotentiale vertikal verschoben sind auf dem Oszi? Und ich dachte, das blaue "2->" am linken Rand markiert die Nulllinie, während "CH2 2.00V" die Volt/Div angibt.
@hofa: Hoppala. In der Tat, mea culpa...das muss ich mir mal ansehen. @spess: Durchgelesen, nein. Angeschaut, ja. Der Code, den ich benutze, basiert ja direkt auf dieser AN. Mein "verständnis" für die Adressierung, datenübertragung etc habe ich nur aus dem PT2257 DB, da dort ja auch die anderen, wichtigen daten drinstehen. Deine Aussage ist genau, was ich meine - der Spike dürfte DA nicht sein, er muss als sauberer Impuls erst mit dem nächsten scl zyklus beginnen - dann rutscht auch der nachfolgende (saubere) sda puls auf bit 5 und alles passt -> 10001000 Ich vermute, dass das triggern "jetzt sende das erste datenbit der adresse" in der routine zur AN-310 irgendwie nicht ganz sauber läuft und halt während der noch aktiven start-condition startet, also nicht wartet, bis der erste "echte" clk impuls zur datenübertragung kommt...ich poste die stelle nacher mal. Als nächstes muss ich den code mal auf einem attiny85 mit einem i2c eeprom laufen lassen, damit ich vergleichen kann, ob es da genau so ist (dafür wurde sie urspr geschrieben). Klaus.
Hallo zusammen, 1) mit 4V läuft das Teil nicht sauber, damit wird SDA nicht richtig freigegeben und vom PT2257 immer halbseiden auf Masse gezogen, hmpf. Spg auf 4,5V erhöht, nun ist auch der blaue SDA Signalverlauf 0/4.5V 2) Code:
1 | #if defined (__AVR_ATtiny44__) // ATtiny44
|
2 | |
3 | OCR1A = (F_CPU / F_INTERRUPTS) - 1; // compare value: 1/15000 of CPU frequency |
4 | TCCR1A = (0 << WGM11) | (0 << WGM10); // switch CTC Mode on |
5 | TCCR1B = (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10); // switch CTC Mode on, set prescaler to 1 |
6 | |
7 | |
8 | #if defined (__AVR_ATmega8__)
|
9 | // ATmegaXX:
|
10 | OCR1A = (F_CPU / F_INTERRUPTS) - 1; // compare value: 1/15000 of CPU frequency |
11 | TCCR1B = (1 << WGM12) | (1 << CS10); // switch CTC Mode on, set prescaler to 1 |
12 | #endif
|
13 | |
14 | #else
|
15 | # ERROR No valid device configured!
|
16 | #endif
|
17 | |
18 | #ifdef TIMSK1
|
19 | TIMSK1 = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare |
20 | #else
|
21 | TIMSK = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare |
22 | #endif
|
23 | }
|
24 | |
25 | #ifdef TIM1_COMPA_vect // ATtiny84
|
26 | #define COMPA_VECT TIM1_COMPA_vect
|
27 | #else
|
28 | #define COMPA_VECT TIMER1_COMPA_vect // ATmega
|
29 | #endif
|
30 | |
31 | ...
|
32 | |
33 | void I2C_send (unsigned int data_01, unsigned int data_02) { |
34 | |
35 | unsigned int temp=TRUE, error=0; |
36 | |
37 | messageBuf[0] = (I2C_SLAVE_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); // Adresse |
38 | messageBuf[1] = data_01; // Daten_01 |
39 | messageBuf[2] = data_02; // Daten_02 |
40 | |
41 | temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3); // Senderoutine mit "messageBuf" aufrufen |
42 | error = USI_TWI_Get_State_Info(); |
43 | |
44 | if(temp == TRUE) PORTA ^= 1<<FREQ_UP; |
45 | if(error) eeprom_write_word(&ee_errorcode, error); |
46 | |
47 | }
|
48 | |
49 | ...
|
50 | |
51 | I2C_send (VOL_01, VOL_02); // Aufruf im main |
52 | |
53 | ...
|
Das sind die wichtigen Inhlate der Main, .c und .h der USI siehe Anhang, wie gesagt direkt aus der von Atmel runtergeladenen lib. Problematisch scheint für mich diese Stelle (Ln 147 der .c) zu sein, wo nach erfolgreicher Start-Condition das erste Datenbit gesendet wird - ich glaube nicht, dass der Code an sich falsch ist, aber mir ist nicht klar, wie es zu dem bei mir ersichtlichen Fehler kommen kann...Signal Verify ist aktiv und wirft keinen Fehler, dann aber "USI_TWI_NO_ACK_ON_ADDRESS;" - zu Recht, was man ja am Oszi-Bild sieht...
1 | #ifdef SIGNAL_VERIFY
|
2 | if( !(USISR & (1<<USISIF)) ) |
3 | {
|
4 | USI_TWI_state.errorState = USI_TWI_MISSING_START_CON; |
5 | return (FALSE); |
6 | }
|
7 | #endif
|
8 | |
9 | /*Write address and Read/Write data */
|
10 | do
|
11 | {
|
12 | /* If masterWrite cycle (or inital address tranmission)*/
|
13 | if (USI_TWI_state.addressMode || USI_TWI_state.masterWriteDataMode) |
14 | {
|
15 | /* Write a byte */
|
16 | PORT_USI &= ~(1<<PIN_USI_SCL); // Pull SCL LOW. |
17 | USIDR = *(msg++); // Setup data. |
18 | USI_TWI_Master_Transfer( tempUSISR_8bit ); // Send 8 bits on bus. |
19 | |
20 | /* Clock and verify (N)ACK from slave */
|
21 | DDR_USI &= ~(1<<PIN_USI_SDA); // Enable SDA as input. |
22 | if( USI_TWI_Master_Transfer( tempUSISR_1bit ) & (1<<TWI_NACK_BIT) ) |
23 | {
|
24 | if ( USI_TWI_state.addressMode ) |
25 | USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS; |
26 | else
|
27 | USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA; |
28 | return (FALSE); |
29 | }
|
30 | USI_TWI_state.addressMode = FALSE; // Only perform address transmission once. |
31 | }
|
32 | /* Else masterRead cycle*/
|
33 | else
|
34 | {
|
35 | /* Read a data byte */
|
36 | DDR_USI &= ~(1<<PIN_USI_SDA); // Enable SDA as input. |
37 | *(msg++) = USI_TWI_Master_Transfer( tempUSISR_8bit ); |
38 | |
39 | /* Prepare to generate ACK (or NACK in case of End Of Transmission) */
|
40 | if( msgSize == 1) // If transmission of last byte was performed. |
41 | {
|
42 | USIDR = 0xFF; // Load NACK to confirm End Of Transmission. |
43 | }
|
44 | else
|
45 | {
|
46 | USIDR = 0x00; // Load ACK. Set data register bit 7 (output for SDA) low. |
47 | }
|
48 | USI_TWI_Master_Transfer( tempUSISR_1bit ); // Generate ACK/NACK. |
49 | }
|
50 | }while( --msgSize) ; // Until all data sent/received. |
:
Bearbeitet durch User
...und im Anhang mal ein erklärendes Bild,wie zB 0xC0 übertragen werden sollte - genau so erwarte ich das mit 0x88 auch, kommt es aber nicht. Das ist das letzte Puzzleteil in meiner Steuerung eines HK330C, damit ihr wisst, worums geht - alles für den WAF eines Vintage Receivers. Klaus.
...ja f*ck die Henne. Wenn ich die Adresse um 1 shifte, dann gehts, also statt 0x88 = 0b10001000 schreibe ich 0b01000100, dann läuft es, wie es aussieht - muss nun testen, ob das Poti was tut - zumindest überträgt er jetzt 3 Byte und bricht NICHT ab...kann mir das bitte mal einer erklären? EDIT: Das Poti loooft, ich werd verrückt...das kommt davon, wenn man beschissen dokumentierten Code aus LCCs weiterverwendet - genau wie auf der Maloche. Klaus.
:
Bearbeitet durch User
Hi >...ja f*ck die Henne. Wenn ich die Adresse um 1 shifte, dann gehts, also >statt 0x88 = 0b10001000 schreibe ich 0b01000100, dann läuft es, wie es >aussieht Deine main.c erwartet einfach die 7-Bit-Adresse ohne das RW-Bit (Bit0) und shiftet die selbstständig nach Bit7..Bit1: messageBuf[0] = (I2C_SLAVE_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MfG Spess
Klaus R. schrieb: > ...ja f*ck die Henne. Wenn ich die Adresse um 1 shifte, dann gehts, also > statt 0x88 = 0b10001000 schreibe ich 0b01000100 Kein Wunder. 0x88 kann es nicht als I2C Adresse geben, weil die nur sieben Bit lang ist und damit dein oberstes Bit hinten runter fliegt.
...ist mir jetzt auch klar geworden, aber das hätte Ranjid da vll auch kurz per Randnotiz anmerken können, finde ich. Denn, de facto ist das ja NICHT die "normale" Adresse des Slaves. Das ist immerhin offizieller Code zu einer AN, nicht vom Software-AG-Server der 9b geklaut. Klaus.
...Tom, dann guck mal ins DB des PT2257, das steht klipp & klar 0x88. Aber ich habe dazu gelernt und deshalb macht man ja :) Klaus.
Hi >Kein Wunder. 0x88 kann es nicht als I2C Adresse geben, weil die nur >sieben Bit lang ist und damit dein oberstes Bit hinten runter fliegt. Das ist eine Frage der Implementierung. Aber darüber wurden hier schon Glaubeskriege geführt. Mit deiner Ansicht könnte das wieder losgehen. MfG Spess
Hehe :) Nein, ein Glaubenskrieg auf der Welt reicht, Danke. Ich bin durch mit dem Thema und wie immer hat einmal drüber Schlafen zum Erfolg geführt. Danke an Alle & GN8.
Hi >Ich bin durch mit dem Thema und wie immer hat einmal drüber Schlafen zum >Erfolg geführt. Hättest dir auch einfach mal deinen Quelltext ansehen können. Das steht doch eindeutig messageBuf[0] = (I2C_SLAVE_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); und in der USI_TWI_Master.h #define TWI_ADR_BITS 1 // Bit position for LSB of the slave address bits in the init byte. Also wird das Adressbyte um 1 Bit nach links geshiftet. Bei 0x100100 geht dann halt ein Bit verloren. MfG Spess
Hi spess, ich hätte es plausibilisieren können, ja - es ist aber nicht mein Quellcode, ich habe eine lib benutzt. Und in dieser wird ganz am Anfang ein define gesetzt, hinter dem steht "// Slave Adress" - im PT2257 steht "Adress 0x88" - ergo...da stand nirgends, dass man nur die oberen 7 Bits eintragen darf. Würde ich die libs auf der Arbeit aus dem repository auschecken und dann erst komplett "reviewen" müssen, würden wir ja nie fertig. Saubere Doku ist das A&O und ICH hätte den "7 Bit Hinweis" dort hinterlassen ODER das shifting dann in der nächsten Zeile automatisiert. Klaus.
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.