这几天拿到了stm32f3discovery,拿到手的第一件事就是测试了硬件i2c,使用stm32cube生成库,测试对象为AD5934与ADG715。经过两天的调试,完美调通。中间也碰到了些问题。
1、一开始用的I2C1,一仿真就会出现死机的情况。
由于I2C1与swd接口重合,所以调用HAL_I2C_Init()函数后就死机,改成I2C2后问题解决。
2、无法访问指定地址的设备
库函数中的入口地址并不是7bit地址,需要输入8bit。我的设备地址为13,始终无法访问设备,改为26后解决。
3、可以读写单个地址的数据,但是不能多字节读写。
(1)、对于多字节写, 库函数中的
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
其中
MemAddSize表示地址的位数,0表示7bit地址,1表示10bit地址。我误认为这个写的字节数,所以导致在写多字节的时候出错。
(2)、对于多字节读,由于AD5934的读操作与库函数的读操作有些出入,所以导致一直读错误。在库函数中写完读的内存地址就开始读,而AD5934中写完block read后接着还要再写一个number bytes read然后才开始读。所以需要对库函数进行修改,新增一个函数,以适合AD5934的block read.
stm32f3的i2c有三种模式:Reload、AutoEnd、SoftEnd模式。
i2c每发送完一个字节,就会产生TXIS标志,当发送完最后一个字节时:
对于Reload模式,当字节大于255字节时,必须使用此模式,此模式下发送结束后,会产生tcr标志。
对于AutoEnd模式,发送后最后一个字节时,会自动产生STOP。
对于SoftEnd模式,发送完最后一个字节时,会产生tc标志,对于发送过程中需要Restart的需要使用此模式。
对于AD5934的读操作,可以事先工作在SoftEnd模式,发送完block read与number bytes read字节后,再转入AutoEnd模式进行Restart,读取完指定的字节后自动产生STOP。操作流程如下:
HAL_StatusTypeDef
HAL_I2C_Mem_Read_AD5934_Block
(
I2C_HandleTypeDef
*
hi2c
,
uint16_t
DevAddress
,
uint16_t
MemAddress
,
uint16_t
MemAddSize
,
uint8_t
*
pData
,
uint16_t
Size
,
uint32_t
Timeout
)
{
uint32_t Sizetmp = 0 ;
/* Check the parameters http://tiyubisai.com/video_news/news_135585.html */
assert_param ( IS_I2C_MEMADD_SIZE ( MemAddSize ));
if ( hi2c -> State == HAL_I2C_STATE_READY )
{
if (( pData == NULL ) || ( Size == 0 ))
{
return HAL_ERROR ;
}
if ( __HAL_I2C_GET_FLAG ( hi2c , I2C_FLAG_BUSY ) == SET )
{
{
uint32_t Sizetmp = 0 ;
/* Check the parameters http://tiyubisai.com/video_news/news_135585.html */
assert_param ( IS_I2C_MEMADD_SIZE ( MemAddSize ));
if ( hi2c -> State == HAL_I2C_STATE_READY )
{
if (( pData == NULL ) || ( Size == 0 ))
{
return HAL_ERROR ;
}
if ( __HAL_I2C_GET_FLAG ( hi2c , I2C_FLAG_BUSY ) == SET )
{