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 | }
|