Forum: Mikrocontroller und Digitale Elektronik MSP430 I2C Kommunikation Slave ACK wird nicht gesendet


von Uli S. (uli_stone)


Angehängte Dateien:

Lesenswert?

Hallo,

der MSP430 bereitet mir ein bisschen Kopfzerbrechen mit dem I2C 
Protokoll.
Anfänglich hatte ich einen anderen Slave am Bus hängen - weil ich 
Probleme hatte, wurde dieser durch BMI160 ausgetauscht.
Leider war das keine Lösung...

Ich benutze den MSP430G2231 auf einem Launchpad. Der BMI160 ist auf 
einer Platine/Modul mit dem Namen GY-BMI160 (Bild der Platine im 
Anhang).
Das Modul ist mit dem Launchpad wie folgt verbunden: Vin->VCC, GND->GND, 
SCL->PIN6, SDA->PIN7 und SA0->GND (SA0 für I2C/Slave Addressenauswahl)

Zwei Sachen habe ich festgestellt (Der Bus wurde mit einem Logikanalyser 
mit 24MHz abgetastet):

1. Wenn ich die SCL Frequenzen ändere, wird das letzte Bit und das ACK 
Bit zeitlich verlängert (Bilder im Anhang für SCL mit 33kHz, 66kHz, 
125kHz und 224kHz).
2. Sende ich alle Adressen von 0x00 bis 0xFF nacheinander an den Slave 
werden von 0x00 bis 0x7F bekomme ich ein ACK und
und alles größer 0x7F bekommt kein ACK. Obwohl nur eine Slave am Bus 
hängt, mit der Adresse 0x68 (ohne Read/Write Bit), sowohl 0xD0 und 0xD1 
bekommt NACK.

Nochmal um klarzustellen, ich habe den I2C Bus des MSP430G2231 mit zwei 
verschiedenen Slaves probiert, beide haben das gleiche Verhalten gezeigt 
(für Punkt 1. und 2.).
Dies lässt mich vermuten das irgendwas mit dem MSP430 und der I2C 
Konfigurierung nicht stimmt, leider kann ich keine Fehler finden...

Ich würde mich freuen, wenn jemand mit Erfahrung mal einen Blick auf 
meinen Code werfen (unten angehängt oder in Dateianhang) könnte und mir 
Tipps gibt, wie ich das Problem lösen kann.
Danke
1
#include <msp430g2231.h>
2
#include <stdio.h>
3
#include <stdint.h>
4
5
#define I2C_add_read 0xD0
6
#define I2C_add_write 0xD1
7
8
    
9
void main(void) {
10
    WDTCTL = WDTPW + WDTHOLD;                                                   //disable watchdog timer
11
    
12
    //-I2C init
13
  USICTL0 |= USIPE7 + USIPE6 + USIMST + USIOE + USISWRST;                     
14
  USICTL1 = USII2C;                                                           
15
  USICKCTL = USIDIV_2 + USISSEL_2 + USICKPL;                                 
16
17
  USICNT |= USIIFGCC;                                      
18
  USICTL0 &= ~USISWRST;                                                      
19
  USICTL1 &= ~USIIFG;                                                                   
20
    
21
    while(1)
22
    {
23
    USICNT |= USIIFGCC;                                      
24
    USICTL0 &= ~USISWRST;                                                      
25
    USICTL1 &= ~USIIFG; 
26
    //Start Condition
27
    USISRL = 0x00;                                     
28
    USICTL0 |= USIGE + USIOE;                          
29
    USICTL0 &= ~USIGE;
30
        
31
        //Send Data
32
    USISRL = I2C_add_read;                                                         
33
    USICTL0 |= USIOE;                              
34
        USICNT = 0x08;
35
        while((USICTL1 & USIIFG) != 0x01);                                          
36
        
37
        //Read Ack Bit
38
        USICTL0 &= ~USIOE;       
39
        USICNT = 0x01;
40
        USICTL0 |= USIOE;          
41
        while((USICTL1 & USIIFG) != 0x01);
42
        ack_flag = USISRL;
43
        
44
        //Stop
45
        USICTL0 |= USIOE;
46
        USISRL = 0x00;                                                              
47
        USICNT = 1;
48
        while((USICTL1 & USIIFG) != 0x01);                                          
49
      
50
        USISRL = 0xFF;                                                             
51
        USICTL0 |= USIGE;
52
        USICTL0 &= ~(USIGE+USIOE);
53
        
54
        for(delay=0; delay<100; delay++);        
55
    }
56
}

Zusatz Info
- Datenblatt BMI160: 
https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmi160-ds000.pdf

von Thomas Z. (usbman)


Lesenswert?

Uli S. schrieb:
> #define I2C_add_read 0xD0
> #define I2C_add_write 0xD1

darüber würde ich noch mal nachdenken Read und Write ist vertauscht

von Uli D. (megi)


Lesenswert?

Hallo Thomas,
danke für deine Nachricht. Das ist korrekt, Read ist 0xD1 und Write ist 
0xD0. Ich habe beides ausprobiert und auch auf beides sollte ein ACK vom 
Slave kommen. Es ist falsch deklariert sollte aber kein Unterschied 
machen...?

Andere Auffälligkeiten warum der Code nicht funktioniert?
Danke

von Thomas Z. (usbman)


Lesenswert?

Uli D. schrieb:
> Ich habe beides ausprobiert und auch auf beides sollte ein ACK vom
> Slave kommen. Es ist falsch deklariert sollte aber kein Unterschied
> machen...?

naja der Baustein erwartet:
<Start> <0xD0> <index> <RepStart> <0xD1> <Payload> <Stop>
beim Lesen eines Registers. Index[0.7F]

Zum MPS430 kann ich nichts sagen kenn ich zu wenig.

von Harald K. (kirnbichler)


Lesenswert?

Bei MSP430 ist es sehr ratsam, sich die Codebeispiele von TI anzusehen.

https://www.ti.com/lit/zip/slac463

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.