Forum: Mikrocontroller und Digitale Elektronik MSP430 + I2C - kein Acknowledgebit


von Ulf S. (ulf2016)


Angehängte Dateien:

Lesenswert?

Werte Community,

folgendes Problem: Gewünscht ist das Auslesen von Sensordaten mithilfe 
des Repeated-Start-Protocols. Wie in den Bildern im Anhang zu sehen ist, 
wird aber nach dem Senden der Slaveadresse immer ein No-Acknowledgebit 
gesendet bevor überhaupt Daten ausgetauscht werden. Genutzt werden soll 
der MSP430G2553 mit dem Bodenfeuchtesensor von Chirp bzw alternativ habe 
ich hier noch einen SI7021. Das Problem besteht mit beiden Sensoren. Ein 
defekt eines Sensors ist daher unwahrscheinlich. Die Pullups zwischen 
VCC und SDA bzw SCL wurden nicht vergessen. Mittlerweile habe ich das 
auszuführende Programm soweit minimiert, dass meineserachtens nach nur 
noch die Adresse des Slave und ein Datenbyte mit einer Registeraddresse 
des Sensors gesendet wird, welches ja eigentlich für das 
Repeated-Start-Protocol benötigt wird. Für den Si7021 ist die Adresse 
laut Datenblatt 0X40 und das Register wäre bspw. 0xF5.

https://www.tindie.com/products/miceuz/i2c-soil-moisture-sensor/
https://ex-store.de/dokumente/Si7021-A20.pdf
1
#include <msp430.h>
2
3
int main(void)
4
{
5
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
6
  P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
7
  P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
8
  UCB0CTL1 |= UCSWRST;                      // Enable SW reset
9
  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
10
  UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
11
  UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
12
  UCB0BR1 = 0;
13
  UCB0I2CSA = 0x40;                         // Slave Address
14
  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
15
  IE2 |= UCB0TXIE;                          // Enable TX interrupt
16
17
  while (1)
18
  {
19
    while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent
20
    UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
21
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts
22
                                            // Remain in LPM0 until all data
23
                                            // is TX'd
24
  }
25
}
26
27
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
28
#pragma vector = USCIAB0TX_VECTOR
29
__interrupt void USCIAB0TX_ISR(void)
30
#elif defined(__GNUC__)
31
void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)
32
#else
33
#error Compiler not supported!
34
#endif
35
{
36
    UCB0TXBUF = 0xF5;                     // Load TX buffer
37
    UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
38
    IFG2 &= ~UCB0TXIFG;                     // Clear USCI_B0 TX int flag
39
    __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
40
}

Hoffnungsvoll & mit freundlichen Grüßen

Ulf

von Clemens L. (c_l)


Lesenswert?

Mit welchem Chip ist der Screenshot?

Ein NACK-Bit wird nie aktiv gesendet; es passiert, wenn niemand auf dem 
Bus das Signal auf Low zieht.

Das ist wahrscheinlich kein Software-Problem. Zeig mal die Schaltung.

: Bearbeitet durch User
von Ulf S. (ulf2016)


Angehängte Dateien:

Lesenswert?

Der Screenshoot wurde mit dem SI7021 gemacht. Das Bild für die Schaltung 
stammt nicht von mir. Ich habe mich jedoch daran beim Aufbauen 
orientiert. Es gibt bei mir aber nur einen Slave. Widerstandswerte 
wurden auch mit unterschiedlichen Werten getestet. Das Ergebnis war 
stets das Gleiche.

Interessant ist allerdings, dass das Senden zwischen 2 
Entwicklungsboards mit Hilfe der Beispielprogramme von TI problemlos 
möglich ist.

Auch verstehe ich eigentlich nicht ganz, warum immer erst ein Start und 
ein Stopbit gesendet wird bevor überhaupt die Addresse gesendet wird. 
Dies sollte nicht so sein?

: Bearbeitet durch User
von test (Gast)


Lesenswert?

um mal was allgemeines zu meinem Nutzen vom 'I2C und MSP zu sagen, ich 
toggle immer erstmalca 1000mal die zwei pins SDA und SCLK als GPIOs 
bevor ich anfange den zu benutzen, weil ich oefters Probleme hatte, und 
seitdem nie wieder.

Ich hatte den Tip damals im e2e forum gelesen.

Ansonsten versteh ich nciht ganz wo genau jetzt dein Problem ist, kann 
aber auch and er Müdigkeit liegen :)

von Ulf S. (ulf2016)


Lesenswert?

Falls es noch irgendwie hilfreich ist. Die Jumper auf dem 
Entwicklungsboard wurden angepasst. Und auch veränderte Einstellung der 
SMCLK brachten keine Verbesserung. Des Weiteren habe ich versucht alle 
Leitungswege so kurz wie möglich zu halten...

von Max G. (l0wside) Benutzerseite


Lesenswert?

Der Si7021 funktioniert am MSP430, läuft hier. Bist du sicher, nicht SDA 
und SCL vertauscht zu haben?

Mein Init-Code sieht aus wie deiner, da scheinen wir beide bei TI 
abgeschrieben zu haben :)

Senden mache ich wie folgt (UC_xxx ist bei mir per Makro auf UCB0xxx 
gemappt):
1
UC_CTL1 |= UCTR;
2
UC_IE = UCTXIE | UCRXIE | UCALIE | UCNACKIE;
3
UC_CTL1 |= UCTXSTT;

In der ISR wird dann jeweils das nächste Byte geschrieben:
1
UC_TXBUF = *(i2c_tx_bfr++);
bzw. wenn kein Byte mehr da ist, auf Empfangen umgeschaltet:
1
UC_CTL1 &= ~UCTR;
2
UC_CTL1 |= UCTXSTT;
und am Schluss ein Stop gesendet:
1
UC_CTL1 |= UCTXSTP;

WIMRE darf der Stopp erst gesendet werden, nachdem das letzte Byte 
tatsächlich empfangen wurde, das war am Anfang etwas verwirrend.

Max

von Ulf S. (ulf2016)


Lesenswert?

P1.6 ist bei mir SDA und 1.7 SCL

Und ja, dass kommt alles von TI ;)

: Bearbeitet durch User
von Ulf S. (ulf2016)


Lesenswert?

Seh grad, dass in dem Bild SDA und SCL vertauscht waren. Man sollte 
immer bei den Unterlagen des Herstellers bleiben ....

: Bearbeitet durch User
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.