Forum: Mikrocontroller und Digitale Elektronik MSP430F5438 I2C


von el_Studente (Gast)


Lesenswert?

Hallo,
Ich hab immer noch ein kleines I2c Problem. Ich versuche mit meine µC 
erst einen Befehl zu senden und dann eine antwort auszulesen. Leider 
klappt das noch nicht so richtig. Vielleicht habt ihr eine Idee für 
meinen Code:
1
#include "msp430x54x.h"
2
3
unsigned char *PTxData;                     // Pointer to TX data
4
unsigned char TXByteCtr;
5
unsigned char *PRxData;                     // Pointer to RX data
6
unsigned char RXByteCtr;
7
volatile unsigned char RxBuffer[128];       // Allocate 128 byte of RAM
8
9
const unsigned char TxData[] =              // Table of data to transmit
10
{
11
 0x50
12
};
13
14
void main(void)
15
{
16
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
17
  P3SEL |= 0x80;
18
  P5SEL |= 0x10;                            // Assign I2C pins to USCI_B1
19
  P8OUT |= 0x80;                            // Set P1.0 for LED
20
  P8DIR |= 0x80;   
21
  UCB1CTL1 |= UCSWRST;                      // Enable SW reset
22
  UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
23
  UCB1CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
24
  UCB1BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
25
  UCB1BR1 = 0;
26
  UCB1I2CSA = 0x19;                         // Slave Address is 048h
27
  UCB1CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
28
  UCB1IE |= UCTXIE;                         // Enable TX interrupt
29
30
  while (1)
31
  {
32
    __delay_cycles(50);   // Delay required between transaction
33
    PTxData = (unsigned char *)TxData;      // TX array start address
34
                                            // Place breakpoint here to see each
35
                                            // transmit operation.
36
    TXByteCtr = sizeof TxData;              // Load TX byte counter
37
38
    P8OUT |= 0x80;                            // reset slave
39
    __delay_cycles(100);
40
    P8OUT &= ~0x80;
41
    UCB1CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
42
43
    __bis_SR_register(LPM0_bits + GIE);// Enter LPM0, enable interrupts
44
    __no_operation();
45
    while (UCB1CTL1 & UCTXSTP);             // Ensure stop condition got sent
46
    
47
    __delay_cycles(2000);
48
    PRxData = (unsigned char *)RxBuffer;    // Start of RX buffer
49
    RXByteCtr = 6;                          // Load RX byte counter
50
    while (UCB1CTL1 & UCTXSTP);             // Ensure stop condition got sent
51
    UCB1CTL1 &= ~UCTR;
52
    UCB1CTL1 |= UCTXSTT;                    // I2C start condition
53
    
54
    __bis_SR_register(LPM0_bits + GIE);     // Enter LPM0, enable interrupts
55
                                            // Remain in LPM0 until all data
56
                                            // is RX'd
57
    __no_operation();                       // Set breakpoint >>here<< and// Remain in LPM0 until all data
58
59
    __delay_cycles(20000);                                        // is TX'd
60
  
61
  }
62
}
63
64
//------------------------------------------------------------------------------
65
// The USCIAB1TX_ISR is structured such that it can be used to transmit any
66
// number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData
67
// points to the next byte to transmit.
68
//------------------------------------------------------------------------------
69
#pragma vector = USCI_B1_VECTOR
70
__interrupt void USCI_B1_ISR(void)
71
{
72
  switch(__even_in_range(UCB1IV,12))
73
  {
74
  case  0: break;                           // Vector  0: No interrupts
75
  case  2: break;                           // Vector  2: ALIFG
76
  case  4: break;                           // Vector  4: NACKIFG
77
  case  6: break;                           // Vector  6: STTIFG
78
  case  8: break;                           // Vector  8: STPIFG
79
  case 10:     
80
    RXByteCtr--;                            // Decrement RX byte counter
81
    if (RXByteCtr)
82
    {
83
      *PRxData++ = UCB1RXBUF;               // Move RX data to address PRxData
84
      if (RXByteCtr == 1)                   // Only one byte left?
85
        UCB1CTL1 |= UCTXSTP;                // Generate I2C stop condition
86
    }
87
    else
88
    {
89
      *PRxData = UCB1RXBUF;                 // Move final RX data to PRxData
90
      __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
91
    }
92
    break;                           // Vector 10: RXIFG
93
  case 12:                                  // Vector 12: TXIFG
94
    if (TXByteCtr)                          // Check TX byte counter
95
    {
96
      UCB1TXBUF = *PTxData++;               // Load TX buffer
97
      TXByteCtr--;                          // Decrement TX byte counter
98
    }
99
    else
100
    {
101
      UCB1CTL1 |= UCTXSTP;                  // I2C stop condition
102
      UCB1IFG &= ~UCTXIFG;                  // Clear USCI_B1 TX int flag
103
      __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
104
    }
105
  default: break;
106
  }
107
}


Vielen Dank für eure Hilfe!!!

von Jörg S. (joerg-s)


Lesenswert?

>Leider klappt das noch nicht so richtig.
Geht es etwas genauer?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Es gibt von TI Beispielcode (SLAA384) für I2C mit der USCI.

Allerdings ist der nicht direkt für den 'F5438, man muss ein paar Bits 
in anderen Registern unterbringen. TI hat die Interruptregister beim 
'5438 gegenüber den älteren USCI-Implementierungen etwas aufgeräumt.

Ist aber nicht so irrwitzig schwierig, das zum Laufen zu bringen.

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.