int8_t I2C_write(uint8_t addr, uint8_t reg_addr, const uint8_t* data, uint8_t len) // packet function {& a S) Z# f. U. b' i HAL_StatusTypeDef status =HAL_OK;; f; b2 q2 R( l7 e$ d- T4 E- S6 s 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); if (HAL_OK != status) { printf("I2C Write Fail:%d\n\r",status); return status;' o% R% @' F9 Q2 l4 M& u } }' Y; N6 Q, n return HAL_OK; } ; [3 e( M0 `5 C, L6 Y int8_t I2C_read(uint8_t addr, uint8_t reg_addr, const uint8_t* data, uint8_t len) //re packet function- e: \9 b6 r. A: { {( ^7 b" C8 r! w% _ HAL_StatusTypeDef status =HAL_OK; uint16_t deviceWriteAddr = addr << 1; //7 bit write address shall be pre-processed% j. N/ |0 _& R) r uint16_t deviceReadAddr = (addr << 1)|0x01; //7 bit read address shall be pre-processed uint8_t regAddr = reg_addr; , S* C3 [3 y# J0 r, B- P status = HAL_I2C_Master_Transmit(&hi2c1,deviceWriteAddr,®Addr,1,I2C_READ_TIMEOUT); - n$ \/ z- n3 i# k# a. u% m if (HAL_OK != status)7 d3 y; ^5 X8 d1 [8 p+ B$ {* y { printf("I2C readreg Fail:%d\n\r",status);3 T6 Q6 x0 ~1 ~- b. e( g6 \ return status; } ~: c7 O1 f. g+ e( _ 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); m* V& u. O* i return status; } return HAL_OK; }$ h/ a. z E/ s8 N + j% P/ M1 h9 @4 J E5 } 写是用HAL_I2C_Mem_Write() 重新打包;, P8 w. w% J3 L: b6 x1 t. n% b 读操作原本要用HAL_I2C_Mem_Read,发现多字节request时,返回 I2C error. 如上改过后,单字节,多字节 读写稳定。) d9 z/ B6 m8 |# S$ l; k* x2 N3 _ HAL_I2C_Mem_Write/HAL_I2C_Mem_Read 都是cubeMX 工具生成的HAL库。 我是在STM32L4系列使用的。 我参考的I2C 协议参考:http://www.cnblogs.com/aaronLinux/p/6218660.html0 t/ c' }( R1 ^- I |