int8_t I2C_write(uint8_t addr, uint8_t reg_addr, const uint8_t* data, uint8_t len) // packet function% H# A, k, y; a {5 L+ ^, b3 D3 H; R( l+ z8 t HAL_StatusTypeDef status =HAL_OK; uint16_t deviceWriteAddr = (addr << 1); //7 bit write address shall be pre-processed- G( g5 o7 b* M status = HAL_I2C_Mem_Write(&hi2c1,deviceWriteAddr,(uint16_t)reg_addr,1,(uint8_t*)data,(uint16_t)len,I2C_READ_TIMEOUT);# G+ l. o2 l1 h if (HAL_OK != status) {- h6 @/ f* w9 D printf("I2C Write Fail:%d\n\r",status); 9 `# a+ I1 ?. Y$ t7 B& T3 { return status; }9 u/ H$ a. [2 t) R6 M! c return HAL_OK;, }) }( a$ h6 q; \5 V4 O: J } 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; uint16_t deviceWriteAddr = addr << 1; //7 bit write address shall be pre-processed uint16_t deviceReadAddr = (addr << 1)|0x01; //7 bit read address shall be pre-processed uint8_t regAddr = reg_addr;! z0 R) Z& K: V8 S7 w. Z status = HAL_I2C_Master_Transmit(&hi2c1,deviceWriteAddr,®Addr,1,I2C_READ_TIMEOUT); 2 B, S% p% w* d6 L% [5 m - u! q- K; {- ?6 \, h$ q if (HAL_OK != status) {; o2 j( G7 I& F2 x _% J printf("I2C readreg Fail:%d\n\r",status); return status;8 }+ U& g+ K# u$ q } + w B! l& ]3 h* j, i : h3 H. w4 T$ _ [. \; }- h status = HAL_I2C_Master_Receive(&hi2c1,deviceReadAddr,(uint8_t*)data,(uint16_t)len,I2C_READ_TIMEOUT); // if (HAL_OK != status)1 k9 f+ I; ~0 D# f% B" s" w {! u* w, V; S: T$ x8 m printf("I2C Read1 Fail:%d\n\r",status);+ b" `! C0 i1 E2 I return status; }9 {& a ]# u Q* Z6 f2 q return HAL_OK;, R+ R7 X o I! N } 写是用HAL_I2C_Mem_Write() 重新打包;% m$ M3 l* q5 |! Y% j* m 读操作原本要用HAL_I2C_Mem_Read,发现多字节request时,返回 I2C error. 如上改过后,单字节,多字节 读写稳定。 HAL_I2C_Mem_Write/HAL_I2C_Mem_Read 都是cubeMX 工具生成的HAL库。* F* u2 S/ @% R, C 我是在STM32L4系列使用的。 我参考的I2C 协议参考:http://www.cnblogs.com/aaronLinux/p/6218660.html9 K- J, @6 W* j7 S1 G: S |