Hallo,
auch wenn hier wohl mehr Leute mit AVRs arbeiten, hoffe ich doch, dass
ihr mir vielleicht doch etwas helfen könntet.
Ich bastel derzeit mit einem MSP430G2553 und versuche diesen mit einer
DS3232 über I2C zu verbinden.
Ich würde gerne das USCI-Modul verwenden. Laut Datenblatt kann ich die
Kommunikation nun über das Pollen von Statuswerten oder Interrupts
abwickeln, wobei ich gerne Interrupts nutzen würde.
Aber nun weiß ich nicht weiter.
Hier einmal meine Initialisierung:
Aber nun weiß ich nicht ganz weiter.
Als ich mal mit AVRs hantiert habe, nutzte ich die Bibliothek von Peter
Fleury. Dieser scheint aber die Status-Flags auch eher zu pollen.
Wenn ich das Datenblatt richtig verstanden habe, dann kann ich mit
folgender Funktion eine Startbedingung und die Adresse des Slaves
senden:
1
voidi2c_start(unsignedchardevice_addr)
2
{
3
while(UCB0STAT&UCBUSY);// wait for STOP
4
UCB0I2CSA=device_addr;
5
UCB0CTL1|=UCTR|UCTXSTT;// write-access + start
6
}
Zum Test wollte ich gerne in den SRAM-Bereich (0x14-0xFF) der DS3232
schreiben und das erste Register gleich wieder auslesen.
Zum schreiben bräuchte ich doch dann so etwas wie:
Nun komme ich aber gerade nicht weiter. Brauche ich die write-Funktion
überhaupt? Ich möchte mir zunächst eine allgemeine I2C-Lib schreiben,
die ich dann für beliebige I2C-Devices nutzen kann.
Aber wenn das ganze Interrupt-gesteuert sein soll, dann müsste ich doch
die write-Funktion in den TX-Interrupt legen oder nicht? solange der
Interrupt ausgelöst wird und Daten vorhanden sind, wir gesendet.
Bin gerade durch den Ablauf etwas verwirrt. Übergebe ich dann die Daten
eher an so etwas:
Aber wie ich dann das Lesen mit dem Restart hinbekomme, ist mir auch
noch nicht so ganz klar.
Könnt ihr mir vielleicht einen kleinen Tipp geben, wie ich das aufbauen
könnte?
Viele Grüße
Du solltest Dir neben dem "MSP430x2xx Family User's Guide" auch die
aktuellen Codebeispiele von TI ansehen.
www.ti.com/lit/zip/slac463
Möchte man beim 'G2553 gleichzeitig die UART verwenden, so wird die
Angelegenheit etwas komplizierter, weil die USCI_B, die für I2C
zuständig ist, und die USCI_A, die für den UART-Betrieb zuständig ist,
sich die Interruptvektoren teilen.
Aber auch dafür gibt es Beispielcode, den findet man in der
arduino-artigen Programmierumgebung "energia".
http://energia.nu/download/
Nein, das bedeutet nicht, daß man jetzt "arduino-like" programmieren
muss, die relevanten Codeteile sind in reinem C geschrieben und lassen
sich mit vertretbarem Aufwand auch mit anderen Compilern als gcc
verwenden (für IAR müssen die Interruptvektordeklarationen angepasst
werden und "boolean" durch "bool" ersetzt werden).
Die relevanten Dateien finden sich in der energia-Verzeichnisstruktur*
unter "hardware/msp430/cores/msp430/"
und sind
usci_isr_handler.c/usci_isr_handler.h
twi.c/twi.h
hardware_serial.cpp/hardware_serial.h
Der I2C-Teil lässt sich recht leicht aus dem "energia"-Gerüst lösen
(eingebundene Headerdateien anpassen, statt "energia.h" "msp430.h"
einbinden, "stdint.h" und "stdbool.h"), und mit etwas Geschick sollte
gleiches auch mit dem Code für die UART möglich sein.
Der Code ist so flexibel geschrieben, daß er nicht nur auf 'G2553
verwendbar ist, sondern auch auf Controllern, bei denen USCI_A und
USCI_B getrennte Interruptvektoren verwenden, und auch auf Controllern
mit EUSCI genutzt werden kann. Das wird mit bedingter Compilation
gemacht; die da verwendeten Symbole werden von den zum jeweiligen
Controller gehörenden Headerdateien korrekt gesetzt, sowohl in den des
mit "energia" mitgelieferten gcc als auch denen der "Embedded Workbench"
von IAR.
*) Ich habe hier gerade einen Mac, daher wird es wenig bringen, den
absoluten Pfad anzugeben, aber eine Suche nach der Datei "twi.c" wird
den richtigen Ort auch für die anderen Dateien ergeben.
Hallo,
erstmal vielen Dank für die Tipps! Über den Userguide hänge ich jetzt
schon ziemlich lange und bin dann irgendwann nicht mehr schlauer
geworden.
Nach einer ersten Durchsicht des Energia-Codes kehrt dann doch
Ernüchterung ein. Ich hätte nicht gedacht, dass hinter dem
Interrupt-basierten Code doch soviel steckt. Über das Pollen, wäre es
denkbar einfacher. Hätte ich dadurch große Nachteile? Das der Code dann
an gewissen stellen steht und nichts tut ist mir klar. Aber gibt es
sonst noch nennenswerte Nachteile?
Viele Grüße
Ich nochmal.
Da ich mich jetzt langsam ranwagen möchte, dachte ich mir, dass ich es
erstmal mit Warteschleifen zum Laufen bekomme und dann mit Interrupts.
Nun habe ich folgendes:
volatileunsignedinti;// volatile to prevent optimization
100
101
P1OUT^=0x01;// Toggle P1.0 using exclusive-OR
102
103
i=10000;// SW Delay
104
doi--;
105
while(i!=0);
106
}
107
108
return0;
109
}
Da ich kein Oszi habe, kann ich leider nichts genaues dazu sagen, ob
alles richtig funktioniert.
Nur beim Auslesen bin ich mir sicher, dass etwas nicht stimmen kann.
Sollte die Schreibfunktion funktioniert haben, müsste ich ja 0xAB
auslesen; bekomme aber immer 0x15, also die Adresse.
Hoffe, ihr könnt mir bitte nochmal einen Anstoß geben.
(Die For-Schleife ist nur zum schauen, ob er bis hier hin kommt ;)
Viele Grüße