int8_t I2C_write(uint8_t addr, uint8_t reg_addr, const uint8_t* data, uint8_t len) // packet function& m* ^+ q! V+ w+ Y6 X% R+ [, k7 y {% j+ U# Q0 T/ K+ Y& _ HAL_StatusTypeDef status =HAL_OK; uint16_t deviceWriteAddr = (addr << 1); //7 bit write address shall be pre-processed! e0 W: x/ l" S) s status = HAL_I2C_Mem_Write(&hi2c1,deviceWriteAddr,(uint16_t)reg_addr,1,(uint8_t*)data,(uint16_t)len,I2C_READ_TIMEOUT);6 i$ M0 z; z$ T: w if (HAL_OK != status)" J' |0 E5 s. b; d {/ k' ^6 g" _0 e, b; B: z printf("I2C Write Fail:%d\n\r",status); return status; }; E/ e! G: u- q% E return HAL_OK;. ]7 X8 s" B ^7 L" T# m }& O0 d2 p1 X+ Y6 [0 K9 }% a" v6 O 7 D, d# k! c, K* g, Y- v# ^+ F6 x int8_t I2C_read(uint8_t addr, uint8_t reg_addr, const uint8_t* data, uint8_t len) //re packet function: w! u# E+ ], c {4 E Z- ]& {' q) M/ B5 y% s 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 5 l' w- v2 H/ k4 j uint8_t regAddr = reg_addr; ( _# K: T3 i% `' X- y) M8 x status = HAL_I2C_Master_Transmit(&hi2c1,deviceWriteAddr,®Addr,1,I2C_READ_TIMEOUT); $ _- Z' L, U) t9 M# P# K 0 U {4 V4 W, F, I, T if (HAL_OK != status) { printf("I2C readreg Fail:%d\n\r",status); return status;2 g1 e1 ]" p" {3 ^( |' n8 v } * [5 @( r! b1 F( {" h7 H3 l6 `1 T4 O status = HAL_I2C_Master_Receive(&hi2c1,deviceReadAddr,(uint8_t*)data,(uint16_t)len,I2C_READ_TIMEOUT); // $ Y/ R9 f& ^) F: f, f) A; g- X if (HAL_OK != status) {7 s9 [& [! r' | printf("I2C Read1 Fail:%d\n\r",status);4 M( n% H7 _# u5 V" v) g( @ ~8 w return status; } return HAL_OK; } o4 l7 Z1 i6 I: m* X 5 S# B+ S& Y2 S ?8 J 写是用HAL_I2C_Mem_Write() 重新打包; 读操作原本要用HAL_I2C_Mem_Read,发现多字节request时,返回 I2C error. 如上改过后,单字节,多字节 读写稳定。 HAL_I2C_Mem_Write/HAL_I2C_Mem_Read 都是cubeMX 工具生成的HAL库。 我是在STM32L4系列使用的。 我参考的I2C 协议参考:http://www.cnblogs.com/aaronLinux/p/6218660.html |