Forum: Mikrocontroller und Digitale Elektronik MSP430FR5739 korrupte Daten am I2C


von Rush .. (rush)


Lesenswert?

Hallo.

In Anlehnung an meinen letzten 
Beitrag "MSP430FR5739 und I2C" möchte ich mit diesem 
meine Problemhierarchie nun fortsetzen :-D

Die Übertragung auf dem Bus läuft nun scheinbar unproblematisch ab. 
Allerdings stehen in meinem Empfangsarray (RXData) meistens korrupte 
Daten drin. Die tatsächlich übertragenen Daten habe ich mir mit dem 
Logicanalyser angesehen. Mal sieht es so aus als würde der 
Empfangspuffer zu früh gelesen werden, mal ist garkein Muster zu 
erkennen.

Den Code habe ich mal mit drangehängt. Vielleicht findet jemand den 
Fehler...
1
#include <msp430.h>
2
#include "msp430fr_i2c_functions.h"
3
4
unsigned char TXData = 0;                          // Pointer to TX data
5
unsigned char TXByteCtr;          // Bytecounter for data to be send
6
unsigned char RXData[4];          // Bytearray for received bytes
7
unsigned int RXByteCtr;            // Bytecounter for data to be received
8
9
10
/*void clear_rx_buffer(void)
11
{
12
  int i=4;      // size of RXData
13
  for (i; i > 0; i--)
14
  {
15
    RXData[i] = 0;
16
  }
17
}*/
18
19
20
void init_i2c(void)
21
{
22
  P1OUT |= BIT6 + BIT7;
23
  P1REN |= BIT6 + BIT7;
24
  //UCB0IE |= UCTXIE0 + UCRXIE0 + UCNACKIE;           //transmit and NACK interrupt enable*/
25
26
  UCB0CTL1 |= UCSWRST;           // Activate the reset status
27
  UCB0CTL1 &= ~UCA10;
28
  UCB0CTL1 &= ~UCSLA10;
29
  UCB0CTLW0 |= UCMODE_3 + UCMST + UCSYNC;      // I2C master mode
30
  UCB0BRW = 0x0008;           // Set baudrate = SMCLK / 8 --> (1MHz/8 = 125kHz)
31
  UCB0CTLW1 = UCASTP_2;           // Autom. STOP assertion
32
  P1SEL1 |= 0xC0;            // Configure I2C pins
33
                // P1SEL_7 = 1;
34
                // P1SEL_6 = 1;
35
36
  UCB0CTL1 ^= UCSWRST;           // Deactivate the reset status
37
  UCB0IE |= UCTXIE;           // Enable transmit interrupt (TX-Interrupt)
38
  UCB0IE |= UCNACKIE;          // Enable NACK interrupt
39
  UCB0IE |= UCRXIE;          // Enable receive interrupt (RX-Interrupt)
40
  UCB0IE |= UCBCNTIE;          // Enable Byte Counter interrupt
41
  UCB0IE |= UCSTPIE;          //Enable STOP condition interrupt
42
43
  _BIS_SR(GIE);             // Enable Interrupts
44
}
45
46
void i2c_send_adr (unsigned int address)      // only Start, Adress, Stop -> for HYT271 Sensor
47
{
48
  UCB0I2CSA = address;           // Set slaveaddress
49
  UCB0CTLW0 |= UCTR;          // Set MSP430 in transmit state
50
  UCB0CTLW0 |= UCTXSTT;          // Startcondition followed by a stopcondition sends only  start|slave-adr|stop
51
  UCB0CTLW0 |= UCTXSTP;                 // Stopcondition
52
}
53
54
unsigned char i2c_read_byte(unsigned char adr, unsigned char bytes_expected)    // received bytes are stroed in RXData
55
{
56
  RXData[0] = 0x0;
57
  RXData[1] = 0x0;
58
  RXData[2] = 0x0;
59
  RXData[3] = 0x0;
60
  //clear_rx_buffer();          // warum hat diese Zeile laut compiler keine Auswirkungen auf den code??  Ich habe sie testweise auskommentiert und das Array manuell gelöscht
61
  UCB0TBCNT = bytes_expected;            //number of bytes to be received
62
  UCB0I2CSA = adr;           // Set slaveaddress
63
  UCB0CTLW0 &= ~UCTR;          // Set MSP430 in receive state
64
  UCB0CTLW0 |= UCTXSTT;          // Set Start Bit
65
  RXByteCtr = bytes_expected-1;
66
  //UCB0CTLW1 |= UCASTP_2;            //automatic stop generated
67
                    //after UCB0TBCNT is reached
68
  return 0;
69
}
70
71
72
#pragma vector = USCI_B0_VECTOR
73
__interrupt void USCIB0_ISR(void)
74
{
75
  switch(__even_in_range(UCB0IV,0x1E))
76
  {
77
  case 0x00: break;                            // Vector 0: No interrupts break;
78
          case 0x02: break;
79
          case 0x04:
80
                UCB0CTLW0 |= UCTXSTT;                 // resend start if NACK
81
                break;                                // Vector 4: NACKIFG break;
82
          case 0x08:                    // clear Flag when Stopcondition was detected
83
            UCB0IFG &=~ UCSTPIFG;
84
            break;
85
          case 0x16:
86
            __delay_cycles(30);
87
            RXData[RXByteCtr] = UCB0RXBUF;        // Get RX data
88
            UCB0RXBUF= 0x00;        // auch nur zu Testzwecken. Das Reg. wir normalerweise beim Empfang neuer Daten überschrieben
89
              if (RXByteCtr > 0)
90
              {
91
                RXByteCtr--;
92
                break;
93
              }
94
              else
95
              {
96
                break;
97
              }
98
          case 0x18:
99
                /*if (TXByteCtr)                        // Check TX byte counter
100
                {
101
                  UCB0TXBUF = sendBytes[TXByteCtr-1];  // Load TX buffer
102
                  TXByteCtr--;                      // Decrement TX byte counter
103
                  if (TXByteCtr == 0)
104
                  {
105
                    __delay_cycles(30);
106
                    UCB0CTLW0 |= UCTXSTP;           // I2C stop condition
107
                  }
108
                }
109
                else
110
                {
111
                  UCB0IFG &= ~UCTXIFG;              // Clear USCI_B0 TX int flag
112
                }*/
113
                break;                                // Vector 26: TXIFG0 break;
114
          case 0x1A:
115
                    UCB0IFG &= ~UCBCNTIFG;
116
                   break;
117
          default: break;
118
  }
119
}

Der Sendeteil in der ISR ist noch auskommentiert. Nicht das da noch eine 
Fehlerquelle ist.
Der compiler meckert auch rum dass die clear_rx_buffer angelich keine 
Auswirkungen auf den Code hätte. Deswegen ist sie auskommentiert... 
Könnt ir euch erklären warum?

Gut, würde mich freuen ein paar Anregungen zu bekommen.

MfG Konrad

von angeregt (Gast)


Lesenswert?

Anregung 1
In der ausgeklammerten Funktion erfolgt eine Bereichsüberschreitung mit 
i = 4

Anregung 2
Wofür ein delay in der ISR?

Anregung 3
Nicht das Empfangsregister beschreiben, nur lesen

von Rush .. (rush)


Lesenswert?

oh tatsächlich... die Sache mit dem i=4 habe ich übersehen.

Das delay in der ISR war auch nur testhalber mit drin, sollte aber raus.

Das Empfangsregister wollte ich auch nur testhalber auf Null setzen. Es 
macht allerdings keinen Unterschied. War auch zu erwarten.

von Xyx (Gast)


Lesenswert?

Rush ... schrieb:
> Die Übertragung auf dem Bus läuft nun scheinbar unproblematisch ab.
> Allerdings stehen in meinem Empfangsarray (RXData) meistens korrupte
> Daten drin. Die tatsächlich übertragenen Daten habe ich mir mit dem
> Logicanalyser angesehen. Mal sieht es so aus als würde der
> Empfangspuffer zu früh gelesen werden, mal ist garkein Muster zu
> erkennen.

Setz mal die Pullup Widerstände niedriger

von Rush .. (rush)


Lesenswert?

Laut Codeexample von TI sollen 10K extern dran. Dies habe ich getan, 
ohne Erfolg.

Also hab ich parallel dazu noch die internen von 35k aktiviert was einen 
Gesamtwiderstand von 7,77k macht. Auch ohne Erfolg.

Normalerweise nehme ich für meine Schaltungen immer 10k und habe 
keinerlei Probleme.

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.