This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430BT5190:I2C 未正确初始化

Guru**** 2379260 points
Other Parts Discussed in Thread: MSP430BT5190
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1170221/msp430bt5190-i2c-not-initializing-properly

器件型号:MSP430BT5190
主题中讨论的其他器件: MSP430WARE

可能涉及的人员、

我尝试使用 MSP430BT5190上的 I2C 功能、由于某种原因、它无法正常工作。
我尝试使用 Arduino 读取 I2C 线路和示波器、但 P1.0上的 LED 确实会打开和关闭、但我不会通过 SDA 或 SCL 传输任何内容。

我重复使用 MSP430F5418AIPNR 上用于 I2C 初始化和发送的代码。
我通过每个寄存器来确保这个迭代和最后一个迭代具有相同的 I2C 初始化和标志值。

我不确定在哪里取得我的成果、如果有任何帮助、我将不胜感激。

因此、
Andres Choy Buentello

#include    <msp430.h>
#include    "stdbool.h"

#define     i2c_address     0x28

/**
 * blink.c
 */

unsigned char TxByteCtr;
unsigned char RxByteCtr;
int sendCounter;
_Bool UCB0_Done;
unsigned char *PTxData;
unsigned char i2c_info;

void i2c_send(unsigned char slave_address, unsigned char *DataBuffer, unsigned char ByteCtr)
{
    UCB0I2CSA = slave_address;

    UCB0IFG &= ~(UCTXIFG + UCRXIFG);    // Clear any pending interrupts
    UCB0IE &= ~UCRXIE;                  // Disable RX interrupt
    UCB0IE |= UCTXIE;                   // Enable TX interrupt

    PTxData = DataBuffer;
    TxByteCtr = ByteCtr;
    sendCounter= 0;
    UCB0_Done = false;

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

    // wait for USB to finish
    while(!UCB0_Done)
    { asm(" nop"); }

    asm(" nop");
}

void main(void)
{
	WDTCTL = WDTPW | WDTHOLD;		// stop watchdog timer
	P1DIR |= 0x01;					// configure P1.0 as output

	//Timer Specific lines
	TA1CCTL0 = CCIE;                                        // CCR0 interrupt enabled
	TA1CCR0 = ((14745600ul/8ul) / 100ul) -1;
	TA1CTL = ID__8 + TASSEL__SMCLK + MC_1 + TACLR;         // SMCLK, contmode, clear TAR

	//I2C Specific Init lines
	P3SEL |= BIT1 | BIT2;                     // P3.0,1 option select

	UCB0CTL1 |= UCSWRST;                                                // Enable SW reset
	UCB0CTL0  = UCMST + UCMODE_3 + UCSYNC;                              // I2C Master, synchronous mode
	UCB0CTL1  = UCSSEL_2 + UCSWRST;                                     // Use SMCLK, keep SW reset
	// TI example uses 12
	UCB0BR0   = 36;                                                     // fSCL = SMCLK/10 = ~100kHz with SMCLK = 1MHz
	UCB0BR1   = 0;
	UCB0CTL1 &= ~UCSWRST;                                               // Clear SW reset, resume operation
	UCB0IE      |=  UCNACKIE;                                               // Enable TX interrup

	volatile unsigned int i;		// volatile to prevent optimization
	int send_cnt = 0;

	while(1)
	{
	    // Prepping data to send
	    if (send_cnt == 0)
	    {
	        i2c_info = 0x00;
	        send_cnt = send_cnt + 1;
	    } else if (send_cnt == 1){
	        i2c_info = 0x01;
	        send_cnt = send_cnt + 1;
	    } else if (send_cnt == 2){
	        i2c_info = 0x02;
	        send_cnt = send_cnt + 1;
	    } else if (send_cnt == 3){
	        i2c_info = 0x03;
	        send_cnt = 0;
	    }

	    // Send data
	    i2c_send(i2c_address, (unsigned char *)i2c_info, 2);
	    __bis_SR_register(GIE);                                 // Enter LPM3, enable interrupts
	    __no_operation();                                       // For debugger


	    // Visual verify that indo is being sent
	    P1OUT ^= 0x01;				// toggle P1.0
		for(i=10000; i>0; i--);     // delay
	}
}

#pragma vector=USCI_B0_VECTOR
__interrupt void USCIAB0TX_ISR(void) {
  switch(__even_in_range(UCB0IV,12))
  {
  case  0:
    break;                // Vector  0: No interrupts
  case  2:
    asm(" nop");
    break;          // Vector  2: ALIFG
  case  4:
    asm(" nop");
    break;              // Vector  4: NACKIFG
  case  6:                      // Vector  6: STTIFG
    asm(" nop");
    break;
  case  8:                      // Vector  8: STPIFG
    asm(" nop");
    break;
  case 10:                      // Vector 10: RXIFG
    asm(" nop");
    break;
  case 12:                      // Vector 12: TXIFG
    if (TxByteCtr) {                                                    // Check TX byte counter
      UCB0TXBUF = *PTxData++;                                         // Load TX buffer
      TxByteCtr--;                                                    // Decrement TX byte counter
      sendCounter++;
    } else {
      UCB0CTL1 |= UCTXSTP;                                            // I2C stop condition
      UCB0IE &= ~UCTXIE;
      UCB0_Done = true;
    }
    break;
  default:
    asm(" nop");
    break;
  }
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我在这里看到了一些奇怪的现象、尽管我无法将其中的任何一个与您所说的症状相关联("没有 I2C 活动"):

    1) 1)第一次调用 i2c_send 时、GIE=0、因此它将挂起在 "while (!UCB0_DONE)"循环中。 不过、您会在总线上看到 SLA 字节。 我建议您在 main 中的 while (1)之前添加"__enable_interrupt ();"。

    2) 2)您设置了 TA1CCR0:CCIE、但我看不到它的 Timer1_A0_vector ISR。 大约140ms 后、您将最终进入 ISR_TRAP (在第一次调用 i2c_send 之前、可能是也可能不是)。 我建议您添加 ISR;对于 A0_vector、它可能为空。

    3)在"i2c_send (i2c_address、(unsigned char *) i2c_info、2);"中、i2c_info 是标量、因此这将从低内存(0x00)写入数据。 由于您要发送2个字节、我希望 i2c_info 应该是一个数组。 用户指南(SLAU208Q)第1.11节声称您不会获得用于从位置0读取数据的 VMAIFG、但您可能仍想修复此问题。  

    这些可能是也可能不是您症状的原因、但如果您解决了这些问题、您将能够看到您真正关注的问题。

    [编辑:(4) UCB0_DONE 应声明为"volatile"。 这可能不是您现在的问题、但最终将是问题。]

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Andres、

    要调试 I2C 问题、请参阅以下应用手册: www.ti.com/lit/slaa734 

    还建议参考或从 TI Resource Explorer - MSP430Ware 中的 I2C 标准示例开始 I2C 开发: https://dev.ti.com/tirex/explore/node?node=A__AA3fvwdFUxJ93NAxjS1fag__msp430ware__IOGqZri__LATEST 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    非常感谢您的回复。

    1) 1)您能否为我提供更多有关 SLA 字节的查找位置或它是什么的信息?
    我确实在 while 循环之前添加了中断、但它仍在 while 循环上挂起

    2) 2)感谢您、我确实看到了 ISR_TRAP 问题、我添加了您的建议、并且该建议有效。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    SLA 是指从器件地址字节(地址+ R/W 位)、该字节在"开始"条件之后出现。 这在您设置 UCTXSTT 后自动生成。 您会在您的示波器上看到它。 您在示波器上确切看到了什么?

    UCB0_DONE 环路上的挂起可能来自上面的(1)或(4)。