工具/软件:TI-RTOS
尊敬的团队:
我有两个任务、一个是 I2C 事务、另一个是 SPI 事务。 当我禁用 SPI 任务 I2C 任务顺利运行时、事务 从传感器读取数据。 即使我启用 SPI 任务, I2C 任务也能正常工作。 但是、当我将 MISO 和 MOSI 线路连接到微控制器时。 I2C 事务将发生错误的 I2C 传输。
简写:当我将 MISO 和 MOSI 线路连接到微控制器并启用 SPI 任务时。 执行 I2C 任务、从而生成 system_abort。
请提供您宝贵的建议、说明我在连接中出错的地方。
以下是每个模块的代码片段:
I2C 引脚配置:
GPIOPinTypeGPIOInput (GPIO_PORTB_BASE、GPIO_PIN_3); GPIOPinTypeGPIOOutput (GPIO_PORTB_BASE、GPIO_PIN_2); while (GPIOPinRead (GPIO_PORTB_BASE、GPIO_PIN_3)!= GPIO_PIN_3) { GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、0); GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、GPIO_PIN_2); } //为 PB2配置 GPIO 引脚多路复用器- I2C0SCL GPIOPinConfigure (GPIO_PB2_I2C0SCL); GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2); //为 PB3配置 GPIO 引脚多路复用器- I2C0SDA GPIOPinConfigure (GPIO_PB3_I2C0SDA); GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3);
I2C 通道开口:
// I2C 通道0打开
I2C_Params_init (&signal.i2c0Params);
signal.i2c0Params.bitrate = I2C_100kHz;
signal.i2c0 = I2C_open (I2C_IMU_left_dagonals、&signal.i2c0Params);
if (signal.i2c0 ==空)
{
System_abort ("初始化 I2C 通道时出错0\n");
}
其他
{
System_printf ("I2C 通道0已初始化!\n");
}
#define I2C_IMU_left_diagonals I2C0_IMU_LEFT_DIAONals
CONST I2CTIVA_HWAttrs i2cTivaHWAttrs[I2CCOUNT ={ { baseAddr = I2C0_BASE、 .intNum = INT_I2C0、 .intPriority =(~0) }、 { baseAddr = I2C1_base、 .intNum = INT_I2C1、 .intPriority =(~0) } }; const I2C_Config I2C_config[]={ { fxnTablePtr =&I2CTiva_fxnTable、 .object =&i2cTivaObjects[0]、 hwAttrs =&i2cTivaHWAttrs[0] }、 { fxnTablePtr =&I2CTiva_fxnTable、 .object =&i2cTivaObjects[1]、 hwAttrs =&i2cTivaHWAttrs[1] }、 {NULL、NULL、NULL} };
WriteRegister 代码:
void csupport:::i2c_writeRegister (I2C_Handle handle、unsigned char slaveAddr、uint16_t regAddr、uint32_t value、I2C_transfer_type transferType)
{
I2C_Handle i2cChannel1;
I2C_Params currI2cParams;
uint8_t txBuffer[4];
I2C_Transaction i2c 交易;
i2cTransaction.slaveAddress = slaveAddr;
i2cTransaction.writeBuf = txBuffer;
开关(传输类型)
{
案例 IMU_TRANSACTION:
//写入8位状态寄存器
i2cTransaction.writeCount = 2;
i2cTransaction.ReadCount = 0;
txBuffer[0]= regAddr & 0xFF;//lb Addr
TxBuffer[1]=值和0xFF;
中断;
案例 CURRENT_TRANSACTION:
i2cTransaction.writeCount = 3;
i2cTransaction.ReadCount = 0;
txBuffer[0]= regAddr & 0xFF;// 8位地址
txBuffer[1]=值>> 8;// HB 地址
txBuffer[2]=值和0xFF;// lb Addr
中断;
默认值:
//写入16位状态寄存器
i2cTransaction.writeCount = 4;
i2cTransaction.ReadCount = 0;
txBuffer[0]=(regAddr >> 8)& 0xFF;//HB Addr
txBuffer[1]= regAddr & 0xFF;//lb Addr
TxBuffer[2]=值& 0xFF;
txBuffer[3]=(值>> 8)& 0xFF;
中断;
}
if (!I2C_transfer (handle、&i2cTransaction)){
/*GPIO_write (Board_LED_RED、Board_LED_ON);*/
system_abort (" I2C 传输错误!");
}
}
读取寄存器:
/*
此函数用于8位和16位寄存器的 I2C 事务中的读取操作
*需要提及传输类型
* IMU_事务 - 8位
* CURRENT_TRANSACTION - 16位
*/
void csupport::i2c_readRegister (I2C_Handle handle、unsigned char slaveAddr、
uint8_t regAddr、uint16_t *数据、size_t length、
I2C_TRANSFER_TYPE TRANSAGEType)
{
uint8_t txBuffer[2];
I2C_Transaction i2c 交易;
i2cTransaction.slaveAddress = slaveAddr;
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.readBuf =数据;
i2cTransaction.ReadCount =长度;
开关(传输类型)
{
案例 IMU_TRANSACTION:
//写入8位状态寄存器
i2cTransaction.writeCount = 1;
txBuffer[0]= regAddr & 0xFF;//lb Addr
中断;
案例 CURRENT_TRANSACTION:
i2cTransaction.writeCount = 1;
txBuffer[0]= regAddr & 0xFF;// 8位地址
中断;
默认值:// 16位地址
i2cTransaction.writeCount = 2;
txBuffer[0]= regAddr >> 8;//HB Addr
txBuffer[1]= regAddr & 0xFF;//lb Addr
中断;
}
if (!I2C_transfer (handle、&i2cTransaction)){
GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_2、1);
system_abort (" I2C 传输错误!");
}
}
I2C 任务:
void get_IMU()
{
uint16_t pwr = 0x00;
c 支助支助;
support.i2c_writeRegister (signal.i2c0、MPU6050_I2C_address、0x6B、0x80、IMU_transaction);
support.i2c_readRegister (signal.i2c0、MPU6050_I2C_address、0x6B、&pwr、1、IMU_transaction);
操作
{
support.i2c_readRegister (signal.i2c0、MPU6050_I2C_address、0x6B、&pwr、1、IMU_transaction);
}
while ((pwr & 0x40)!= 0x40);
//使用具有 X 轴陀螺仪基准的 PLL
support.i2c_writeRegister (signal.i2c0、MPU6050_I2C_address、0x6B、0x01、IMU_transaction);
//启用 I2C 主机模式
support.i2c_writeRegister (signal.i2c0、MPU6050_I2C_address、0x6A、0x20、IMU_transaction);
//设置采样率分频器
support.i2c_writeRegister (signal.i2c0、MPU6050_I2C_address、0x19、0x13、IMU_transaction);
support.i2c_writeRegister (signal.i2c0、MPU6050_I2C_address、0x67、0x11、IMU_transaction);
while (1)
{
Semaphore_pend (IMUSem、BIOS_wait_forever);
support.i2c_readRegister (signal.i2c0、MPU6050_I2C_address、0x3B、(uint16_t *)&signal.imu.mpu6050、14、IMU_transaction);
signal.imu.acx = signal.imu.mpu6050.AccelXH << 8 | signal.imu.mpu6050.AccelXL;
signal.imu.acy = signal.imu.mpu6050.AccelYH << 8 | signal.imu.mpu6050.AccelYL;
signal.imu.acz = signal.imu.mpu6050.AccelZH << 8 | signal.imu.mpu6050.AccelZL;
signal.imu.temperature =(((signal.imu.mpu6050.TempH << 8)| signal.imu.mpu6050.Templ)/ 340)+36.5;
signal.imu.GyX = signal.imu.mpu6050.gyroXH << 8 | signal.imu.mpu6050.gyroXL;
signal.imu.gy= signal.imu.mpu6050.gyroyH << 8 | signal.imu.mpu6050.gyl;
SIGNAL .IMU.GyZ = SIGNAL .IMU.mpu6050.GyroZH << 8 | SIGNAL .IMU.mpu6050.GyroZL;
}
I2C_Close (signal.i2c0);//取消初始化 I2C
System_printf ("I2C 通道0关闭!\n"\});
system_flush();
}
SPI 引脚配置:
//为 PA2 - SSI0CLK 配置 GPIO 引脚多路复用器 GPIOPinConfigure (GPIO_PA2_SSI0CLK); GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_2); //为 PA3配置 GPIO 引脚多路复用器- SSI0FSS GPIOPinTypeGPIOOutput (GPIO_PORTD_base、GPIO_PIN_0);//将芯片选择线路拉低。 因为驱动器 CS 未提供所需的结果 GPIOPinConfigure (GPIO_PA3_SSI0FSS); GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_3); //为 PA4配置 GPIO 引脚多路复用器- SSI0RX GPIOPinConfigure (GPIO_PA4_SSI0RX); GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_4); //为 PA5配置 GPIO 引脚多路复用器- SSI0TX GPIOPinConfigure (GPIO_PA5_SSI0TX); GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5);
SPI 通道打开:
SPI_Params_init (&rightSpiParams);
rightSpi = SPI_open (right_oragon_SPI0、&rightSpiParams);
if (rightSpi =NULL) System_abort ("初始化右侧 SPI\n"时出错);
否则为 System_printf ("right SPI initialized\n");
#define SPI_right_diagonals 对角线_SPI0
CONST SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[SPICOUNT]={ { baseAddr = SSI0_BASE、 .intNum = INT_SSI0、 .intPriority =(~0)、 .scratchBufPtr =&spiTivaDMAscratchBuf[0]、 defaultTxBufValue = 0、 .rxChannelIndex = UDMA_CHANGE_SSI0RX、 txChannelIndex = UDMA_CHANGE_SSI0TX、 channelMappingFxn = uDMAChannelAssign、 .rxChannelMappingFxnArg = UDMA_CH10_SSI0RX、 txChannelMappingFxnArg = UDMA_CH11_SSI0TX }、 { baseAddr = SSI1_base、 .intNum = INT_SSI1、 .intPriority =(~0)、 .scratchBufPtr =&spiTivaDMAscratchBuf[1]、 defaultTxBufValue = 0、 .rxChannelIndex = UDMA_CHANGE_SSI1RX、 txChannelIndex = UDMA_CHANGE_SSI1TX、 channelMappingFxn = uDMAChannelAssign、 .rxChannelMappingFxnArg = UDMA_CH10_SSI1RX、 txChannelMappingFxnArg = UDMA_CH11_SSI1TX } }; const SPI_Config SPI_CONFIG[]={ { fxnTablePtr =&SPITIvaDMA_fxnTable、 .object =&spiTivaDMAObjects[0]、 hwAttrs =&spiTivaDMAHWAttrs[0] }、 { fxnTablePtr =&SPITIvaDMA_fxnTable、 .object =&spiTivaDMAObjects[1]、 hwAttrs =&spiTivaDMAHWAttrs[1] }、 {NULL、NULL、NULL}、 };
SPI 任务:
void get_height (){
//事务缓冲区
unsigned char rightRxBuffer[8]={0};
无符号字符 rightTxBuffer[]={0x00、0x01、0x87、0x00、0x00、0x00、0x00、0x00、0x00};//对于2个计数器- 24位
SPI_Handle rightSpi、leftSpi、frontSpi;
SPI_Params rightSpiParams、leftSpiParams、FrontSpiParams;
SPI_Transaction rightSpiTrans、leftSpiTrans、FrontSpiTrans;
bool rightConfigure、leftConfigure、frontConfigure;
bool 右前接收机、左前接收机、前接收机;
SPI_Params_init (&rightSpiParams);
rightSpi = SPI_open (right_oragon_SPI0、&rightSpiParams);
if (rightSpi =NULL) System_abort ("初始化右侧 SPI\n"时出错);
否则为 System_printf ("right SPI initialized\n");
/*初始化正确的 SPI 事务结构*/
rightSpiTrans.count = sizeof (rightTxBuffer);
rightSpiTrans.txBuf =(ptr) rightTxBuffer;
rightSpiTrans.rxBuf =空;
/*配置编码器*/
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_0、1);
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_0、0);
rightConfigure = SPI_transfer (rightSpi、&rightSpiTrans);
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_0、1);
if (rightConfigure) System_printf ("成功配置的正确 SPI\n");
否则 System_abort ("右侧 SPI 配置失败");
system_flush();
rightTxBuffer[0]={0x30};//在计数前重置计数器
rightTxBuffer[1]={0x03};
rightSpiTrans.rxBuf =(ptr) rightRxBuffer;
rightSpiTrans 计数= 2;
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_0、0);
rightConfigure = SPI_transfer (rightSpi、&rightSpiTrans);
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_0、1);
rightTxBuffer[0]={0x88};//读取计数器值
rightSpiTrans.rxBuf =(ptr) rightRxBuffer;
rightSpiTrans 计数= 7;
COUNTER_48位右编码器;
while (1){
Semaphore_pend (ENCSem、BIOS_WAIT_FOREVER);
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_0、0); //建议使用2:1 MUX 在不同 SPI 从器件之间进行芯片选择
rightReceive= SPI_transfer (rightSpi、&rightSpiTrans);
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_0、1);
if (!rightReceive) System_abort ("右 SPI receive failed:(");
signal.rightEncoder.counter1 =(rightRxBuffer[1])<<16|(rightRxBuffer[2]<<8)|(rightRxBuffer[3]);
signal.rightEncoder.counter0 =(rightRxBuffer[4])<<16|(rightRxBuffer[5])<8)|(rightRxBuffer[6]);
}