Giao tiếp 2 MCU430G2553 bằng I2C

nhokviet

Trứng gà
Mình tìm ở diễn đàng chí có code MCU430G2553 làm Master mà ko có con nào Làm Slave. Bạn nào đã từng làm, hoặc biết giao tiếp 2 con MCU qua I2C thì chỉ mình với. Mình không biết làm như thế nào.

Thank!
 
1 tuần rùi ko ai trả lời thế này :( :la:
điều đó có nghĩa là vấn đề này đã được TI hướng dẫn sẵn trong phần code mẫu. bạn nên tìm kiếm trước khi đặt câu hỏi. vấn đề này mình đã làm rồi, sau khi xem và làm thử mà bạn vẫn thấy có vướng mắc chỗ nào thì lên hỏi, mình tận tình trả lời cho.
 

nhokviet

Trứng gà
Mình có code master & slave thế này, chỉnh sửa từ code mẫu nhưng ko chạy

Master
Code:
//******************************************************************************
#include <msp430.h>
 
unsigned char TXData;
unsigned char TXByteCtr;
 
int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                // Stop WDT
  P1SEL |= BIT6 + BIT7;                    // Assign I2C pins to USCI_B0
  P1SEL2|= BIT6 + BIT7;                    // Assign I2C pins to USCI_B0
  UCB0CTL1 |= UCSWRST;                      // Enable SW reset
  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;    // I2C Master, synchronous mode
  UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
  UCB0BR0 = 12;                            // fSCL = SMCLK/12 = ~100kHz
  UCB0BR1 = 0;
  UCB0I2CSA = 0x48;                        // Slave Address is 048h
  UCB0CTL1 &= ~UCSWRST;                    // Clear SW reset, resume operation
  IE2 |= UCB0TXIE;                          // Enable TX interrupt
 
  TXData = 65;                            // Holds TX data
  P1DIR |= BIT0;
  while (1)
  {
    TXByteCtr = 1;                          // Load TX byte counter
    while (UCB0CTL1 & UCTXSTP);            // Ensure stop condition got sent
    UCB0CTL1 |= UCTR + UCTXSTT;            // I2C TX, start condition
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts
                                            // Remain in LPM0 until all data
                                            // is TX'd
    TXData++;                              // Increment data byte
    P1OUT ^= BIT0;
    __delay_cycles(1000000);
  }
}
 
//------------------------------------------------------------------------------
// The USCIAB0TX_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count.
//------------------------------------------------------------------------------
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
  if (TXByteCtr)                            // Check TX byte counter
  {
    UCB0TXBUF = TXData;                    // Load TX buffer
    TXByteCtr--;                            // Decrement TX byte counter
  }
  else
  {
    UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
    IFG2 &= ~UCB0TXIFG;                    // Clear USCI_B0 TX int flag
    __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
  }
}
Slave
Code:
#include <msp430.h>
#include "lcd16.h"
 
volatile unsigned char RXData;
 
int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                // Stop WDT
  P1SEL |= BIT6 + BIT7;                    // Assign I2C pins to USCI_B0
  P1SEL2|= BIT6 + BIT7;                    // Assign I2C pins to USCI_B0
  UCB0CTL1 |= UCSWRST;                      // Enable SW reset
  UCB0CTL0 = UCMODE_3 + UCSYNC;            // I2C Slave, synchronous mode
  UCB0I2COA = 0x48;                        // Own Address is 048h
  UCB0CTL1 &= ~UCSWRST;                    // Clear SW reset, resume operation
  IE2 |= UCB0RXIE;                          // Enable RX interrupt
 
  P1DIR |= BIT0;
 
  P2DIR = 0xFF;
  P2OUT = 0x00;
  lcdinit();
  prints("MSP430 16x2  LCD");
 
 
  while (1)
  {
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts
    __no_operation();                      // Set breakpoint >>here<< and read
  }                                        // RXData
}
 
// USCI_B0 Data ISR
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
  RXData = UCB0RXBUF;                      // Get RX data
  lcdcmd(0x01); // clear lcd
  waitlcd(250);
  lcdData(RXData);
  __bic_SR_register_on_exit(CPUOFF);        // Exit LPM0
}
Code master gửi từ ký tự A sang Slave rồi Slave xuất ra LCD. Làm thế nhưng ko chạy ko bik nguyên nhân.
 
code mẫu bạn lấy file nào nhỉ? đây là code bên slac485, file uscib0_i2c_09
Code:
//******************************************************************************
//  MSP430G2xx3 Demo - USCI_B0 I2C Slave RX multiple bytes from MSP430 Master
//
//  Description: This demo connects two MSP430's via the I2C bus. The master
//  transmits to the slave. This is the slave code. The interrupt driven
//  data receiption is demonstrated using the USCIB0 RX interrupt.
//  ACLK = n/a, MCLK = SMCLK = default DCO = ~1.2MHz
//
//                                /|\  /|\
//              MSP430G2xx3      10k  10k    MSP430G2xx3
//                  slave        |    |        master
//            -----------------  |    |  -----------------
//          -|XIN  P3.1/UCB0SDA|<-|---+->|P3.1/UCB0SDA  XIN|-
//            |                |  |      |                |
//          -|XOUT            |  |      |            XOUT|-
//            |    P3.2/UCB0SCL|<-+----->|P3.2/UCB0SCL    |
//            |                |        |                |
//
//  D. Dang
//  Texas Instruments Inc.
//  February 2011
//  Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include "msp430g2553.h"
 
unsigned char *PRxData;                    // Pointer to RX data
unsigned char RXByteCtr;
volatile unsigned char RxBuffer[128];      // Allocate 128 byte of RAM
 
void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                // Stop WDT
  P1SEL |= BIT6 + BIT7;                    // Assign I2C pins to USCI_B0
  P1SEL2|= BIT6 + BIT7;                    // Assign I2C pins to USCI_B0
  UCB0CTL1 |= UCSWRST;                      // Enable SW reset
  UCB0CTL0 = UCMODE_3 + UCSYNC;            // I2C Slave, synchronous mode
  UCB0I2COA = 0x48;                        // Own Address is 048h
  UCB0CTL1 &= ~UCSWRST;                    // Clear SW reset, resume operation
  UCB0I2CIE |= UCSTPIE + UCSTTIE;          // Enable STT and STP interrupt
  IE2 |= UCB0RXIE;                          // Enable RX interrupt
 
  while (1)
  {
    PRxData = (unsigned char *)RxBuffer;    // Start of RX buffer
    RXByteCtr = 0;                          // Clear RX byte count
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts
                                            // Remain in LPM0 until master
                                            // finishes TX
    __no_operation();                      // Set breakpoint >>here<< and read
  }                                        // read out the RxData buffer
}
 
//------------------------------------------------------------------------------
// The USCI_B0 data ISR is used to move received data from the I2C master
// to the MSP430 memory.
//------------------------------------------------------------------------------
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
  *PRxData++ = UCB0RXBUF;                  // Move RX data to address PRxData
  RXByteCtr++;                              // Increment RX byte count
}
 
//------------------------------------------------------------------------------
// The USCI_B0 state ISR is used to wake up the CPU from LPM0 in order to
// process the received data in the main program. LPM0 is only exit in case
// of a (re-)start or stop condition when actual data was received.
//------------------------------------------------------------------------------
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
{
  UCB0STAT &= ~(UCSTPIFG + UCSTTIFG);      // Clear interrupt flags
  if (RXByteCtr)                            // Check RX byte counter
    __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0 if data was
}                                          // received
mình thấy bạn enable RX Interrupt
IE2 |= UCB0RXIE; // Enable RX interrupt
mà lại không hề có interrupt handler nào cho RX đó. trong code mẫu có đấy, xem ra bạn cần xét lại kỹ hơn.
 

nhokviet

Trứng gà
Bác xem code mẫu 05 & 06 đi, 2 cái interrupt TX và RX nó dùng chung với nhau.

Exm: msp430g2xx3_uscib0_i2c_06 & msp430g2xx3_uscib0_i2c_05
 
Bác xem code mẫu 05 & 06 đi, 2 cái interrupt TX và RX nó dùng chung với nhau.

Exm: msp430g2xx3_uscib0_i2c_06 & msp430g2xx3_uscib0_i2c_05
msp430g2xx3_uscib0_i2c_05:Slave TX single bytes to MSP430 Master
msp430g2xx3_uscib0_i2c_06:Master TX single bytes to MSP430 Slave
=> cả 2 thằng cùng muốn nói thì ai nghe ai đây bạn?
Code bạn cần dùng là file msp430g2xx3_uscib0_i2c_07: Slave RX single bytes from MSP430 Master chứ ko phải file 05 nhé.
 

nhokviet

Trứng gà
Bác xem code mẫu 05 & 06 đi, 2 cái interrupt TX và RX nó dùng chung với nhau.

Exm: msp430g2xx3_uscib0_i2c_06 & msp430g2xx3_uscib0_i2c_05
msp430g2xx3_uscib0_i2c_05:Slave TX single bytes to MSP430 Master
msp430g2xx3_uscib0_i2c_06:Master TX single bytes to MSP430 Slave
=> cả 2 thằng cùng muốn nói thì ai nghe ai đây bạn?
Code bạn cần dùng là file msp430g2xx3_uscib0_i2c_07: Slave RX single bytes from MSP430 Master chứ ko phải file 05 nhé.
uhm mình dùng hình như 06 07 đó bạn, có thể mình nhầm đấy, nhưng mà mình xem 1 vài ex thì nó toàn dùng 1 interrupt.

Mình đã làm nó hoạt động được rồi. dùng 1 interrupt thôi.
 
Top