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.

[参考译文] MSP430G2553:I2C 数据问题

Guru**** 2538950 points
Other Parts Discussed in Thread: MSP430G2553

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

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

器件型号:MSP430G2553

各位专家:

我有一个 EEPROM、我将尝试连接到 MSP430G2553。 我为 I2C 编写了一个驱动程序、问题是它必须将数据从 MSB 发送到 LSB、但控制器恰好相反。 我要说的另一件事是、它进入 RX 中断、但它检查一条 if 语句并从 ISR 发出。 它没有执行在 RX 中断中写入的代码。 有没有人能指出我在这里提到的问题

1) 1) MSB 到 LSB 的问题和

2) 2) I2C Rx 中断仅检查条件并从该条件发出、它不会执行任何语句。

静态内联 void init_sysClock (void)

BCSCTL1 = CALBC1_1MHz;//将 DCO 设置为1MHz
DCOCTL = CALDCO_1MHz;
BCSCTL3 = LFXT1S_0;// LFXT1 = 32KHz
BCSCTL2 = SELM_0;//选择 SMCLK = MCLK = DCOCLK

空 initI2C()

//为 I2C 总线插入 GPIO
P3REN |= BIT6 + BIT7;
I2C_PIN_SEL |= BIT6 + BIT7;//将 I2C 引脚分配给 USCI_B0
I2C_PIN_SEL2 |= BIT6 + BIT7;// I2C 引脚配置

UCB0CTL1 |= UCSWRST;
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC + UCMSB;
UCB0CTL1 = UCSSEL_2 + UCSWRST;
UCB0BR0 = 10;//我们的 SMCLK = 1MHz。 SMCLK/10 =~100KHz
UCB0BR1 = 0;
UCB0I2CSA = SLAVE_READ_ADDR;
UCB0CTL1 &=~UCSWRST;
UCB0I2CIE |= UCNACKIE;

I2C_Mode I2C_Master_WriteReg (uint8_t dev_addr、uint8_t reg_addr、uint8_t * reg_data、uint8_t count)

MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
UCB0_TxComplete =错误;
//将寄存器数据复制到 TransmitBuffer
CopyArray (reg_data、TransmitBuffer、count);

TXByteCtr =计数;
RXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;

/*初始化从地址和中断*/
UCB0I2CSA = DEV_addr;
IFG2 &=~μ s (UCB0TXIFG + UCB0RXIFG);//清除任何挂起的中断
IE2 &=~UCB0RXIE;//禁用 RX 中断
IE2 |= UCB0TXIE;//启用 TX 中断

UCB0CTL1 |= UCTR + UCTXSTT;// I2C TX、启动条件
_bis_SR_register (CPUOFF + GIE);//输入 LPM0、带中断
while (!UCB0_TxComplete);
返回 MasterMode;

I2C_Mode I2C_Master_ReadReg (uint8_t dev_addr、uint8_t reg_addr、uint8_t count)

/*初始化状态机*/
UCB0_RxComplete =错误;
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
RXByteCtr =计数;
TXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;

/*初始化从地址和中断*/
UCB0I2CSA = DEV_addr;
IFG2 &=~μ s (UCB0TXIFG + UCB0RXIFG);//清除任何挂起的中断
IE2 &=~UCB0RXIE;//禁用 RX 中断
IE2 |= UCB0RXIE;//启用 RX 中断

UCB0CTL1 |= UCTR + UCTXSTT;// I2C TX、启动条件
_bis_SR_register (CPUOFF + GIE);//输入 LPM0、带中断
while (!UCB0_RxComplete);
返回 MasterMode;

void main (void)

WDTCTL = WDTPW + WDTHOLD;

init_system();

initi2C();

I2C_Master_ReadReg (SLAVE_READ_ADDR、0x00、1);

while (1)

__no_operation();

#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector = USCIAB0TX_vector
_interrupt void USCIAB0TX_ISR (void)
#Elif defined (_GNU_)
void __attribute__((interrupt (USCIAB0TX_vector)) USCIAB0TX_ISR (void)
其他
错误编译器不受支持!
#endif

IF (IFG2 & UCB0TXIFG)//发送数据中断

开关(主模式)

案例 TX_REG_ADDRESS_MODE:
UCB0TXBUF = TransmitRegAddr;
IF (RXByteCtr)
MasterMode = SWITCH_TO_RX_MODE;//需要立即开始接收
其他
MasterMode = TX_DATA_MODE;//继续转换发送缓冲区中的数据
中断;

案例切换至 RX_MODE:
IE2 |= UCB0RXIE;//启用 RX 中断
IE2 &=~UCB0TXIE;//禁用 TX 中断
UCB0CTL1 &=~Ω UCTR;//切换到接收器
MasterMode = RX_DATA_MODE;//状态是接收数据
UCB0CTL1 |= UCTXSTT;//发送重复起始
IF (RXByteCtr = 1)

//必须发送停止,因为这是 N-1字节
while ((UCB0CTL1 & UCTXSTT));
UCB0CTL1 |= UCTXSTP;//发送停止条件

中断;

案例 TX_DATA_MODE:
IF (TXByteCtr)

UCB0TXBUF =传输缓冲器[TransmitIndex++];
TXByteCtr --;

其他

//传输完成
UCB0_TxComplete =真;
UCB0CTL1 |= UCTXSTP;//发送停止条件
MasterMode = IDLE_MODE;
IE2 &=~UCB0TXIE;//禁用 TX 中断
_BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0

中断;

默认值:
__no_operation();
中断;


#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector = USCIAB0RX_vector
_interrupt void USCIAB0RX_ISR (void)
#Elif defined (_GNU_)
void __attribute__((interrupt (USCIAB0RX_vector)) USCIAB0RX_ISR (void)
其他
错误编译器不受支持!
#endif

IF (IFG2 & UCB0RXIFG)//接收数据中断

//必须从 UCB0RXBUF 中读取
uint8_t Rx_val = UCB0RXBUF;

IF (RXByteCtr)

ReceiveBuffer[ReceiveIndex++]= Rx_val;
RXByteCtr---;

IF (RXByteCtr = 1)

UCB0CTL1 |= UCTXSTP;
UCB0_RxComplete =真;

否则、如果(RXByteCtr = 0)

IE2 &=~UCB0RXIE;
MasterMode = IDLE_MODE;
_BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0


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

    UCMSB 是指字节中的最高有效位、I2C 定义表明您需要该位。

    如果 EEPROM 大于256字节、则需要以多个字节的形式发送地址、(在我熟悉的存储器器件上)首先发送最高有效字节。 发送地址时、必须将其分解为字节。  

    在 I2C 存储器器件上、地址等效于(大多数)其他 I2C 器件的"寄存器编号"。 当我读取此代码时、它假定寄存器编号(在您的情况下为存储器地址)只有一个字节宽(TransmitRegAddr)。 您需要做的是扩展该值以适应更宽的地址、主要是 在 ISR 中的 TX_REG_ADDRESS_MODE 情况下。

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

    您好、Bruce、

    根据您的建议、我从 I2C Init 过程中删除了 UCMSB 位、您在代码中发现了任何其他问题、或者它应该起作用吗?

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

    不应删除 UCMSB、因为 I2C 规范要求它。

    您应该将"寄存器编号"(存储器地址)的宽度扩展到 EEPROM 需要的多个字节、这取决于 EEPROM 的大小。 您使用的是什么 EEPROM 器件?