TI中文支持网
TI专业的中文技术问题搜集分享网站

MSP430F5418A I2C通信问题

Hi all,

MSP430F5418A在用I2C通信过程中,需要将slave的地址装到寄存器中,我用的是7位地址模式,但是还有一位读/写位放在什么位置呢?

是和地址放到一起吗?

还有,如果我是想从slave中读数据,那么先要将地址写入,之后再写入要读去哪个寄存器,才开始读。整个过程中是不是需要读和写的过程转换?如果需要的话,应该如何

转换数据方向?

 

谢谢

 

Nick

Nick wang:

Hi

还是我,另外一个问题,当slave收到数据之后,会给master一个ACK,这个ACK是slave自动发的吧?master在检测到

ACK之后,才会继续发送下一个数据吗?

谢谢

Nick

Young Hu:

回复 Nick wang:

还是我,另外一个问题,当slave收到数据之后,会给master一个ACK,这个ACK是slave自动发的吧?master在检测到

ACK之后,才会继续发送下一个数据吗?

1、ACK是由slave自动发送的;

2、ACK是一个握手标志,如果没有检测到ACK,那么说明从机通信失败,需要重新建立通信过程。

Nick wang:

回复 Young Hu:

Hi,

十分感谢您及时的回复。

Nick

Nick wang:

回复 Young Hu:

Hi,

我在用i2c通信过程又遇到了以下问题:

我在发送数据过程中,为什么只发送了几个byte就从ISR中跳出来了?而且在发送数据过程中,STAT寄存器中SCLLOW

位始终置位,这是对的吗?

我的程序如下所示:

#include "msp430x54xA.h"

unsigned char *PTxData;                     // Pointer to TX data

unsigned char TXByteCtr;

#define VCC3P3_PwrOn         (P8OUT |= BIT5)

#define VCC3P3_PwrGood       (P8IN & BIT6)

#define LED_ON               (P3OUT &= ~(BIT6))

#define LED_OFF              (P3OUT |= BIT6)

const unsigned char TxData[] =              // Table of data to transmit

{

 0x01,

 0x0b,

 0x02,

 0x00,

 0x00,

 0x03,

 0x32,

 0x00,

};

void test_mcu_port_init(void);

void main(void)

{

 WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

 test_mcu_port_init();

 VCC3P3_PwrOn;

 while(!(VCC3P3_PwrGood))

 {

;

 }

 LED_ON;

 P3SEL |= 0x80;                            // Assign I2C pins to USCI_B0

 P5SEL |= 0x10;

 UCB1CTL1 |= UCSWRST;                      // Enable SW reset

 UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode

 UCB1CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset

 UCB1BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz

 UCB1BR1 = 0;

 UCB1I2CSA = 0x4a;                         // Slave Address is 048h

 UCB1CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation

 UCB1IE |= UCTXIE;                         // Enable TX interrupt

//  while (1)

//  {

   __delay_cycles(50);                     // Delay required between transaction

   PTxData = (unsigned char *)TxData;      // TX array start address

                                           // Place breakpoint here to see each

                                           // transmit operation.

   TXByteCtr = sizeof TxData;              // Load TX byte counter

   UCB1CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition

   __bis_SR_register(GIE);     // Enter LPM0, enable interrupts

   __no_operation();                       // Remain in LPM0 until all data

                                           // is TX'd

   while (UCB1CTL1 & UCTXSTP);             // Ensure stop condition got sent

//  }

}

void test_mcu_port_init(void)

{

/*将所有端口恢复到初始值*/

P1OUT &= 0x00;

P2OUT &= 0x00;

P3OUT &= 0x00;

/*LED为关闭状态*/

LED_OFF;

P4OUT &= 0x00;

/*I/O扩展芯片中断管脚拉高*/

P4OUT |= BIT6;

P5OUT &= 0x00;

P6OUT &= 0x00;

P7OUT &= 0x00;

/*关闭1.8V的MOSFET*/

P7OUT |= BIT4;

P8OUT |= 0x00;

/*定义所有端口方向和功能选择*/

P1SEL |= 0x00;

P1DIR |= 0x5b;

P2SEL |= 0x00;

P2DIR |= 0xe7;

P3SEL |= 0xbf;

P3DIR |= 0x40;

P4SEL |= 0x59;

P4DIR |= 0xae;

P5SEL |= 0xd0;

P5DIR |= 0x25;

P6SEL |= 0x03;

P6DIR |= 0x78;

P7SEL |= 0x0b;

P7DIR |= 0xb4;

P8SEL |= 0x00;

P8DIR |= 0x3f;

}

//——————————————————————————

// 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. Also, TXData

// points to the next byte to transmit.

//——————————————————————————

#pragma vector = USCI_B1_VECTOR

__interrupt void USCI_B1_ISR(void)

{

 switch(__even_in_range(UCB1IV,12))

 {

 case  0: break;                           // Vector  0: No interrupts

 case  2: break;                           // Vector  2: ALIFG

 case  4: break;                           // Vector  4: NACKIFG

 case  6: break;                           // Vector  6: STTIFG

 case  8: break;                           // Vector  8: STPIFG

 case 10: break;                           // Vector 10: RXIFG

 case 12:                                  // Vector 12: TXIFG

   if (TXByteCtr)                          // Check TX byte counter

   {

     UCB1TXBUF = *PTxData++;               // Load TX buffer

     TXByteCtr–;                          // Decrement TX byte counter

   }

   else

   {

     UCB1CTL1 |= UCTXSTP;                  // I2C stop condition

     UCB1IFG &= ~UCTXIFG;                  // Clear USCI_B0 TX int flag

   }

 default: break;

 }

}

请帮忙解答一下

Thx

Nick

Young Hu:

回复 Nick wang:

Nick,您好,

建议您参考一下TI最近刚推出的一个MSP430的一个驱动库,其中就包括了I2C的使用,可以参考一下这部分代码。

www.ti.com.cn/…/msp430ware

Xiaowei Bai1:

Hi,

1,当写数据的时候,Master每发送完8个数据位,Slave设备如果还有空间接受下一个字节回答“ACK”,如果没有空间接收数据了,就不会发“ACK”,所以是需要检测到“ACK”后再发送下个数据个Slave.

Hardy Hu:

回复 Nick wang:

是的,ACK是slave发送,发完第8bit后,master会release SDA给slave,等待ACK,如果slave不把SDA拉低,则会触发NACK,如果拉低会触发UCB0TXIFG,因为我们一般在NCAK中断中放置STOP或者重发,在TXIFG被置位后说明slave收到了改数据,才再开始发送下一个数据

Hardy Hu:

回复 Xiaowei Bai1:

实现这个功能可以这样做,不接受数据了,在RXIFG中断中read RXBUF,然后generate NACK。

Hardy Hu:

回复 Hardy Hu:

这是从机这边的程序。

在主机端,接收到NACK时generate stop就行了。

赞(0)
未经允许不得转载:TI中文支持网 » MSP430F5418A I2C通信问题
分享到: 更多 (0)