Forum: Mikrocontroller und Digitale Elektronik MSP430G2232 USI I2C Slave


von fluxi (Gast)


Lesenswert?

Hallo,

ich habe ein Problem mit meinem MSP430G2232. Und zwar habe ich von TI 
ein Code-Example verwendet und ein wenig umgebaut. Mein Ziel ist es, 
dass der MSP430 z.b. 2 Bytes empfängt (1 Kommando, 1 Wert) und die 
beiden Bytes in ein Array/Variable abspeichert um diese dann in der main 
Funktion weiter zu verarbeiten.
Ich bin noch ganz neu auf diesem Gebiet.
Die Kommunikation von I2C funktioniert. Habe das Senden und Empfangen 
mit meinem Oszi gemessen. Nur das speichern der gesendeten und 
empfangenen Werte machen mir Probleme. Wahrscheinlich habe ich irgendwo 
einen Denkfehler, vllt. könnt ihr mir auf die Sprünge helfen.

Vielen Dank!
1
#pragma vector = USI_VECTOR
2
__interrupt void USI_ISR (void)
3
{  
4
  if (USICTL1 & USISTTIFG)
5
  {
6
    I2C_State = 2;            // Enter 1st state on start
7
  }
8
  
9
  switch (I2C_State)
10
  {
11
    /* Idle */
12
    case 0:
13
      break;
14
    
15
    /* RX address */  
16
    case 2:
17
      USICNT = (USIIFGCC | 0x08);    // Stop auto clr USIIFG, read 8 bits
18
      USICTL1 &= ~USISTTIFG;      // Clear start flag
19
      I2C_State = 4;          // Next state: check addres
20
      break;
21
    
22
    /* Check address and send (N)ACK */  
23
    case 4:
24
      if (USISRL & 0x01)        // If Master read...
25
      {
26
        slv_addr = rd_addr;      // Save R/W bit
27
        transmit = 1;
28
      }
29
      else
30
      {
31
        slv_addr = 0x60;
32
        transmit = 0;
33
      }  
34
      
35
      USICTL0 |= USIOE;        // SDA = Output
36
      
37
      if (USISRL == slv_addr)      // Address match?
38
      {
39
        USISRL = 0x00;        // Send ACK
40
        
41
        if (transmit == 0)
42
        {
43
          I2C_State = 6;      // Next state: RX data
44
        }
45
        else
46
        {
47
          I2C_State = 10;      // Next state: TX data
48
        }
49
      }
50
      else
51
      {
52
        USISRL = 0xFF;        // Send NACK
53
        I2C_State = 8;
54
      }
55
      
56
      USICNT |= 0x01;          // Bit counter = 1, send (N)ACK bit
57
      break;
58
    
59
    /* RX data byte */  
60
    case 6:
61
      RX_Data ();
62
      break;
63
    
64
    /* Check data & TX (N)ACK */
65
    case 8:
66
      USICTL0 |= USIOE;        // SDA = Output
67
      if(ByteCtr <= NUM_BYTES)
68
      {
69
        USISRL = 0x00;        // Send ACK
70
        I2C_State = 6;        // RX another byte
71
        ByteCtr++;
72
        USICNT |= 0x01;        // Bit counter = 1, send (N)ACK
73
//        
74
      }
75
      else
76
      {
77
        USISRL = 0xFF;        // Send NACK
78
        USICTL0 &= ~USIOE;      // SDA = Input
79
        I2C_State = 0;        // Reset state machine
80
        ByteCtr = 0;        // Reset counter for next TX/RX
81
//        
82
      }
83
      break;
84
      
85
    /* TX data byte */
86
    case 10:
87
      TX_Data ();
88
      break;
89
    
90
    /* Receive (N)ACK */
91
    case 12:
92
      USICTL0 &= ~USIOE;        // SDA = Input
93
      USICNT |= 0x01;          // Bit counter = 1, receive (N)ACK
94
      I2C_State = 14;          // Next state: check (N)ACK
95
      break;
96
    
97
    /* Process Data ACK/NACK */  
98
    case 14:
99
      if (USISRL & 0x01)        // If NACK received...
100
      {
101
        USICTL0 &= ~USIOE;      // SDA = input
102
        slv_addr = 0x60;
103
        I2C_State = 0;        // Reset state machine
104
        ByteCtr = 0;        // Reset counter
105
      }
106
      else
107
      {
108
        TX_Data ();          // TX next byte
109
      }
110
      break;
111
  }
112
  
113
  USICTL1 &= ~USIIFG;            // Clear pending flags
114
}
115
116
/* Receive data over I2C */
117
static void RX_Data (void)
118
{
119
  USICTL0 &= ~USIOE;    // SDA = Input
120
  USICNT |= 0x08;      // Bit counter = 8
121
  RxBuffer[RXByteCtr] = USISRL;
122
  RXByteCtr++;
123
  I2C_State = 8;      // Test data and send (N)ACK
124
}
125
126
/* Transmit data over I2C */
127
static void TX_Data (void)
128
{
129
  USICTL0 |= USIOE;    // SDA = Output
130
  USISRL = TxBuffer[TXByteCtr];
131
  TXByteCtr++;
132
  USICNT |= 0x08;      // Bit counter = 8
133
  I2C_State = 12;      // Receive (N)ACK
134
}

von Krapao (Gast)


Lesenswert?

> und die beiden Bytes in ein Array/Variable abspeichert um diese dann in
> der main Funktion weiter zu verarbeiten.
1
int main(void)
2
{
3
  DATENTYP1 idx = 0; // To do: gleicher DATENTYP wie RXByteCtr 
4
  DATENTYP2 b; // To do: gleicher DATENTYP wie ein Element von RxBuffer[]
5
6
  while(1)
7
  {
8
    if ( idx < RXByteCtr )
9
    {
10
      b = RxBuffer[idx++];
11
      // To do: Was mit b machen
12
    }
13
    else
14
    {
15
      // To do: IRQ USI_ISR sperren
16
      RXByteCtr = 0; // I2C RX Puffer zurücksetzen
17
      // To do: IRQ USI_ISR freigeben
18
      idx = 0;
19
    }
20
  }  
21
}

von fluxi (Gast)


Lesenswert?

Danke für den Denkanstoß, werde ich nachher mal ausprobieren.
Sind denn die RX_Data und TX_Data Funktionen korrekt und funktioniert 
das mit
1
RxBuffer[RXByteCtr] = USISRL;
1
USISRL = TxBuffer[TXByteCtr];
 korrekt oder habe ich etwas übersehen?

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.