器件型号:MSP-EXP432P401R
工具/软件:Code Composer Studio
大家好、我正在使用 MSP432P401R Launchpad 连接 MPU9250 IMU、并且 I2C 实现存在一些问题。 我有一个用于 msp430g2553的 I2C 代码、它对我来说非常有用、因此我决定使用 msp432 driverlib 来移植此代码。
以下是 MSP430的写入、读取函数和 i2c 中断:
void CopyArray (uint8_t *源、uint8_t * dest、uint8_t count) { uint8_t copyIndex = 0; for (copyIndex = 0;copyIndex < count;copyIndex++) { dest[copyIndex]= source[copyIndex]; } } I2C_Mode MSP430_I2C_Master_ReadReg (uint8_t dev_addr、uint8_t reg_addr、uint8_t count、uint8_t * rec_buff) { /*初始化状态机*/ MasterMode = TX_REG_ADDRESS_MODE; TransmitRegAddr = reg_addr; RXByteCtr =计数; TXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /*初始化从地址和中断*/ UCB0I2CSA = DEV_addr; IFG2 &=~(UCB0TXIFG + UCB0RXIFG); //清除所有挂起的中断 IE2 &=~UCB0RXIE; //禁用 RX 中断 IE2 |= UCB0TXIE; //启用 TX 中断 UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX、启动条件 _bis_SR_register (CPUOFF + GIE); //输入带中断的 LPM0 //rec_buff =接收缓冲器; CopyArray (ReceiveBuffer、rec_buff、count); 返回 MasterMode; } I2C_Mode MSP430_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; //将寄存器数据复制到 TransmitBuffer CopyArray (reg_data、TransmitBuffer、count); TXByteCtr =计数; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /*初始化从地址和中断*/ UCB0I2CSA = DEV_addr; IFG2 &=~(UCB0TXIFG + UCB0RXIFG); //清除所有挂起的中断 IE2 &=~UCB0RXIE; //禁用 RX 中断 IE2 |= UCB0TXIE; //启用 TX 中断 UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX、启动条件 _bis_SR_register (CPUOFF + GIE); //输入带中断的 LPM0 返回主模式; } //********* //接收和传输数据的 I2C 中断********* // #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_ISR)#vector (void USCIA0TX_ISR)#UCIAB0TX_ISR (void))#defineer_COMPLETE!错误!#UICUICUICUICUICU #endif { if (IFG2 & UCB0RXIFG)} //接收数据中断 { //必须从 UCB0RXBUF 中读取 uint8_t Rx_val = UCB0RXBUF; IF (RXByteCtr) { ReceiveBuffer[ReceiveIndex++]= Rx_val; RXByteCtr --; } IF (RXByteCtr = 1) { UCB0CTL1 |= UCTXSTP; } 否则、如果(RXByteCtr = 0) { IE2 &=~UCB0RXIE; MasterMode = IDLE_MODE; _BIC_SR_REGISTER_ON_EXIT (CPUOFF); //退出 LPM0 } } 否则 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 --; } 其他 { //传输完成 UCB0CTL1 |= UCTXSTP; //发送停止条件 MasterMode = IDLE_MODE; IE2 &=~UCB0TXIE; //禁用 TX 中断 _BIC_SR_REGISTER_ON_EXIT (CPUOFF); //退出 LPM0 } 中断; 默认值: __no_operation(); 中断; } }
这里是 MSP432的相同函数
I2C_Mode I2C_Master_ReadReg (uint8_t dev_addr、uint8_t reg_addr、uint8_t count、uint8_t * rec_buff) { MasterMode = TX_REG_ADDRESS_MODE; TransmitRegAddr = reg_addr; RXByteCtr =计数; TXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; MAP_I2C_setSlaveAddress (EUSCI_B0_BASE、DEV_addr); ///map_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Transmit 模式); //map_I2C_enableModule (USCI_B0_BASE); MAP_I2C_clearInterruptFlag (EUSCI_B0_BASE、 EUSCI_B_I2C_Transmit INTERRUPT0 + EUSCI_B_I2C_Receive_INTERRUPT0); MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_INTERRUPT0); /*启用主机发送中断*/ MAP_I2C_enableInterrupt (EUSCI_B0_BASE、 EUSCI_B_I2C_Transmit INTERRUPT0); //MAP_Interrupt_enableInterrupt (INT_EUSCIB0); /*确保最后一个交易已完全发送*/ while (MAP_I2C_masterIsStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending _stop); /*发送寄存器以写入*/ MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE、TransmitRegAddr); CopyArray (ReceiveBuffer、rec_buff、count); 返回 MasterMode; } 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; //将寄存器数据复制到 TransmitBuffer CopyArray (reg_data、TransmitBuffer、count); TXByteCtr =计数; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; MAP_I2C_setSlaveAddress (EUSCI_B0_BASE、DEV_addr); MAP_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Transmit 模式); MAP_I2C_enableModule (EUSCI_B0_BASE); MAP_I2C_clearInterruptFlag (EUSCI_B0_BASE、 EUSCI_B_I2C_Transmit INTERRUPT0); /*启用主机发送中断*/ MAP_I2C_enableInterrupt (EUSCI_B0_BASE、 EUSCI_B_I2C_Transmit INTERRUPT0); MAP_Interrupt_enableInterrupt (INT_EUSCIB0); /*确保最后一个交易已完全发送*/ while (MAP_I2C_masterIsStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending _stop); /*发送寄存器以写入*/ MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE、TransmitRegAddr); 返回主模式; } /********* / void EUSCIB0_IRQHandler (void) { uint_fast16_t status; STATUS = MAP_I2C_getEnabledInterruptStatus (EUSCI_B0_BASE); IF (STATUS & EUSCI_B_I2C_NAK_INTERRUPT) { MAP_I2C_clearInterruptFlag (EUSCI_B0_BASE、EUSCI_B_I2C_NAK_INTERRUPT); } IF (STATUS & EUSCI_B_I2C_Transmit _INTERRUPT0) { 开关(MasterMode){ 案例 TX_REG_ADDRESS_MODE: IF (RXByteCtr) MasterMode = SWITCH_TO_RX_MODE;//需要立即开始接收 其他 MasterMode = TX_DATA_MODE; //继续传输缓冲区中的数据 中断; 案例切换至 RX_MODE: MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Transmit INTERRUPT0); MAP_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_mode); MAP_I2C_masterReceiveStart (EUSCI_B0_BASE); MAP_I2C_enableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_INTERRUPT0); //map_I2C_masterSendMultiByteStop (EUSCI_B0_BASE); //map_I2C_clearInterruptFlag (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_INTERRUPT0); MasterMode = RX_DATA_MODE;//状态是接收数据 //UCB0CTL1 |= UCTXSTT; //发送重复起始 IF (RXByteCtr = 1) { //必须发送停止,因为这是 N-1字节 while (MAP_I2C_masterIsStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending _stop); ///map_I2C_enableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_STOP_INTERRUPT); MAP_I2C_masterSendMultiByteStop (EUSCI_B0_BASE); } 中断; 案例 TX_DATA_MODE: if (TXByteCtr){ MAP_I2C_masterSendMultiByteNext (EUSCI_B0_BASE、TransmitBuffer[TransmitIndex++]); TXByteCtr --; } 其他 { //传输完成 MAP_I2C_masterSendMultiByteStop (EUSCI_B0_BASE); MasterMode = IDLE_MODE; MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Transmit INTERRUPT0); MAP_Interrupt_disableSlepOnIsrExit(); } 中断; } } /*将字节接收到接收缓冲区中。 如果我们已接收所有字节、 *发送停止条件*/ IF (STATUS & EUSCI_B_I2C_Receive_INTERRUPT0) { IF (RXByteCtr) { ReceiveBuffer[ReceiveIndex++]= MAP_I2C_ReceivmasterMultiByteNext (EUSCI_B0_BASE); RXByteCtr --; } IF (RXByteCtr = 1) { MAP_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE); } 否则、如果(RXByteCtr = 0) { //map_I2C_masterSendMultiByteStop (EUSCI_B0_BASE); MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_INTERRUPT0); MasterMode = IDLE_MODE; MAP_Interrupt_disableSlepOnIsrExit(); } } 否则、如果(STATUS & EUSCI_B_I2C_STOP_INTERRUPT) { MAP_Interrupt_disableSlepOnIsrExit(); MAP_I2C_DisableInterrupt (EUSCI_I2C_MODULE、EUSCI_B_I2C_STOP_INTERRUPT); } }
我不知道问题在 MSP432代码中的哪个位置、但我读取的值不正确、因为 IMU 的 Wow Am I 寄存器不会应答0x71默认值。 我可以写入和读取、但实际上我不知道
如果它运行良好。 希望我的代码可读。
此致、
Diana