TI论坛
直播中

王凤兰

7年用户 180经验值
私信 关注
[问答]

为什么LM3S9B92 I2C作主机访问其他芯片能读但不能写?

先贴上程序
void SkI2cInit (void)
[
// The I2C0 peripheral must be enabled before use.
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
GPIOPinConfigure(GPIO_PB2_I2C0SCL);
GPIOPinConfigure(GPIO_PB3_I2C0SDA);
// Select the I2C function for these pins. This function will also
// configure the GPIO pins pins for I2C operation, setting them to
// open-drain operation with weak pull-ups. Consult the data sheet
// to see which functions are allocated per pin.
ROM_GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);
// Enable and initialize the I2C0 master module. Use the system clock for
// the I2C0 module. The last parameter sets the I2C data transfer rate.
// If false the data rate is set to 100kbps and if true the data rate will
// be set to 400kbps. For this example we will use a data rate of 100kbps.
ROM_I2CMasterInitExpClk(I2C0_MASTER_BASE, ROM_SysCtlClockGet(), false);
]
void I2cWriteByte(unsigned char deviceID,unsigned char offset,unsigned value)
[
ROM_I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, deviceID, false);
ROM_I2CMasterDataPut(I2C0_MASTER_BASE, offset);
ROM_I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);
while(ROM_I2CMasterBusy(I2C0_MASTER_BASE))
[
]


ROM_I2CMasterDataPut(I2C0_MASTER_BASE, value);
ROM_I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);
while(ROM_I2CMasterBusy(I2C0_MASTER_BASE))
[
]
]
unsigned char I2cReadByte(unsigned char deviceID,unsigned char offset)
[
unsigned char value;
ROM_I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, deviceID, false);
//This function will set the address that the I2C Master will place on the bus when initiating a
//transaction. When the bReceive parameter is set to true, the address will indicate that the
//I2C Master is initiating a read from the slave; otherwise the address will indicate that the I2C
//Master is initiating a write to the slave.
ROM_I2CMasterDataPut(I2C0_MASTER_BASE, offset);//Transmits a byte from the I2C Master
ROM_I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);//Controls the state of the I2C Master module.
while(ROM_I2CMasterBusy(I2C0_MASTER_BASE))//Indicates whether or not the I2C Master is not-busy.
[
]


ROM_I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, deviceID, true);
ROM_I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
while(ROM_I2CMasterBusy(I2C0_MASTER_BASE))
[
]
value=ROM_I2CMasterDataGet(I2C0_MASTER_BASE);//Receives a byte that has been sent to the I2C Master.
return (value);
]
//*****************************************************************************
//
// Print "Hello world!" to the UART on the Stellaris evaluation board.
//
//*****************************************************************************
int
main(void)
[
unsigned char buffer=0;
//
// Set the clocking to run directly from the crystal.
//
ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);
//
// Initialize the UART.
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioInit(0);

SkI2cInit();

// Hello!
//
UARTprintf("33[2JHello World!n");

while(1)
[
//I2cWriteByte(0x64>>1,0x08,0x23);
buffer=I2cReadByte(0x64>>1,0x08);
UARTprintf("Received:%02xn",buffer);
]
]
以下是此芯片的I2C时序

现在我单独调用I2cReadByte();通过串口打印UARTprintf()能读到该芯片的ID寄存器以及其他默认不为0的寄存器的值;
但是我先用I2cWriteByte();写某个寄存器,再用I2cReadByte();读出这个寄存器的值发现读不到这个寄存器的值,很奇怪,请大家帮我分析分析
另外Stellaris® Peripheral Driver Library USER’S GUIDE 文档中 “I2CMasterControl()” 此函数的用法大家有详细说明吗?以下命令:
I2C_MASTER_CMD_SINGLE_SEND
I2C_MASTER_CMD_SINGLE_RECEIVE
I2C_MASTER_CMD_BURST_SEND_START
I2C_MASTER_CMD_BURST_SEND_CONT
I2C_MASTER_CMD_BURST_SEND_FINISH
I2C_MASTER_CMD_BURST_SEND_ERROR_STOP
I2C_MASTER_CMD_BURST_RECEIVE_START
I2C_MASTER_CMD_BURST_RECEIVE_CONT
I2C_MASTER_CMD_BURST_RECEIVE_FINISH
I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP
I2C_MASTER_CMD_QUICK_COMMAND
I2C_MASTER_CMD_HS_MASTER_CODE_SEND
都是怎么用的?
非常感谢!

回帖(4)

杨红

2019-9-3 13:22:20
楼主,
   I2C从设备的寄存器是可读的吧。 我觉得可能还是因为没有按照从设备的I2C寄存的读取规范。至于楼主列的那些命令的含义,楼主可以参考stellarisware里面的driverlib中的源代码,这几个命令其实就是代表着往寄存器I2CMCS中写入的值, 楼主可以参考下面的值,在datasheet的表15-5(Write Field Decoding for I2CMCS[3:0] Field)中查找相应值的含义。
#define I2C_MASTER_CMD_SINGLE_SEND
0x00000007
#define I2C_MASTER_CMD_SINGLE_RECEIVE
0x00000007
#define I2C_MASTER_CMD_BURST_SEND_START
0x00000003
#define I2C_MASTER_CMD_BURST_SEND_CONT
0x00000001
#define I2C_MASTER_CMD_BURST_SEND_FINISH
0x00000005
#define I2C_MASTER_CMD_BURST_SEND_STOP
0x00000004
#define I2C_MASTER_CMD_BURST_SEND_ERROR_STOP
0x00000004
#define I2C_MASTER_CMD_BURST_RECEIVE_START
0x0000000b
#define I2C_MASTER_CMD_BURST_RECEIVE_CONT
0x00000009
#define I2C_MASTER_CMD_BURST_RECEIVE_FINISH
0x00000005
#define I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP
0x00000004
#define I2C_MASTER_CMD_QUICK_COMMAND
0x00000027
#define I2C_MASTER_CMD_HS_MASTER_CODE_SEND
0x00000011
举报

王凤兰

2019-9-3 13:39:27
引用: sunguodong 发表于 2019-9-3 13:22
楼主,
   I2C从设备的寄存器是可读的吧。 我觉得可能还是因为没有按照从设备的I2C寄存的读取规范。至于楼主列的那些命令的含义,楼主可以参考stellarisware里面的driverlib中的源代码,这几个命令其实就是代表着往寄存器I2CMCS中写入的值, 楼主可以参考下面的值,在datasheet的表15-5(Write Field Decoding for I2CMCS ...

寄存器是可读写的,而且I2C的读写时序(帖子中已经贴出来了)也是对的。我在TI源代码中找找看相关例子
举报

杨红

2019-9-3 13:54:45
引用: zcy615 发表于 2019-9-3 13:39
寄存器是可读写的,而且I2C的读写时序(帖子中已经贴出来了)也是对的。我在TI源代码中找找看相关例子

如果楼主对时序理解正确,我觉得就是几个命令字使用的问题了,建议楼主研究一下命令字的含义,我列出几个楼主可能可以用到的,然后按照时序图应该就可以了:
             I2C_MASTER_CMD_SINGLE_SEND:    start, data和stop相都有的
              I2C_MASTER_CMD_SINGLE_RECEIVE :start, data和stop相都有的
              I2C_MASTER_CMD_BURST_SEND_START :有start和data相,没有stop相
              I2C_MASTER_CMD_BURST_SEND_CONT:只有data相,  
              I2C_MASTER_CMD_BURST_SEND_FINISH :有data相和stop相,没有start相
              I2C_MASTER_CMD_BURST_SEND_STOP :只有stop相
I2C_MASTER_CMD_BURST_RECEIVE_START, I2C_MASTER_CMD_BURST_RECEIVE_CONT,I2C_MASTER_CMD_BURST_RECEIVE_FINISH
,I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP可以参考上面
举报

王凤兰

2019-9-3 14:11:56
引用: sunguodong 发表于 2019-9-3 13:54
如果楼主对时序理解正确,我觉得就是几个命令字使用的问题了,建议楼主研究一下命令字的含义,我列出几个楼主可能可以用到的,然后按照时序图应该就可以了:
             I2C_MASTER_CMD_SINGLE_SEND:    start, data和stop相都有的
              I2C_MASTER_CMD_SINGLE_RECEIVE :start, data和stop ...

问题已经解决,谢谢
举报

更多回帖

发帖
×
20
完善资料,
赚取积分