请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
部件号: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;//清除待处理标志
}



