Forum: Mikrocontroller und Digitale Elektronik xmega und DS1307


von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

Hi

ich versuche einen DS1307 mit einem ATXMEGA zum laufen zu bringen.
Da ich zum ersten mal einen ic2 finde bin ich hier allerdins noch nicht 
so fit. Pull Up Widerstände habe ich an 3,3V angeschlossen.
Kann mir jemand sagen, wieso meine Variable zwischenwert immer 0 bleibt?
irgendwas Grundlegendes muss ich falsch machen^^
1
void TWI_MasterInit(TWI_t *twi)
2
{
3
  twi->MASTER.BAUD = TWI_BAUDRATE;
4
  twi->MASTER.CTRLA = TWI_MASTER_ENABLE_bm |
5
  TWI_MASTER_INTLVL_HI_gc |
6
  TWI_MASTER_RIEN_bm |
7
  TWI_MASTER_WIEN_bm;
8
  twi->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
9
}
10
11
void TWI_Send_Address(TWI_t *twi, char Adresse, char RW)
12
{
13
  twi->MASTER.ADDR = (Adresse << 1) + RW;
14
}
15
16
int main(void)
17
{
18
  sei();//Globale Interrruptfreigabe
19
  PMIC.CTRL |= PMIC_HILVLEN_bm|PMIC_MEDLVLEN_bm|PMIC_LOLVLEN_bm;
20
  
21
  Clock_init();
22
23
       //Uhr starten
24
  TWI_Send_Address(&TWIE, DS1307, 0); //schreiben
25
  _delay_us(500);
26
  TWIE.MASTER.DATA = 00; //Sekunden
27
  _delay_us(500);
28
  TWIE.MASTER.DATA = 80; //Uhr starteb
29
  _delay_us(500);
30
  TWIE.MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
31
  _delay_us(500);
32
  
33
  //----------------------------------
34
  //Register Pointer setzen
35
  
36
  TWI_Send_Address(&TWIE, DS1307, 0); //schreiben
37
  _delay_us(500);
38
  TWIE.MASTER.DATA = 0x00;//Sekunden
39
  _delay_us(500);
40
  TWIE.MASTER.CTRLC = TWI_MASTER_CMD_REPSTART_gc;
41
  _delay_us(500);
42
  
43
  TWI_Send_Address(&TWIE, DS1307, 1); //lesen
44
  _delay_us(500);
45
  zwischenwert = TWIE.MASTER.DATA; 
46
  _delay_us(500);
47
  set_bit(TWIE.MASTER.CTRLC, 2);
48
  _delay_us(500);
49
   
50
  TWIE.MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
51
  _delay_us(500);
52
53
}

von Thomas (Gast)


Lesenswert?

hab das hier vergessen in den Kommentar zu schreiben.

Sieht jemand was ich falsch mache? :-P
1
//defines für i2c
2
#define Taktfrequenz 32000000
3
#define Takt_TWI 80000
4
#define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)
5
#define TWI_BAUDRATE TWI_BAUD(Taktfrequenz, Takt_TWI)
6
#define DS1307 0x68 //Adresse des DS1307

von Dieter F. (Gast)


Lesenswert?

Wo rufst du denn

TWI_MasterInit( ...

auf?

von Thomas (Gast)


Lesenswert?

nach clock init.
Ich habe die Zeilen, welche nichts mit i2c zu tun haben hier nicht 
mitkopiert.
Das hab ich wohl vergessen zu kopieren. die init ist aber drin und es 
geht trotzdem nicht :-/

von Dieter F. (Gast)


Lesenswert?

Nicht gut, wenn nur Teile des Codes hier eingestellt werden ...

Kennst Du AVR1308?

Ws passiert übrigens im Interrupt?

von Thomas (Gast)


Lesenswert?

auf AVR1308 bin ich gestoßen. hab es aber bis jetzt nur grob überflogen. 
Ich sollte es mir wohl mal genauer ansehen.

Ich habe keine Interrupt Routine.
Beim I2c geht es doch auch ohne oder? Schließlich weiß ich ja wann ich 
eine Antwort erwarten kann.
Die Zeile "TWI_MASTER_INTLVL_HI_gc |" hab ich auch schon auskommentiert 
gehabt. Trotzdem geht es nicht :-/

von Dieter F. (Gast)


Lesenswert?

Thomas schrieb:
> TWI_Send_Address(&TWIE, DS1307, 0); //schreiben
>   _delay_us(500);
>   TWIE.MASTER.DATA = 00; //Sekunden
>   _delay_us(500);
>   TWIE.MASTER.DATA = 80; //Uhr starteb
>   _delay_us(500);

O.K., die Initialisierung sieht nach Kampi aus ...

Woher hast Du denn diese Sequenz?

DS1703 braucht (zum Schreiben)

- Adresse des Slave
- Byte-Position im Speicher wohin geschrieben gelesen werden soll
- Byte, was geschrieben werden soll
- ggf. weiteres Byte, was an die nächste Byte-Position im Speicher 
geschrieben werden soll
- ...

So wie Du das übergibst stoppst Du den Oszillator:

 Bit 7 of Register 0 is the clock halt
(CH) bit. When this bit is set to 1, the oscillator is disabled.

Was Du mit dem Kommentar "// Sekunden" übergibst ist die Byte-Position 
0x00. Mit 0x80 setzt Du das CH-Bit und stoppst den Oszillator.

Du solltest, denke ich, nochmal das Datenblatt sichten ..


Beim Lesen sieht es anders aus da wird die Adresse des Slave mit 
Lese-Bit übergeben, dann sendet der Slave, bis ein NAK kommt. Das finde 
ich in Deinem Code nicht.

von Dieter F. (Gast)


Lesenswert?

Habe nochmal drüber geschlafen :-)

Nach wie vor gilt die Empfehlung, die Routinen aus der AN zu nutzen. Ob 
Deine "fire-wait-forget-Lösung" sicher funktioniert kann ich nicht 
beurteilen. "Eigentlich" fragt man nach dem Senden etc. immer 
Status-Flags ab und führt dann weitere Aktionen durch.

Habe auf dem ATXMega noch nicht mit TWI gearbeitet, sonst könnte ich Dir 
ggf. ein eigenes Beispiel liefern.

Um die Frustrationsrate gering zu halten empfehle ich Dir die 
Anschaffung eines Logik-Analysators (Salae ... gibts es auch als 
China-Clone) oder - aus eigener Erfahrung dafür noch besser geeignet - 
den Bus-Pirate. Mit dem kannst Du Deine Befehle aus "ausprobieren" und 
die Reaktionen Bit-genau beobachten.

von Sven (Gast)


Lesenswert?

Vielleicht liegt es auch daran, das der DS1307 4,5V bis 5V benötigt.

https://www.sparkfun.com/datasheets/Components/DS1307.pdf

von Dieter F. (Gast)


Lesenswert?

Keine Antwort - dann hat es sich wohl erledigt ...

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.