Hallo, ich bin relativ neu im Bereich des MSP430. Beim aktuellen Projekt eines USB-Tracers hänge ich gerade bei der Instandsetzung der I2C Übertragung. Ich verwende für den Master den MSP430F5310 und für den Empfang den MSP430F6638. Die empfangenen Daten speichere ich in einem Ringbuffer. Nur leider sind die empfangenen Daten ziemlcih durcheinander. SIe kommen einfach nicht in der richtigen Reihenfolge an. Verbaut habe ich 5,1kOhm Pull-ups. Das witzige ist auch, wenn ich Breakpoints setze sowohl in der INterrupt Routine des Senders als auch beim Empfänger, und immer wieder auf Play drücke, kommen die Daten in der richtigen Reihenfolge an. Woran kann das liegen? Es handelt sich hier um den Beispielcode von TI: EMpfänger:
1 | #include <msp430.h> |
2 | #include "circularBuffer.h" |
3 | |
4 | |
5 | volatile unsigned char RXData; |
6 | void Port_Mapping(void); |
7 | |
8 | |
9 | int main(void) |
10 | {
|
11 | WDTCTL = WDTPW + WDTHOLD; // Stop WDT |
12 | Port_Mapping(); |
13 | P2SEL |= 0x03; // Assign P2.0 to UCB0SDA and... |
14 | P2DIR |= 0x03; // P2.1 to UCB0SCL |
15 | |
16 | UCB0CTL1 |= UCSWRST; // Enable SW reset |
17 | UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode |
18 | UCB0I2COA = 0x48; // Own Address is 048h |
19 | UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation |
20 | UCB0IE |= UCRXIE; // Enable RX interrupt |
21 | |
22 | while (1) |
23 | {
|
24 | __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts |
25 | __no_operation(); // Set breakpoint >>here<< and read |
26 | } // RXData |
27 | }
|
28 | |
29 | // USCI_B0 Data ISR
|
30 | #pragma vector = USCI_B0_VECTOR
|
31 | __interrupt void USCI_B0_ISR(void) |
32 | {
|
33 | switch(__even_in_range(UCB0IV,12)) |
34 | {
|
35 | case 0: break; // Vector 0: No interrupts |
36 | case 2: break; // Vector 2: ALIFG |
37 | case 4: break; // Vector 4: NACKIFG |
38 | case 6: break; // Vector 6: STTIFG |
39 | case 8: break; // Vector 8: STPIFG |
40 | case 10: // Vector 10: RXIFG |
41 | addElement(UCB0RXBUF); // Get RX data |
42 | //__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
|
43 | break; |
44 | case 12: break; // Vector 12: TXIFG |
45 | default: break; |
46 | }
|
47 | }
|
48 | |
49 | |
50 | void Port_Mapping(void) |
51 | {
|
52 | // Disable Interrupts before altering Port Mapping registers
|
53 | __disable_interrupt(); |
54 | // Enable Write-access to modify port mapping registers
|
55 | PMAPPWD = 0x02D52; |
56 | |
57 | #ifdef PORT_MAP_RECFG
|
58 | // Allow reconfiguration during runtime
|
59 | PMAPCTL = PMAPRECFG; |
60 | #endif
|
61 | |
62 | P2MAP0 = PM_UCB0SDA; |
63 | P2MAP1 = PM_UCB0SCL; |
64 | |
65 | // Disable Write-Access to modify port mapping registers
|
66 | PMAPPWD = 0; |
67 | #ifdef PORT_MAP_EINT
|
68 | __enable_interrupt(); // Re-enable all interrupts |
69 | #endif
|
70 | }
|
Sender:
1 | #include <msp430.h> |
2 | |
3 | unsigned char TXData; |
4 | unsigned char TXByteCtr; |
5 | |
6 | int main(void) |
7 | {
|
8 | WDTCTL = WDTPW | WDTHOLD; // Stop WDT |
9 | P3SEL |= 0x03; // Assign I2C pins to USCI_B0 |
10 | // P3DIR |= 0x03;
|
11 | UCB0CTL1 |= UCSWRST; // Enable SW reset |
12 | UCB0CTL0 = UCMST | UCMODE_3 | UCSYNC; // I2C Master, synchronous mode |
13 | UCB0CTL1 = UCSSEL_2 | UCSWRST; // Use SMCLK, keep SW reset |
14 | UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz |
15 | UCB0BR1 = 0; |
16 | UCB0I2CSA = 0x48; // Slave Address is 048h |
17 | UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation |
18 | UCB0IE |= UCTXIE; // Enable TX interrupt |
19 | |
20 | TXData = 0x31; // Holds TX data |
21 | |
22 | while (1) |
23 | {
|
24 | TXByteCtr = 1; // Load TX byte counter |
25 | |
26 | //UCB0CTL1 |= UCTXSTP;
|
27 | while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent |
28 | UCB0CTL1 |= UCTR | UCTXSTT; // I2C TX, start condition |
29 | |
30 | __bis_SR_register(GIE); // Enter LPM0 w/ interrupts |
31 | __no_operation(); // Remain in LPM0 until all data |
32 | // is TX'd
|
33 | if(TXData <= 0x39){ |
34 | TXData++; // Increment data byte |
35 | }
|
36 | else{ |
37 | TXData = 0x21; |
38 | }
|
39 | }
|
40 | }
|
41 | |
42 | //------------------------------------------------------------------------------
|
43 | // The USCIAB0_ISR is structured such that it can be used to transmit any
|
44 | // number of bytes by pre-loading TXByteCtr with the byte count.
|
45 | //------------------------------------------------------------------------------
|
46 | #pragma vector = USCI_B0_VECTOR
|
47 | __interrupt void USCI_B0_ISR(void) |
48 | {
|
49 | switch(__even_in_range(UCB0IV,12)) |
50 | {
|
51 | case 0: break; // Vector 0: No interrupts |
52 | case 2: break; // Vector 2: ALIFG |
53 | case 4: break; // Vector 4: NACKIFG |
54 | case 6: break; // Vector 6: STTIFG |
55 | case 8: break; // Vector 8: STPIFG |
56 | case 10: break; // Vector 10: RXIFG |
57 | case 12: // Vector 12: TXIFG |
58 | if (TXByteCtr) // Check TX byte counter |
59 | {
|
60 | UCB0TXBUF = TXData; // Load TX buffer |
61 | TXByteCtr--; // Decrement TX byte counter |
62 | }
|
63 | else
|
64 | {
|
65 | UCB0CTL1 |= UCTXSTP; // I2C stop condition |
66 | UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag |
67 | //__bis_SR_register_on_exit(LPM0_bits); // Exit LPM0
|
68 | }
|
69 | break; |
70 | default: break; |
71 | }
|
72 | }
|