Forum: Mikrocontroller und Digitale Elektronik MSP430f23x0 + SHT21 und I2C


von Nasenschleim (Gast)


Lesenswert?

Hallo,

ich versuche mit Hilfe eines MSP430f2370 einen Temperatur- und 
Feuchtigkeitssensor (SHT21 von Sensirion) auszulesen.
Das komische ist das mal eine I2C-Kommunikation stattfindet und ein 
anderes mal funktionierts wieder nicht. Der Fehler lässt sich auch nicht 
reproduzieren. Nach langem hin und her rätseln/versuchen wollte ich euch 
mal fragen ob ihr durch Zufall einen Fehler im Code entdeckt.

10k Ohm PullUps sind an SDA und SCL dran.

PS: Da der Code noch in der Entwurfsphase ist, schaut er an manchen 
Stellen noch etwas komisch aus.

Ich danke schon mal für jeden kleinen Hinweis.

1
#include  "msp430x23x0.h"
2
3
4
//Funktionsdeklaration
5
void warte_ms(unsigned int i);
6
void ausgeben(unsigned char c[], unsigned char len);
7
void Reset();
8
void I2C_schreiben_byte(unsigned char cmd);
9
void I2C_lesen();
10
11
int main(void)
12
{
13
  
14
  unsigned char Ende[2]="00";
15
  unsigned char Test[5]="TEST-";
16
  int a=0;
17
18
// ---Initialisierung-Start---
19
  WDTCTL = WDTPW + WDTHOLD;  // Watchdog aus
20
  BCSCTL3 = XCAP1;      // Clock
21
22
  P4DIR = BIT5;               // P4.5 als Ausgang
23
24
// UART init
25
  UCA0CTL1 = UCSWRST;
26
  UCA0CTL1 |= UCSSEL0;                       // UCLK = ACLK
27
  UCA0BR0 = 0x03;                            // 32k/2400 - 13.65
28
  UCA0BR1 = 0x00;
29
  UCA0MCTL = 0x06;                           // Modulation
30
  P3SEL |= 0x30;  
31
  P3DIR |= 0x10;
32
  P3OUT |= 0x10;
33
  UCA0CTL1 &= ~(UCSWRST);                    // Initalize USART state machine
34
35
// I2C init
36
  P3SEL |= 0x06;                            // Assign I2C pins to USCI_B0
37
  UCB0CTL1 |= UCSWRST;                      // Enable SW reset
38
  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
39
  UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset  
40
  UCB0BR0 = 12;                             // fSCL = ACLK/12 = ~100kHz
41
  UCB0BR1 = 0;
42
  UCB0I2CSA = 0x40;                         // Set slave address
43
  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
44
 
45
// TIMER init
46
  TACCTL0 = CCIE;
47
  TACTL = TASSEL0 + ID0 + ID1;
48
49
  _BIS_SR(GIE);              // Interrupts ein
50
// ---Initialisierung-Ende---
51
52
for (a=0;a<20000;a++)            // Delay fuer Hardwarekonfigurierung
53
{;}
54
55
Ende[0] = '\r';
56
Ende[1] = '\n';
57
58
//ausgeben(Test,5);
59
60
//Reset();
61
//warte_ms(20);  
62
//
63
//ausgeben(Test,5);
64
65
  while(1)  // Hauptschleife
66
  {
67
//    ausgeben(Test,5);
68
    
69
    P4OUT &= ~BIT5;        // gelbe LED an
70
//    I2C_schreiben_byte(0xF3);  // Temp noHOLD-MASTER
71
    I2C_schreiben_byte(0xE3);  // Temp HOLD-MASTER
72
    I2C_lesen();
73
    P4OUT |= BIT5;        // gelbe LED aus
74
    
75
//    ausgeben(Test,5);
76
    
77
    warte_ms(50);
78
    
79
    P4OUT &= ~BIT5;        // gelbe LED an
80
//    I2C_schreiben_byte(0xF5);  // RH noHold-Master
81
    I2C_schreiben_byte(0xE5);  // RH Hold-Master  
82
    I2C_lesen();
83
    P4OUT |= BIT5;        // gelbe LED aus
84
    
85
    ausgeben(Ende,2);
86
87
  }
88
89
}
90
91
#pragma vector = TIMERA0_VECTOR    // ISR-TIMERA0
92
__interrupt void Timer_A (void)
93
{
94
  TACTL &= ~(MC0);
95
  TAR=0;
96
  TAIV = 0;
97
  LPM0_EXIT;                // Exit LPM0 um mit Programmausführung fortzufahren
98
}
99
100
//---------------------------------------------------------------------------------
101
// ausgelagerte Funktionen
102
103
void warte_ms(unsigned int i)
104
{
105
  if(i>=4)
106
  {
107
  TACCR0 = (i<<2);
108
  TACTL |= MC0;
109
  _BIS_SR(LPM0);
110
  }
111
  else
112
  {
113
    TACCR0 = (4<<2);
114
    TACTL |= MC0;
115
    _BIS_SR(LPM0);
116
  }
117
}
118
119
void ausgeben(unsigned char c[], unsigned char len)
120
{
121
  unsigned char i=0;
122
  while(i<len)
123
  {
124
    while (!(IFG2 & UCA0TXIFG));  // USART0 TX buffer ready?
125
      UCA0TXBUF = c[i];
126
    i++;
127
    while(UCBUSY & UCA0STAT);
128
  }
129
}
130
131
void Reset()  // Sensor Reset
132
{
133
  UCB0I2CSA = 0x40;                   // Slave Address 
134
  UCB0CTL1 |= UCTR + UCTXSTT;         // I2C TX, Start senden
135
  UCB0TXBUF = 0xFE;
136
  
137
  while((UCB0CTL1 & UCTXSTT) && !(UCB0STAT & UCNACKIFG));      // Warten bis Start und Adresse gesendet  
138
139
  UCB0CTL1 |= UCTXSTP;              // Stop senden
140
  while(UCB0CTL1 & UCTXSTP);          // Warten bis Stop gesendet  
141
}
142
143
void I2C_schreiben_byte(unsigned char cmd)
144
{
145
146
  UCB0I2CSA = 0x40;                   // Slave Address 
147
  UCB0CTL1 |= UCTR + UCTXSTT;         // I2C TX, Start senden
148
  UCB0TXBUF = cmd;
149
  
150
  while((UCB0CTL1 & UCTXSTT) && !(UCB0STAT & UCNACKIFG));      // Warten bis Start und Adresse gesendet  
151
  
152
  // Kein stop senden
153
}
154
155
// Temperatur oder RH lesen
156
void I2C_lesen()
157
{
158
  unsigned int i=0;
159
  unsigned char j=0;
160
  unsigned char Daten[3] = "000";
161
  
162
  UCB0I2CSA = 0x40;                    // Slave Address 
163
  
164
  UCB0CTL1 &=~UCTR;                   // I2C RX
165
  UCB0CTL1 |= UCTXSTT;                // Start senden
166
  while((UCB0CTL1 & UCTXSTT) && !(UCB0STAT & UCNACKIFG));      // Warten bis Start und Adresse gesendet  
167
  
168
  for (i=0; i<3; i++)
169
  {
170
      while (!(IFG2 & UCB0RXIFG));      // Buffer bereit?
171
//    Daten[i] = UCB0RXBUF;
172
     
173
      if(i==0)            // erstmal ohne Schleifenindex + Array-Index
174
      {Daten[0] = UCB0RXBUF;}
175
      if(i==1)
176
      {Daten[1] = UCB0RXBUF;
177
      UCB0CTL1 |= UCTXSTP;    // beim vorletzten Byte stop senden
178
      }
179
      if(i==2)
180
      {Daten[2] = UCB0RXBUF;}
181
   }
182
  
183
//  UCB0CTL1 |= UCTXSTP;            // Stop senden
184
  while(UCB0CTL1 & UCTXSTP);                    // Warten bis Stop gesendet
185
  
186
  // gleich Daten uebertragen
187
  while(j<3)
188
  {
189
    while (!(IFG2 & UCA0TXIFG));  // USART0 TX buffer ready?
190
      UCA0TXBUF = Daten[j];
191
    j++;
192
    while(UCBUSY & UCA0STAT);
193
  }
194
  
195
//  IFG2 &= ~UCB0RXIFG;    // Clear receive interruptflag
196
}

von Daniel S. (nasenschleim)


Lesenswert?

Sorry, hätte den Code mal lieber als Anhang machen sollen.
Kommt nicht wieder vor.

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.