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.

[参考译文] MSP430F5510:I2C 问题

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1256879/msp430f5510-i2c-issue

器件型号:MSP430F5510

大家好、

客户正在调试 msp430F5510+MAX7311的 I2C 操作、目前正在使用例程中的代码 "MSP430F550x_uscib0_i2c_08.c"。  客户配置好端口后、现在它发现在进入中断后无法发送数据、然后退出中断。 从范围来看、它停留在从器件被发送的地址、然后 SCL 时钟似乎有问题。  

原理图如下、单片的 I2C 连接到一个电平转换芯片、一个上拉引脚连接到 I2C 芯片:

运行至:UCB1CTL1 |= UCTR + UCTXSTT;// I2C TX、启动条件

UCSCLLOW 和 UCBBUSY 被置位为1、然后进入一个中断、生成 SCL、并发送从机地址(0x44被置位)。 之后无法继续发送 slave_reg 地址和数据。  

客户通过断点进行调试、并使用 SCLK 在 UCB1I2CSA (0x44)中发送数据。 无法发送 UCB1TXBUF 中的数据(0x11)并且此时钟丢失(在示波器中、前八位数据和第九个确认位可用。 应该没有从第10个时钟开始的数据或时钟)。  

例程如下所示:

规范如下:

#include <msp430f5510.h>
#include "cmd.h"
#include <stdint.h>
#include <stdio.h>

unsigned char timeFlag;

unsigned char *PTxData; // Pointer to TX data
unsigned char TXByteCtr;

const unsigned char TxData[] = // Table of data to transmit
{
0x11,0x22,0x33,0x44,0x55
};

void writeI2C() {
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);
__no_operation();

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

void GPIO_Init(void)
{
PJDIR |= 0x01; // PJ.0 output
}

void I2C_Init(void)
{
P4SEL |= 0x06; // Assign I2C pins to UCB1 P4.1 P4.2
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 = 0x44;
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCTXIE; // Enable TX interrupt
}

void timer0_Init(void)
{
TA0CCTL0 = CCIE; // CCR0 interrupt enabled
TA0CCR0 = 52616; // ~50ms
TA0CTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, upmode, clear TAR
}

void uart_Init(void)
{
P4SEL |= BIT4+BIT5; // P4.4,5 = USCI_A1 TXD/RXD
UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
UCA1CTL1 |= UCSSEL_2; // SMCLK
UCA1BR0 = 9; // 1MHz 115200 (see User's Guide)
UCA1BR1 = 0; // 1MHz 115200
UCA1MCTL |= UCBRS_1 + UCBRF_0; // Modulation UCBRSx=1, UCBRFx=0
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA1IE |= UCRXIE; // Enable USCI_A1 RX interrupt
}

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
GPIO_Init();
I2C_Init();
timer0_Init();
uart_Init();
_EINT();
// __bis_SR_register(GIE);

PrintfBufLen = sprintf(PrintfBuf,"\r\nI2C Switch Debug:\r\n");
UARTwrite(PrintfBuf,PrintfBufLen);

while(1)
{
UartTx();
if(timeFlag == 1)
{
timeFlag = 0;
writeI2C();
}
}
}

// Timer0 A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void)
{
PJOUT ^= 0x01; // Toggle P1.0
timeFlag++;
}

#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
// while (!(UCA1IFG&UCTXIFG)); // USCI_A1 TX buffer ready?
// UCA1TXBUF = UCA1RXBUF; // TX -> RXed character
}

#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_B1 TX int flag
}
default: break;
}
}

您能帮助检查这个案例吗? 谢谢。

此致、

切里

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

    您好、Cherry:

    现在看看这个、他们是否在 MAX7311器件上某处连接了 AD1和 AD2?

    对我来说、这看起来像是一个有效的地址传输、后跟一个基于示波器捕获的 NAK。  

    此致、
    布兰登·费舍尔

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

    尊敬的 Brandon:

    感谢您的支持。

    他们是否在 MAX7311器件上连接了 AD1和 AD2?

    是的、 AD0-AD2分别为010。

    谢谢。此致、

    切里

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

    "地址(十六进制)"列显示包括 R/W 位、它实际上不是地址的一部分。 它们显示的 i2c 地址(A6-A0)为0x22。

    0x22是您应该在 I2CSA 中使用的值。

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

    我相信你是对的、这 是一个很好的抓住布鲁斯的机会。 它们似乎显示了7个 MSB、且 该列中的十六进制结果向左移动以考虑 R/W 位。  

    此致、
    布兰登·费舍尔