我尝试通过 I2C 读取霍尔效应传感器。 我的代码基于 driverlib 示例 i2c_ex5_master_slave_interrupt.c、示例2。
我可以在 Saleae 逻辑分析仪上看到写入是正确的。 但是、当我尝试读取时、传感器地址会正确放置在总线上、但寄存器地址不是。 它保持高电平、同时时钟脉冲。

以下代码生成此序列:
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "i2cLib_FIFO_master_slave_interrupt.h"
//
// Defines
//
#define I2CA_SENSORADDRESS 0x35
#define I2CA_ADDRESS 0x30
#define I2CB_ADDRESS 0x40
//
// Globals
//
uint16_t status = 0;
struct I2CHandle I2CA;
struct I2CHandle I2CB;
//
// Function Prototypes
//
__interrupt void i2cAISR(void);
__interrupt void i2cAFIFOISR(void);
__interrupt void i2cBISR(void);
__interrupt void i2cBFIFOISR(void);
uint16_t AvailableI2C_slaves[MAX_I2C_IN_NETWORK];
uint16_t I2CA_TXdata[MAX_BUFFER_SIZE];
uint16_t I2CB_TXdata[MAX_BUFFER_SIZE];
uint16_t I2CA_RXdata[MAX_BUFFER_SIZE];
uint16_t I2CB_RXdata[MAX_BUFFER_SIZE];
uint32_t I2CA_ControlAddr;
uint32_t I2CB_ControlAddr;
uint16_t status;
//
// Main
//
void i2c_test(void)
{
//
// Board initialization
//
I2C_GPIO_init();
//
// Initialize PIE and clear PIE registers. Disables CPU interrupts.
//
Interrupt_initModule();
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
//
Interrupt_initVectorTable();
I2Cinit();
// Board_init();
I2C_setOwnSlaveAddress(I2CA_BASE, I2CA_ADDRESS);
I2C_setOwnSlaveAddress(I2CB_BASE, I2CB_ADDRESS);
//I2Cs connected to I2CA will be found in AvailableI2C_slaves buffer
//after you run I2CBusScan function.
//When you run I2C BusScan you need to disable I2C interrupts and clear
//the flag set during I2CBusScan
// uint16_t i;
//
// for(i=0;i<MAX_I2C_IN_NETWORK;i++)
// {
// AvailableI2C_slaves[i] = 0;
// }
//
// I2C_disableInterrupt(I2CA_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
// I2C_disableInterrupt(I2CB_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
//
// uint16_t *pAvailableI2C_slaves = AvailableI2C_slaves;
// status = I2CBusScan(I2CA_BASE, pAvailableI2C_slaves);
//
// I2C_clearStatus(I2CA_BASE,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
// I2C_clearStatus(I2CB_BASE,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
//
// ESTOP0;
// I2C_disableInterrupt(I2CA_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
// I2C_disableInterrupt(I2CB_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
//
// status = I2CBusScan(I2CB_BASE, pAvailableI2C_slaves);
//
// I2C_clearStatus(I2CA_BASE,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
// I2C_clearStatus(I2CB_BASE,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
I2C_clearStatus(I2CA_BASE,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
I2C_clearStatus(I2CB_BASE,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
I2C_enableInterrupt(I2CA_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
I2C_enableInterrupt(I2CB_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
//
// Set I2C use, initializing it for FIFO mode
//
Interrupt_register(INT_I2CA, &i2cAISR);
Interrupt_enable(INT_I2CA);
Interrupt_register(INT_I2CB, &i2cBISR);
Interrupt_enable(INT_I2CB);
Interrupt_register(INT_I2CA_FIFO, &i2cAFIFOISR);
Interrupt_enable(INT_I2CA_FIFO);
Interrupt_register(INT_I2CB_FIFO, &i2cBFIFOISR);
Interrupt_enable(INT_I2CB_FIFO);
//
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
EINT;
ERTM;
uint16_t i;
for(i=0;i<MAX_BUFFER_SIZE;i++)
{
I2CA_TXdata[i] = 0;
I2CA_RXdata[i] = 0;
I2CB_TXdata[i] = 0;
I2CB_RXdata[i] = 0;
}
I2CA.currentHandlePtr = &I2CA;
I2CA.base = I2CA_BASE;
I2CA.SlaveAddr = I2CA_SENSORADDRESS;
I2CA.pControlAddr = &I2CA_ControlAddr;
I2CA.NumOfAddrBytes = 1;
I2CA.pTX_MsgBuffer = I2CA_TXdata;
I2CA.pRX_MsgBuffer = I2CA_RXdata;
I2CA.NumOfDataBytes = 64;
I2CB.currentHandlePtr = &I2CB;
I2CB.base = I2CB_BASE;
I2CB.SlaveAddr = I2CB_ADDRESS;
I2CB.NumOfAddrBytes = 4;
I2CB.pControlAddr = (uint32_t *)0;
I2CB.pTX_MsgBuffer = (uint16_t *)0;
I2CB.pRX_MsgBuffer = (uint16_t *)0;
I2CA.pTX_MsgBuffer[0] = 0x00;
I2CA.SlaveAddr = 0x00;
I2CA.NumOfDataBytes = 1;
I2CA_ControlAddr = 0x10;
status = I2C_MasterTransmitter(&I2CA);
// Wait for I2CA to be complete transmission of data
while(I2C_getStatus(I2CA.base) & I2C_STS_BUS_BUSY);
I2CA.SlaveAddr = I2CA_SENSORADDRESS;
// I2CA.pTX_MsgBuffer[0] = 0x10; // register address
I2CA.pTX_MsgBuffer[0] = 0b00000000; // set config register - all channels, full range, odd CP parity = 0x
I2CA.pTX_MsgBuffer[1] = 0b10001001; // MOD1 register: master controlled mode, one byte read command, enabled interrupt, no collision avoidance, odd FP parity
I2CA.NumOfDataBytes = 2;
status = I2C_MasterTransmitter(&I2CA);
// Wait for I2CA to be complete transmission of data
while(I2C_getStatus(I2CA.base) & I2C_STS_BUS_BUSY);
I2CA_ControlAddr = 0x00 | 0b00100000;
// I2CA.pTX_MsgBuffer[0] = 0b00100000; // trigger after I2c write frame is finished
I2CA.NumOfDataBytes = 0;
status = I2C_MasterTransmitter(&I2CA);
// Wait for I2CA to be complete transmission of data
while(I2C_getStatus(I2CA.base) & I2C_STS_BUS_BUSY);
SysCtl_delay(5000); //Adding delay for sensor conversion
I2CA.NumOfDataBytes = 0;
I2CA.pTX_MsgBuffer[0] = 0b00000000; // reset tx data
I2CA_ControlAddr = 0b00000000;
status = I2C_MasterReceiver(&I2CA);
// Wait for I2CA to be complete transmission of data
while(I2C_getStatus(I2CA.base) & I2C_STS_BUS_BUSY);
ESTOP0;
}
我必须更改 I2C_MasterReceiver ()代码(创建和调用 I2C_TransmitSlaveAddress_ControlBytes_MasterReadBit()方法,该方法设置 I2C_MASTER_Receive_mode 而不是 I2C_MASTER_SEND_MODE)以将读取位发送为高电平,因为 WRITE 位已硬编码,这确实起作用。
我在总线上需要0x0 + ACK、但我得到了 OxFF + NACK。 读数应如下所示:

