大家好、我已经在 MSP4305438A 中尝试了 I2C 的基本通信。
我使用的晶体为29.5MHz。
我的目标是达到 Adafruit MPRLS 压力传感器并获取压力数据。
在上一篇文章中、我最终可以将数据发送到传感器。 我使用示波器检查信号、它可以完美地显示 SCL/SDA。
我检查 了传感器的文档、它说如果我想读取数据、步骤是:(不确定我是否误解了这一点)
发送0x30、0xAA、0x00、0x00
2.发送0x31并从从从器件读取1个字节
3.发送0x31并从从从器件读取4个字节
如下图所示(此传感器的地址为0x18):
现在、我想首先读取状态字节以检查 I2CRead 函数是否正常工作。
但是、如果我尝试从传感器读取数据。 它在 I2CRead 函数中停止、无法读取任何内容。
最糟糕的是:调用 I2CRead 函数后、无法再通过 I2C 发送数据。
如果我想让我的器件再次工作、我必须将其复位(和调试器)并删除 I2CRead 函数。
以下是我的代码:
//写入命令
U8 TXData;
U8 TXByteCtr;
//读取数据
U8 RXData;
U8 * PRxData; //指向 RX 数据
U8 RXByteCtr 的指针;
volatile U8 RxBuffer[128]; //分配128字节的 RAM
int main (void)
{
int i;
// LED 控制
P3DIR |=(BIT2|BIT3|BIT6);
P3OUT |=(BIT3|BIT6);
P3REN |=(BIT2|BIT3|BIT6);
init_clock
();_EINT);
I2CInit();
while (1)
{
I2CWrite (0x30);
I2CWrite (0xAA);
I2CWrite (0x00);
I2CWrite (0x00);
I2CWrite (0x31);
U8测试= I2CRead ();
}
/
*********
函数:init_clock
用途:初始系统时钟
参数:无
返回值:无
/
void init_clock (void)
{
unsigned int i;
WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器
P5SEL |= 0x0C;//端口选择 XT2
UCSCTL6 &=~XT2OFF;//即使未使用
也可以
启用 XT2 #ifdef crystal_295 CLR6 |= 0xT2OFF
;//如果未使用则启用 // FLLref = REFO
UCSCTL4 |= SELA_XT2CLK;//从 XT2-16M
UCSCTL4中选择源|= IVA_5 + SELM_5;// SMCLK=MCLK=XT2-16M
_NOP ();
#ifdef CRYS_OSCTL295 |
= DIVA_5 + SEL_;// XFFT2+
D_+ DCODx
~+ DFFD_+ Dx + DFFDx + Dx + T2M_+ T2M_+ DFFT2M_+ DFFDx + T2M_+ DFFDCO+ Dx + DFFDx + Dx + T2M_+ DFFT2M_+ DFFDCO+ Dx + DFFDx + Dx + DFFT2M_+ D
~ //清除
(i=0;i<0xFFFF;i++)的故障标志;// OSC 稳定的延迟
} while (SFRIFG1&OFIFG);//测试振荡器故障标志
}
void I2CInit()
{
P3SEL |= BIT7; //将 I2C 引脚分配给 USCI_B0
P5SEL |= BIT4;
UCB1CTL1 |= UCSWRST; //启用 SW 复位
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C 主设备,同步模式
UCB1CTL1 = UCSSEL_SMCLK + UCSWRST; //使用 SMCLK、保持软件复位
UCB1BR0 = 12; // fSCL = SMCLK/12 =~100kHz
UCB1BR1 = 0;
UCB1I2CSA = 0x18; //从器件地址为048h
UCB1CTL1 &=~UCSWRST; //清除 SW 复位,恢复操作
UCB1IE |= UCTXIE;
}//-----------
// USCIAB0_ISR 的结构使其可用于通过
预加载带有字节计数的 TXByteCtr 来发送任何//字节数。
///----------------------------------
#pragma vector = USCI_B1_Vector
__INTERRUPT void USCI_B1_ISR (void)
{
switch (_even_in_range (UCB1IV、12))
{
case 0:break; //向量0:无中断
情况2:中断; //向量2:ALIFG
情况4:中断; //向量4:NACKIFG
情况6:中断; //向量6:STTIFG
情况8:中断; //向量8:STPIFG
情况10: //向量10:RXIFG
RXData = UCB1RXBUF; //获取 RX 数据
_BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//退出活动 CPU
中断;
情况12: //向量12:TXIFG
IF (TXByteCtr) //检查 TX 字节计数器
{
UCB1TXBUF = TXData; //加载 TX 缓冲区
TXByteCtr --; //减量 TX 字节计数
器}
其他
{
UCB1CTL1 |= UCTXSTP; // I2C 停止条件
UCB1IFG &=~UCTXIFG; //清除 USCI_B0 TX int 标志
_BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//退出 LPM0
}
中断;
默认值:中断;
}
/*********
函数:I2CWrite
Purpose:Write 1 byte via I2C
parameter:unsigned char
return value:none
/
void I2CWrite (U8 cmd)
{
TXByteCtr = 1; //加载 TX 字节计数器
TXData = cmd;
UCB1IE &=~UCRXIE; //启用 TX 中断
UCB1IE |= UCTXIE; //启用 TX 中断
while (UCB1CTL1 & UCTXSTP); //确保发送了停止条件
UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX、启动条件
_bis_SR_register (LPM0_bits + GIE); //输入带中断的 LPM0
__no_operation(); //保持在 LPM0中直到所有数据
//是 TX
//增加数据字节
}
/*********
函数:I2CRead
用途:通过 I2C
参数写入1个字节:无符号字符
返回值:无
/
U8 I2CRead ()
{
UCB1IE &=~UCTXIE; //启用 TX 中断
UCB1IE |= UCRXIE; //启用 TX 中断
while (UCB1CTL1 & UCTXSTP); //确保发送了停止条件
UCB1CTL1 |= UCTXSTT; // I2C 启动条件
while (UCB1CTL1 & UCTXSTT); //起始条件是否已发送?
UCB1CTL1 |= UCTXSTP; // I2C 停止条件
_bis_SR_register (LPM0_bits + GIE); //输入 LPM0,启用中断
__no_operation(); //用于调试器
返回 RXData
;}
我不确定我的代码发生了什么情况。
是否有人可以帮助我解决此问题?
非常感谢您的参与。
Michelle



