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.

[参考译文] CCS/MSP430G2102:I'm使用MSP430G2102作为I2C从接收器,我无法在USISRL寄存器中获取正确的数据

Guru**** 2553450 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/590744/ccs-msp430g2102-i-m-using-msp430g2102-as-an-i2c-slave-receiver-i-can-not-get-the-right-data-in-the-usisrl-register

部件号:MSP430G2102

工具/软件:Code Composer Studio

我使用USI作为I2C从接收器,无法在USISRL寄存器中获取正确的数据。源代码是TI资源浏览器中的示例msp430g2xxS 2_USI_08.c。

我可以正确输入I2C启动中断和I2C接收中断。

我将I2C总线波形和USI寄存器的图片粘贴在末尾

谢谢!

#include <MSP40.0>


char MST_Data =0;//接收数据的变量
char SLV_Addr = 0x90;//地址为0x48<1表示R/W
int I2C_State =0;//状态变量

int main(void)
{
WDTCTL = WDTPW + WDTHOLD;//停止看门狗
,如果(CALC1_1MHz=0x1FF)校准

时清除 //不加载,捕获CPU!
!}

DCOCTL = 0;//选择最低DCOx和MODx设置
BCSCTL1 = CALC1_1MHz;//设置DCO
DCOCTL = CALDCO_1MHz;

P1OUT = 0xC0;// WFP 1.6 1.6 1.7 和WFP 1.7
P1REN |= 0xC0;// MODCO DCOCTL = CALDCO_1MHz;P1OUT = 0xC0;//不
使用的输出P1DIR P1FF
= 0


USICTL0 = USIPE6+USIPE7+USISWRST;// Port & USI mode setup
USICL1 = USII2C+USIIE+USISTTIIE;// Enable I2C mode & USI interrupts
USICKCTL = USICKPL;// Setup clock polity
USICNT |= USIIFIIFG;// Disable automatic clear control & USICST=
~USICST_USICST/
~


while (1)
{
LPM0;// CPU off,await USI interrupt
__no_operation();// used for IAR
}
//**********************************************************************************************


// USI中断服务例行程序
//******************************************************************************************************
#if defined(__TI_Compiler_version__)|| defined(__IAR_SYSTEMS _ICC__)
#pragma vector = USI_vector
__interrupt void USI_TXRX (void)
#Elif defined(__GNUC__)
void __attribute__(interrupt (USI_vector)) USI_TXRX (void)
#else
编译器不支持错误#else
#endif
{
IF (USICTL1 & USISTTIFG)//开始输入?
{
P1OUT |= 0x01;// LED开:序列启动
I2C_State =2;//在启动时输入第一个状态
}

开关(I2C_State){

案例0://空闲,不应获得此处
中断;

案例2:// RX地址
USICNT =(USICNT & 0xE0)+ 0x08; //位计数器= 8,RX地址
USICTR1 &=~USISTTIFG;//清除开始标志
USISRL = 0x00;
I2C_STATE = 4;//转到下一个状态:检查地址
中断;

案例4://处理地址并发送(N)确认
IF (USISRL & 0x01)//如果读取...
SLV_Addr+;//保存R/W位
USICTL0 |= USIOE;// SDA =输出
IF (USISRL == SLV_Addr)//地址匹配?
{
USISRL = 0x00;//发送确认
P1OUT &=~0x01;// LED关闭
I2C_State =8;//转到下一个状态:Rx数据
}
否则
{
USISRL = 0xFF;//发送nack
P1OUT |= 0x01;// LED打开:错误
I2C_State =6;//转到下一个状态: 准备下一个开始
}
USICNT |= 0x01;//位计数器=1,发送(N)Ack位
中断;

案例6://准备启动条件
USICTL0 &=~USIOE;// SDA =输入
SLV_Addr = 0x90;//重置从属地址
I2C_State =0;//重置状态机
中断;

案例8: //接收数据字节
USICL0 &=~USIOE;// SDA =输入
USICNT |= 0x08;//位计数器=8, RX DATA
I2C_STATE =10;//转到下一个状态:测试数据和(N)Ack
中断;

案例10://检查数据和TX (N)Ack
USICL0 |= USIOE; // SDA =输出
IF (USISRL == MST_Data)//如果数据有效...
{
USISRL = 0x00;//发送确认
MST_Data+;//增量主数据
P1OUT &=~0x01;// LED关闭
}
否则
{
USISRL = 0xFF;//发送nack
P1OUT |= 0x01;// LED打开:错误
}
USICNT |= 0x01;//位计数器=1,发送(N)I2C_Ack
//转到下一个状态:准备下一个开始
休息;
}

USICL1 &=~USIIFG;//清除待处理标志
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    刘秋虎:
    您的示波器截图显示看起来正确的从属地址...
    您说的是进入接收地址,还是数据接收?
    屏幕截图似乎显示了看起来正确的从属地址。

    您如何连接到主机?

    是否可以在生成nack的行上设置断点,并在同一屏幕截图上显示您点击的断点以及MST_Data变量内容和USISR内容? 通过这种方式,我们可以找出数据不正确的地方,以及预期的情况和接收的情况。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 ,Cameron,

    感谢您的回复。 在执行启动命令后,要发送的第一个数据是从属地址和写入命令,主设备发送数据(0x48<1 + 0)。

    现在,断点显示地址匹配,但注册窗口显示USISRL等于0x21,这似乎不正确。  

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

    刘秋虎:

    通过传递IF语句,值应该是正确的。您看到的是不同的值,因为您是主控不会停止。 为了按状态查看USISRL数据,可以使用不同的变量并检查这些变量。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    要详细说明,USI没有与USCI相同的缓冲区。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    刘秋虎:
    我将关闭此线程,如果此线程未回答您的问题,请回复,它将重新打开。 如果没有,请单击Verify Answer (验证答案)以确认答案。