工具/软件:Code Composer Studio
MSP430FR2355
Code Composer Studio
版本:8.3.1.00004
从器件:MPU6050 (Accel / Gyro)模块
我可以顺利启动 MPU6050。
但是、当我开始数据收集(TX 和 RX 部分)时、它应该会看到
主器件:I2C 作为 TX
TX 地址+代码+重新启动或停止 (0x68 + 0x3B + S)
主器件:I2C 作为 RX
TX 地址、然后是 NACK。 (0x68 || 数据字节 || NACK)则主器件期望通过 NACK 进行确认以结束传输
这应该重复;
我得到的是
TX 地址+停止 (0x68 + S)
RX 地址|| 0x00 + 0x00 || NACK
逻辑分析仪中的以下示例
真的不知道为什么会发生这种情况、为什么主器件 MSP430FR2355仅发送地址而不是数据?
尝试在不同位置设置延迟、 尝试当前设置为/8的不同时钟速度 (尝试从/2到/20不幸运)
这是示波器跟踪黄色是数据线蓝色是 P3 BIT4 (我放置一个 P3位4以在中断例程中变为高电平和低电平、它在 I2C 协议的地址部分捕获此干扰
主设备
#include #include "stdint.h" /** * MPU-6050 I2C = 0x68 * **/ void I2C_BUSY (void); void 延迟(void); const unsigned int MPU_address = 0x68;// MPU-6050 i2c 地址 const unsigned int Accel_XOUT_H = 0x003B; const unsigned int Accel_L = 0x003C_int 执行;unsigned int Accel = 0x003C_int Accel;unsigned int Accel = 0x003c const unsigned int Accel_Zout_H = 0x003F; const unsigned int Accel_Zout_L = 0x0040; const unsigned int Gyro_XOUT_H = 0x0043; const unsigned int Gyro_XOUT_L = 0x0044; const unsigned int Gyro_Conout_H = 0x0045; const unsigned int Gyro_ZOUT_L = 0x0046;unsigned int Gyout_L = 0x0047;unsigned g_g_gyout_L unsigned int RXData = 0; unsigned int TXByteCtr = 0; unsigned int SlaveFlag = 0; unsigned int RXcnt = 0; volatile unsigned int stop = 0; volatile unsigned int read = 0; signed int TXData[]={0x6B、0x00、0x1A、0x04、0x1B、 0x00、0x1C、0x00}; unsigned int RX[4]; unsigned int RX1[0x0100]; unsigned int RX1cnt = 0; signed int x_acc = 0; signed int y_acc = 0; signed int z_acc = 0; signed int x_gyr = 0;signed int z_gyr = 0; unsigned int valid = 0; signed int acc_led = 0; int main (void) { WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器 P1SEL0 |= BIT2 | BIT3; // I2C 引脚 P5DIR |= BIT0 | BIT1 | BIT2 | BIT3 | BIT4;//步进驱动器0=DIR、1=步进、3-4-5步进值 P5OUT = 0x00; P3DIR = 0xFF; P3OUT = 0x00; //禁用 GPIO 上电默认高阻抗模式以激活 //先前配置的端口设置 PM5CTL0 &=~LOCKLPM5; //将 USCI_B0配置为 I2C 模式 UCB0CTLW0 |= UCSWRST; //软件复位被启用 UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC;// I2C 模式、主控模式、同步 UCB0CTLW1 |= UCASTP_0; //未生成自动停止 //到达 UCB0TBCNT 后 UCB0BRW = 0x0008; //波特率= SMCLK /8 ------ 32岁以上 UCB0TBCNT = 0x0000; //禁用字节 cntr UCB0I2CSA = MPU_ADDRESS; // MPU-6050的从器件地址 UCB0CTL1 &=~UCSWRST; UCB0IE |= UCRXIE | UCTXIE0 | UCNACKIE | UCTXSTP;// EN INT TX、RX、NACK __bis_SR_register (GIE); //启用中断 while (UCB0CTLW0 & UCTXSTP); //确保停止条件已发送 I2C_BUSY (); TX_CNTR = 0x00; TXByteCtr = 0x02; UCB0CTLW0 |= UCTR | UCTXSTT; // TX 0x6B 0x00 I2C_BUSY (); TXByteCtr = 0x02; UCB0CTLW0 |= UCTR | UCTXSTT; // TX 0x1A 0x00 I2C_BUSY (); TXByteCtr = 0x02; UCB0CTLW0 |= UCTR | UCTXSTT; // TX 0x1B 0x00 I2C_BUSY (); TXByteCtr = 0x02; UCB0CTLW0 |= UCTR | UCTXSTT; // TX 0x1C 0x00 I2C_BUSY (); // * MPU6050初始化完成 */ TX_CNTr = 0x0000; TXData[0]= 0x3B; TXData[1]= 0x3C; TXData[2]= 0x3D; TXData[3]= 0x3E; TXData[4]= 0x3F; TXData[5]= 0x40; TXData[6]= 0x00; TXData[7]= 0x00; RXcnt = 0x00; // RX 数据 //主|S|AD+W||RA||S|AD+R|||ack| //从设备 |ack||ack|||ack|Data|| while (UCB0CTLW0和 UCTXSTP); //确保发送了停止条件 I2C_BUSY(); while (1) { P3OUT = 0x00; TX_CNTr = 0x00; TXByteCtr = 0x01; // UCB0CTLW0 |= UCSWRST; //软件复位被启用 UCB0CTLW0 |= UCTR; // INTx 模式 UCB0CTLW1 |= UCASTP0; // UCB0TBCNT = 0x03;// TX 2字节 // UCB0CTLW0 &=~UCSWRST; //软件复位被启用 UCB0CTLW0 |= UCTXSTT; // I2C 启动条件 I2C_BUSY(); P3OUT |= BIT0; // UCB0CTLW0 |= UCSWRST; //软件复位被启用 UCB0CTLW0 &=~UCTR; //接收模式 UCB0CTLW1 |= UCASTP1; UCB0TBCNT = 0x01;// Rx 1字节 // UCB0CTLW0 &=~UCSWRST; //软件复位被启用 UCB0CTLW0 |= UCTXSTT; // I2C 启动条件 INTx 模式 I2C_BUSY(); while (read)_no_operation (); P3OUT |= BIT1; if (有效) { RX1[RX1cnt+]= x_ACC; if (RX1cnt > 0x00FF) RX1cnt = 0x0000; ACC_LED = x_ACC >>8; // P3OUT = ACC_LEed;//希望实时查看结果 if (acc_led > 128) { P5OUT |= BIT0; P5OUT |= BIT1; delay();//步进电机延迟脉冲太快 P5OUT &= BIT1; delay();//步进电机延迟脉冲太快 } 如果(z_gyr <-128)则为其他值 { P5OUT &=~BIT0; P5OUT |= BIT1; delay();//步进电机延迟脉冲太快 P5OUT &= BIT1; delay();//步进电机延迟脉冲太快 } P3OUT |= BIT2; } } void I2C_BUSY (void) { unsigned int wait; while (UCB0STATW 和 UCBBUSY) { for (Wait = 0xFFFF;wait = 0;wait--)_no_operation (); } } void delay (void) { unsigned int ***; for (STEPER_PULSE_DELAY = 0xFFFF;STEPER_PULSE_DELAY = 0;STEPER_PULSE_DELAY--)__NO_OPERATION (); } #pragma vector = USCI_B0_Vector __INTERRUPT void USCIB0_ISR (void) { volatile unsigned int I2C_int; I2C_int = UCB0IV; if (I2C_int =UCIV__UCTXIFG0)// TX 缓冲区为空 { IF (TXByteCtr) //检查 TX 字节计数器 { P3OUT |= BIT4; TXByteCtr --; UCB0TXBUF = TXData[TX_CNTR]; //加载 TX 缓冲区 TX_CNTR++; STOP = 0x01; //测量 TX 字节计数器 P3OUT &=~BIT4; } 其他 { STOP = 0x00; UCB0CTLW0 |= UCTXSTP; // I2C 停止条件 } } 否则、如果(I2C_int = UCIV_UCRXIFG0)// RX 数据存在 { UCB0CTLW0 |= UCTXSTP; RXData = UCB0RXBUF; RX[RXcnT]= RXData; RXcnt++; if (RXcnt > 0x0001) { RXcnt = 0; X_ACC = RX[1]|(RX[0]<<8); 有效= 0x0001; } 有效= 0x0001; 读取= 0x0000; P3OUT |= BIT5; } 否则、如果(I2C_int = UCIV_UCNACKIFG)//接收到 NACK { STOP = 0x00; 读取= 0x0000; UCB0CTLW0 |= UCTXSTP; // I2C 停止条件 } 否则,如果(I2C_int =UCIV_UCSTPIFG)//停止接收 { 停止= 0x00; } }