Forum: Mikrocontroller und Digitale Elektronik MSP430 Launchpad und MS5611 Sensor


von mmax (Gast)


Lesenswert?

Hi,

Ich hab soeben ein Breakout Board mit dem MS5611-01BA03 Sensor bekommen:
http://www.csgshop.com/product.php?id_product=96

Leider finde ich dazu keine Doku und weiss nicht wie ich zwischen SPI 
und I2C auswaehle (denke man muss auf dem Board eine Bruecke bei den 
Loetpads setzen, aber welche) und ob die Pullup Widerstaende da schon 
drauf sind ... schaetze aber schon, da zwei (R1 & R2) SMD Widerstaende 
schon drauf sind.

Jetzt moechte ich den Sensor via Lauchpad (MSP430G2553) auslesen. Ich 
hab noch das alte (Rev.1.4) Board bei dem urspruenglich ein MSP430G2231 
gesteck war. Gibts da igendwas zu beachten? Muss ich da vielleicht die 
Firmware von
http://processors.wiki.ti.com/index.php/MSP430_LaunchPad_Firmware_Update
updaten? Um den HW-UART nutzen zu koennen, muss man ja die RX und TX 
Jumper auskreuzen, das hab ich eh schon rausgefunden und die 
Kommunikation mit dem PC funktioniert auch.

In der Doku vom Sensor wird immer von einer Versorungsspannung von 3V 
(er geht aber bis 3,8V) ausgegangen, das Launchpad liefert aber ja 3,5V. 
Ist das ein Problem, brauch ich da groessere Pullups?

Vielleicht hat schon jemand diese Kombination im Einsatz und kann mir 
diesbezueglich helfen. Als Beispielcode gehe ich von dem Code von TI 
aus.

lG,
Max

von auf die Schnelle (Gast)


Lesenswert?

Hallo Max,

du musst für den I2C Modus den PS Pin auf High legen.
(Datenblatt S. 5)
Datenblatt kann man im cgsshop finden

Viele Grüße

von auf die Schnelle (Gast)


Angehängte Dateien:

Lesenswert?

Hey,

und hier noch einmal das Datenblatt...!

Viele Grüße und viel Spaß...

von mmax (Gast)


Lesenswert?

Ja danke, das Datenblatt hab ich natuerlich gelesen. Ich hab jetzt auch 
den Schaltplan vom Hersteller bekommen und weiss jetzt dass ich via 
Bruecke am SW1 zwischen SPI und I2C umstellen kann. Die beiden 
Widerstaende R1 & R2 sind, wie vermutet, die Pullups an SCLK und SDI/SDA 
und mit 2,2k angegeben.

Laut diesem Schaltplan ist die Versorgung mit 3,3V angegeben, denke also 
dass ich das Board direkt mit dem Launchpad verbinden kann.

Hat vielleicht noch jemand eine Antwort zweicks Firmware Update?

lG,
Max

von mmax (Gast)


Angehängte Dateien:

Lesenswert?

Irgendwie komm ich einfach nicht weiter. Ich hab das MS5611 Board jetzt 
an das Launchpad (mit MSP430G2553) und versuche ganz einfach zyklisch 
RESETs an den Drucksensor zu schicken nur um mal schaun was ueber den 
Bus drueber geht.

Leider passiert nix und auf dem Oszi ist auch nichts zu sehen, nicht mal 
der Takt der SCLK Leitung.

Von der Verdrahtung kanns ja auch fast net falsch sein, da hab folgede 
Pins verbunden:

Launchpad | MS5611 Board
-------------------------
VCC       | VDD
GND       | CSB
1.6       | SLC
1.7       | SDA
          | SDO
GND       | GND

von mmax (Gast)


Lesenswert?

Achja, ich verwende die i2C library von:
https://github.com/alanbarr/msp430-launchpad/blob/master/common/src/i2c.c

Und mein bescheidenes Programm schaut so aus:
1
#include <msp430g2553.h>
2
3
#include "uart.h"
4
#include "i2c.h"
5
6
#define MS5611_ADDR_CSB_LOW 0xEE // Address with CSB set to low
7
#define MS5611_CMD_RESET    0x1E // Reset command
8
9
char cmd[1] = { 0x1E };
10
11
void busy_waiting( volatile unsigned long cycles ) {
12
    do (cycles--);
13
    while (cycles != 0);
14
}
15
16
int main(void) {
17
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
18
    
19
    BCSCTL1 = CALBC1_1MHZ;    // Set "Basic clock system control 1" to 1MHz
20
    DCOCTL  = CALDCO_1MHZ;    // Set "DCO clock frequency control " to 1MHz
21
    
22
    P1DIR |= BIT0;
23
    P1OUT &= ~BIT0;
24
    
25
    // Initialize Hardware UART
26
    uartSetupPins();
27
    uartInit();
28
    
29
    // Initialize I2C Bus
30
    i2cSetupPins();
31
    
32
    __enable_interrupt();
33
    
34
    uartWrite((char *) "-- start --\n\r");
35
    
36
    while (1) {
37
        i2cSetupTx( MS5611_ADDR_CSB_LOW );
38
        // i2cTransmit( &cmd[0], 1 );
39
        
40
        P1OUT ^= BIT0; // Hardbeat signal
41
        busy_waiting( 20000 );
42
    }
43
}

Sobald ich die Zeile mit i2cTransmit einkommentiere, haengt das programm 
(Die rote LED auf Port 1.0 blinkt nicht mehr). Die Ausgabe via uart auf 
eine Konsole meines Rechners funktioniert soweit.

Jemand eine Idee?

Danke,
Max

von Markus M. (mmax)


Lesenswert?

So, ich hab jetzt herausgefunden dass es anscheineden an der I2C Adresse 
des Sensors liegt. Laut Datenblatt sollte diese 111011Cx, wobei C das 
invertierte CSB (Also in meinem Fall 1, da CSB mit Masse verbunden) und 
x das Read (x=1) bzw. Write (x=0) Bit ist.

Im meinem Fall schreibe ich also 0xEE (11101110) ins Register UCB0I2CSA 
des Mikrocontrollers, doch daran scheint es zu liegen. Schreibe ich 0x77 
(das selbe ohne LSB von 0xEE), also nur 7Bit ins Register, laeuft der 
Controller weiter.

Daraufhin hab ich im Forum gesucht und bin draufgekommen das es bzgl. 
I2C Addressierung einige Uneinstimmigkeiten gibt, wie z.B hier 
Beitrag "I2C Bus Adressierung"

Kanns wirklich nur daran liegen, dass der Controller haengen bleibt?

von auf die Schnelle (Gast)


Lesenswert?

Guten Morgen,

ja, es kann daran liegen. Schließlich wird über die I2C-Adresse der 
Baustein eindeutig angesprochen. Ein Vorteil beim I2C ist ja, das du 
mehrere I2C Bausteine an den Bus (die Leitungen parallel) hängen kannst. 
Die Unterscheidung welcher Baustein über Software jetzt angesprochen 
wird, wird über die Adresse durchgeführt.
Jeder Baustein sieht die Adresse, aber nur der Baustein arbeitet 
weiter, welcher durch seine Adresse angesprochen wird. Alle anderen 
Bausteine bleiben bis zur nächsten StartCondition inaktiv.
Die Schwierigkeit mit der Adressierung liegt jetzt wohl darin begründet, 
das eine I2C-Adresse 7Bit (10Bit) lang ist.
In den Datenblättern ist aber die Adresse in zwei Bytes angegeben, wobei 
das letzte Bit die Unterscheidung zwischen Lese- und Schreibzugriff auf 
den Bus ist. Prinzipiell hat jeder Baustein somit zwei Adressen, eine 
für den Lesezugriff und einen für den Schreibzugriff.
Das letzte Bit fügt der MSP430 automatisch der 7Bit Adresse hinzu.
Die Unterscheidung ob er sendet (Transmitter) oder empfängt (Receiver) 
wird in der Software durch das Setzen des UCTR-Bits im UCB0CTL1 Register 
durchgeführt.
Dies ist in der von die verwendeten library in den Zeilen 62
 UCB0CTL1 |= UCTR + UCTXSTT;   für den Transmitmodus
und in Zeile 71
 UCB0CTL1 |= UCTXSTT;          für den Receivemodus
programmiert.
Somit weiß der Mikrocontroller schon, ob er Lesen oder Schreiben soll 
und das heißt für dich, du musst ihm nur noch die wirkliche 7Bit Adresse 
übergeben.

Jetzt ist meine Antwort doch etwas lang geworden, aber ich hoffe, sie 
hilft dir weiter.

Viele Grüße

von Markus M. (mmax)


Angehängte Dateien:

Lesenswert?

Ja danke, bin mir jetzt auch sicher das das RW Bit (LSB) vom MSP430 
selbst hinzugefuegt wird. Das senden und empfangen haut jetzt auch 
grundsaetzlich hin. Anbei auch ein Screenshot, der eine Kommunikation 
zeigt und die beiden wichtigsten Sourcefiles.

Laut Datenblatt muss ich zuerst die Werte aus dem PROM des Sensors 
auslesen um damit (im ersten Schritt mal) die Temperatur berechnen zu 
koennen. PROM lesen scheint ja zu funktionieren nur der Wert fuer die 
Referenztemperatur scheint etwas abzuweichen.

Leider springt die Temperatur um mehrere Grad, was natuerlich nicht sein 
kann. Ich glaub da ist irgendwie noch was faul ... aber wo?

Und hier die Ausgabe von meinem Programm:
1
-------------------------- START ------------------------------
2
Pres. sensitivity:                      40192 (0x9D00)
3
Pres. offset:                           55040 (0xD700)
4
Temp. coefficient of pres. sensitivity: 38656 (0x9700)
5
Temp. coefficient of pres. offset:      52224 (0xCC00)
6
Reference temperature:                  1792 (0x0700)
7
Temp. coefficient of the temperature:   26880 (0x6900)
8
9
raw=8388608 td=8388608 temp=1744
10
raw=8388608 td=8388608 temp=1744
11
raw=8650752 td=8650752 temp=2072
12
raw=8650752 td=8650752 temp=2072
13
raw=8650752 td=8650752 temp=2072
14
raw=8650752 td=8650752 temp=2072
15
raw=8650752 td=8650752 temp=2072
16
raw=8650752 td=8650752 temp=2072
17
raw=8650752 td=8650752 temp=2072
18
raw=8650752 td=8650752 temp=2072
19
raw=8650752 td=8650752 temp=2072
20
raw=8650752 td=8650752 temp=2072
21
raw=8388608 td=8388608 temp=1744
22
raw=8388608 td=8388608 temp=1744
23
raw=8388608 td=8388608 temp=1744
24
raw=8912896 td=8912896 temp=1888
25
raw=8388608 td=8388608 temp=1744

Komisch ist ja auch dass die Ausgabe der Variablen raw und td (sollte dt 
heissen) uebereinstimmen, kann aber nur sein wenn MS5611_CAL_TREF null 
waere, ist es aber nicht (siehe Ausgabe weiter oben). Die Berechnungen 
finden im ms5611.c File, ab Zeile 133 statt.

Evtl. passen meine Datentypen nicht oder die Art und Weise wie ich die, 
via I2C empfangenen, Daten in die Variablen speichere. Bin fuer jeden 
Tip dankbar.

lG,
Max

von Markus M. (mmax)


Lesenswert?

Sonderbar kommt mir auch vor, dass beim emfangen der PROM Daten (werden 
zur weiteren Berechnungen benoetigt) immer das untere Byte 0x00 ist.

Bei der Debug-Ausgabe der Werte fuer C1 bis C6, empfange ich folgendes:
Rx C0: 9D 00
Rx C1: D7 00
Rx C2: 97 00
Rx C3: CC 00
Rx C4: 07 00
Rx C5: 69 00
1
Die Routine im Source:
2
3
void ms5611_read_prom()
4
{
5
    unsigned short i;      // Loop variable
6
    volatile char rxb[2];  // 2 Byte Receive buffer
7
    char debug[64];        // Buffer for uart debug output
8
    
9
    for( i=0; i<6; i++ ) {
10
        i2cSetupTx( MS5611_ADDR_CSB_LOW );
11
        i2cTransmit( &cmd[i+12], 1 );
12
        
13
        i2cSetupRx( MS5611_ADDR_CSB_LOW );
14
        i2cReceive( rxb, 2 );
15
        
16
        prom_data[i] = (uint16_t)(rxb[1] << 8 | rxb[0]);
17
        
18
        sprintf(debug,"Rx C%d: %02X %02X\r\n", i, (unsigned char)rxb[1], (unsigned char)rxb[0] );
19
        uart_write(debug);
20
    }
21
}

Im Datenblatt (Seite 7) wird z.B. als Beispielwert fuer C1 40127 
angegeben, was in hex 0x9CBF ist ... also schon beide Byte ungleich 
null. Als kanns doch bei mir kein Zufall sein dass das untere Byte immer 
Null ist. Ich finds aber nicht raus wieso.

von Markus M. (mmax)


Lesenswert?

Ich kann mir schon wieder selbst die Antwort geben. Es scheint wohl ein 
Timingproblem zu sein. Zwischen i2cTransmit() und i2cReceive() muss wohl 
ein wenig Zeit vergehen.

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.