##################################################### i2c.h ##################################################### #ifndef _I2C_H_ #define _I2C_H_ #include "stdbool.h" #include "stm32f4xx_hal.h" #define u8 uint8_t #define u16 uint16_t #define add_w 0x90 #define add_r 0x91 #define SDA_H GPIOB->BSRR=GPIO_PIN_8 #define SDA_L GPIOB->BSRR=(uint32_t)GPIO_PIN_8 << 16 #define SCL_H GPIOB->BSRR=GPIO_PIN_9 #define SCL_L GPIOB->BSRR=(uint32_t)GPIO_PIN_9 << 16 #define SDA_READ GPIOB->IDR& GPIO_PIN_8 #define SCL_READ GPIOB->IDR& GPIO_PIN_9 void writebyte(u8 sendbyte,u16 write_add,u8 device_add); bool readbyte(u8* pBuffer,u8 length,u16 read_add,u8 device_add); ####################################### i2c.c ###################################### #include "i2c.h" void i2c_delay() { u8 i = 100; while(i--); } bool i2c_start(void) { SDA_H; SCL_H; i2c_delay(); if(!SDA_READ)//test the sda != 0 return false; SDA_L; i2c_delay(); if(SDA_READ)//test the sda == 0 return false; SCL_L; i2c_delay(); return true; } void i2c_stop(void) { //scl == 0, and sda == 0 SCL_L; i2c_delay(); SDA_L; i2c_delay(); //scl = 1 , then sda = 1 SCL_H; i2c_delay(); SDA_H; i2c_delay(); } void i2c_ack(void) { SDA_H; i2c_delay(); SCL_H; i2c_delay(); SCL_L; i2c_delay(); SDA_L; i2c_delay(); SCL_H; i2c_delay(); } bool i2c_waitack(void) { SCL_L; i2c_delay(); SDA_H; i2c_delay(); SCL_H; i2c_delay(); if(SDA_READ) { SCL_L; return false; } SCL_L; return true; } void i2c_sendbyte(u8 send) { u8 i = 8; while(i--) { SCL_L; i2c_delay(); if(send&0x80) SDA_H; else SDA_L; send <<= 1; i2c_delay(); SCL_H; i2c_delay(); } SCL_L; } u8 receivebyte(void) { u8 i = 8; u8 receive = 0; SDA_H; while(i--) { receive<<=1; SCL_L; i2c_delay(); SCL_H; i2c_delay(); if(SDA_READ) { receive |= 0x01; } } SCL_L; return receive; } void writebyte(u8 sendbyte,u16 write_add,u8 device_add) { device_add = device_add | 0x00; i2c_start(); i2c_sendbyte(device_add); i2c_delay(); i2c_sendbyte(write_add); i2c_delay(); i2c_sendbyte(sendbyte); i2c_delay(); i2c_stop(); } bool readbyte(u8* pBuffer,u8 length,u16 read_add,u8 device_add) { device_add = device_add | 0x01; if(!i2c_start()) return false; i2c_sendbyte(device_add); i2c_delay(); i2c_sendbyte(read_add-1); i2c_delay(); i2c_sendbyte(*pBuffer); i2c_delay(); i2c_ack(); i2c_delay(); i2c_stop(); return true; } |
延时时间不够 |
用逻辑分析仪看下就明白了。 |
注意时序,我好几年前调通过,找到可以发给你参考 |
用示波器看看 |
SDA的 IO推动方式 ,最好用开漏型,脚上接个上拉电阻试试 |