int8_t I2C_write(uint8_t addr, uint8_t reg_addr, const uint8_t* data, uint8_t len) // packet function { HAL_StatusTypeDef status =HAL_OK;1 V# y$ Y) A8 T5 E, H1 k9 u( ^ uint16_t deviceWriteAddr = (addr << 1); //7 bit write address shall be pre-processed status = HAL_I2C_Mem_Write(&hi2c1,deviceWriteAddr,(uint16_t)reg_addr,1,(uint8_t*)data,(uint16_t)len,I2C_READ_TIMEOUT);0 b, `) w# c2 Z4 v& a if (HAL_OK != status). _9 o! ]# \6 t { printf("I2C Write Fail:%d\n\r",status); return status;0 j3 P+ v. W9 F: V' q& M2 v4 u# S: A }( S" ]3 G+ V) o! b1 v0 i6 \: d& ] return HAL_OK; }7 A# g3 m/ m' H, F) [: N9 w) p & e9 E# ^' e( O int8_t I2C_read(uint8_t addr, uint8_t reg_addr, const uint8_t* data, uint8_t len) //re packet function { HAL_StatusTypeDef status =HAL_OK;# y/ C5 I3 E3 G8 _ _. Q, w uint16_t deviceWriteAddr = addr << 1; //7 bit write address shall be pre-processed. [# P' `+ r! |( n$ A uint16_t deviceReadAddr = (addr << 1)|0x01; //7 bit read address shall be pre-processed uint8_t regAddr = reg_addr; 4 j1 X3 ]6 p: b: y$ |2 \ status = HAL_I2C_Master_Transmit(&hi2c1,deviceWriteAddr,®Addr,1,I2C_READ_TIMEOUT); : O. k, }( c0 J3 J if (HAL_OK != status)+ E' K+ h6 j4 y$ ?7 f9 b. [, O {. ~; g h: c& A* {8 _& Y2 ^ printf("I2C readreg Fail:%d\n\r",status); Q) i6 z9 [+ H5 Q/ N4 { return status; } status = HAL_I2C_Master_Receive(&hi2c1,deviceReadAddr,(uint8_t*)data,(uint16_t)len,I2C_READ_TIMEOUT); // if (HAL_OK != status) { printf("I2C Read1 Fail:%d\n\r",status); return status; } return HAL_OK;. v) M/ c! Z* f# f6 z1 `( v( P } p1 U4 J! |# d! E' n: Y 写是用HAL_I2C_Mem_Write() 重新打包; 读操作原本要用HAL_I2C_Mem_Read,发现多字节request时,返回 I2C error.2 Z; k! q3 i" v- X5 ` 如上改过后,单字节,多字节 读写稳定。 HAL_I2C_Mem_Write/HAL_I2C_Mem_Read 都是cubeMX 工具生成的HAL库。 我是在STM32L4系列使用的。* g4 y" v; j+ {7 `( s 我参考的I2C 协议参考:http://www.cnblogs.com/aaronLinux/p/6218660.html |