--------------------------------------------------------------------------- C ---------------------------------------------------------------------------------
#include"simulation_i2c.h"
GPIO_InitTypeDef mGPIO_InitTypeDef;
unsigned long Delaycount=0;
static void I2C_err_SCL( );
static void I2C_err_SDA( );
static void I2C_res_SDA( int gp_ft );
static void I2C_res_SCL( int gp_ft );
static void I2C_SCL_0();
static void I2C_SCL_1();
static void I2C_SDA_0();
static void I2C_SDA_1();
static void i2c_Start(void);
static void i2c_Stop(void);
static GPIO_PinState I2C_SDA_READ();
static uint8_t i2c_WaitAck(void);
static void i2c_Ack(void);
static void i2c_noAck(void);
static void i2c_SendByte(uint8_t _ucByte);
static GPIO_PinState I2C_SCL_READ();
static uint8_t i2c_ReadByte(void);
static void I2C_res_SDA( int gp_ft ){
mGPIO_InitTypeDef.Pin = I2cSda;
mGPIO_InitTypeDef.Mode = GPIO_MODE_OUTPUT_PP ;
mGPIO_InitTypeDef.Pull = GPIO_PULLUP;
mGPIO_InitTypeDef.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(I2cGrep, &mGPIO_InitTypeDef);
HAL_GPIO_WritePin(I2cGrep,I2cSda,gp_ft);
}
static void I2C_res_SCL( int gp_ft ){
mGPIO_InitTypeDef.Pin = I2cScl;
mGPIO_InitTypeDef.Mode = GPIO_MODE_OUTPUT_PP ;
mGPIO_InitTypeDef.Pull = GPIO_PULLUP;
mGPIO_InitTypeDef.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(I2cGrep, &mGPIO_InitTypeDef);
HAL_GPIO_WritePin(I2cGrep,I2cScl,gp_ft);
}
static void I2C_err_SCL( ){
mGPIO_InitTypeDef.Pin=I2cScl;
mGPIO_InitTypeDef.Mode=GPIO_MODE_INPUT;
HAL_GPIO_Init(I2cGrep, &mGPIO_InitTypeDef);
}
static void I2C_err_SDA( ){
mGPIO_InitTypeDef.Pin = I2cSda;
mGPIO_InitTypeDef.Mode = GPIO_MODE_OUTPUT_PP ;
mGPIO_InitTypeDef.Pull = GPIO_PULLUP;
mGPIO_InitTypeDef.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(I2cGrep, &mGPIO_InitTypeDef);
}
int i2c_err_fla(){
int err_sda = 1;
int err_scl = 1;
I2c_Delay(I2c_delay_num);
I2C_err_SCL( );
I2C_err_SDA( );
err_sda = HAL_GPIO_ReadPin(I2cGrep,I2cSda);
err_scl = HAL_GPIO_ReadPin(I2cGrep,I2cScl);
if( err_sda == 0 ){
return -2;
}
if( err_scl == 0 ){
return -2;
}
return 1;
}
void i2c_res(){
int wh = 9;
I2C_res_SDA( 1 );
I2C_res_SCL( 1 );
I2c_Delay(I2c_delay_num);
while( wh-- ){
I2C_res_SCL( 0 );
I2C_res_SDA( 0 );
I2c_Delay(I2c_delay_num);
I2C_res_SCL( 1 );
I2C_res_SDA( 1 );
I2c_Delay(I2c_delay_num);
}
}
void Mi2cGpioInit(void)
{
HAL_GPIO_WritePin(I2cGrep, I2cSda|I2cScl, 1 );//GPIO_PIN_SET);
mGPIO_InitTypeDef.Pin = I2cSda|I2cScl;
mGPIO_InitTypeDef.Mode = GPIO_MODE_OUTPUT_OD; // GPIO_MODE_OUTPUT_OD ;
mGPIO_InitTypeDef.Pull = GPIO_PULLUP; // GPIO_PULLUP;
mGPIO_InitTypeDef.Speed = GPIO_SPEED_FREQ_LOW ; //GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(I2cGrep, &mGPIO_InitTypeDef);
}
static void I2C_SDA_1()
{
mGPIO_InitTypeDef.Pin = I2cSda;
mGPIO_InitTypeDef.Mode = GPIO_MODE_OUTPUT_OD; // GPIO_MODE_OUTPUT_PP;
mGPIO_InitTypeDef.Pull = GPIO_PULLUP; // GPIO_NOPULL;
mGPIO_InitTypeDef.Speed = GPIO_SPEED_FREQ_LOW; // GPIO_SPEED_FREQ_HIGH
HAL_GPIO_Init(I2cGrep, &mGPIO_InitTypeDef);
HAL_GPIO_WritePin(I2cGrep,I2cSda,1);
}
static void I2C_SDA_0()
{
mGPIO_InitTypeDef.Pin = I2cSda;
mGPIO_InitTypeDef.Mode = GPIO_MODE_OUTPUT_OD;
mGPIO_InitTypeDef.Pull = GPIO_PULLUP;
mGPIO_InitTypeDef.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(I2cGrep, &mGPIO_InitTypeDef);
HAL_GPIO_WritePin(I2cGrep,I2cSda,0);
}
static void I2C_SCL_1()
{
mGPIO_InitTypeDef.Pin = I2cScl;
mGPIO_InitTypeDef.Mode = GPIO_MODE_OUTPUT_OD;
mGPIO_InitTypeDef.Pull = GPIO_PULLUP;
mGPIO_InitTypeDef.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(I2cGrep, &mGPIO_InitTypeDef);
HAL_GPIO_WritePin(I2cGrep,I2cScl,1);
}
static void I2C_SCL_0()
{
mGPIO_InitTypeDef.Pin = I2cScl;
mGPIO_InitTypeDef.Mode = GPIO_MODE_OUTPUT_OD;
mGPIO_InitTypeDef.Pull = GPIO_PULLUP;
mGPIO_InitTypeDef.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(I2cGrep, &mGPIO_InitTypeDef);
HAL_GPIO_WritePin(I2cGrep,I2cScl,0);
}
static void i2c_Start(void)
{
I2c_Delay(I2c_delay_num);
I2C_SDA_0();
I2c_Delay(I2c_delay_num);
I2C_SDA_1();
I2C_SCL_0();
I2c_Delay(I2c_delay_num);
}
static void i2c_Stop(void)
{
I2C_SDA_0();
I2c_Delay(I2c_delay_num);
I2C_SCL_1();
I2c_Delay(I2c_delay_num);
I2C_SDA_1();
I2c_Delay(I2c_delay_num);
}
static GPIO_PinState I2C_SDA_READ()
{
// memset( &mGPIO_InitTypeDef, 0, sizeof(GPIO_InitTypeDef) );
mGPIO_InitTypeDef.Pin=I2cSda;
mGPIO_InitTypeDef.Mode=GPIO_MODE_INPUT;
HAL_GPIO_Init(I2cGrep, &mGPIO_InitTypeDef);
I2c_Delay(I2c_delay_num);
return HAL_GPIO_ReadPin(I2cGrep,I2cSda);
}
static GPIO_PinState I2C_SCL_READ()
{
mGPIO_InitTypeDef.Pin=I2cScl;
mGPIO_InitTypeDef.Mode=GPIO_MODE_INPUT;
HAL_GPIO_Init(I2cGrep, &mGPIO_InitTypeDef);
I2c_Delay(I2c_delay_num);
return HAL_GPIO_ReadPin(I2cGrep,I2cScl);
}
static uint8_t i2c_WaitAck(void)
{
uint8_t re;
I2C_SDA_1(); /* CPU释放SDA总线 */
I2c_Delay(I2c_delay_num);
I2C_SCL_1(); /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
if (I2C_SDA_READ()) /* CPU读取SDA口线状态 */
{
re = 1;
}
else
{
re = 0;
}
I2C_SCL_0();
I2c_Delay(I2c_delay_num);
return re;
}
//应答信号
static void i2c_Ack(void)
{
I2C_SDA_0(); /* CPU驱动SDA = 0 */
I2c_Delay(I2c_delay_num);
I2C_SCL_1(); /* CPU产生1个时钟 */
I2c_Delay(I2c_delay_num);
I2C_SCL_0();
I2c_Delay(I2c_delay_num);
I2C_SDA_1(); /* CPU释放SDA总线 */
}
static void i2c_noAck(void){
I2C_SDA_1();
I2c_Delay(I2c_delay_num);
I2C_SCL_1();
I2c_Delay(I2c_delay_num);
I2C_SCL_0();
I2c_Delay(I2c_delay_num);
I2C_SDA_0();
}
static void i2c_SendByte(uint8_t _ucByte)
{
uint8_t i;
// 先发送字节的高位bit7
for (i = 0; i < 8; i++)
{
if (_ucByte & 0x80)
{
I2C_SDA_1();
}
else
{
I2C_SDA_0();
}
I2c_Delay(I2c_delay_num);
I2C_SCL_1();
I2c_Delay(I2c_delay_num);
I2C_SCL_0();
if (i == 7)
{
I2C_SDA_1(); // 释放总线
}
_ucByte <<= 1; // 左移一个bit
I2c_Delay(I2c_delay_num);
}
}
static uint8_t i2c_ReadByte(void)
{
uint8_t i;
uint8_t value;
/* 读到第1个bit为数据的bit7 */
value = 0;
for (i = 0; i < 8; i++)
{
value <<= 1;
I2C_SCL_1();
I2c_Delay(I2c_delay_num);
if (I2C_SDA_READ())
{
value++;
}
I2C_SCL_0();
I2c_Delay(I2c_delay_num);
}
return value;
}
uint8_t i2c_CheckDevice(uint8_t _Address)
{
uint8_t ucAck=1;
if (I2C_SDA_READ() && I2C_SCL_READ())
{
i2c_Start(); /* 发送启动信号 */
/* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */
i2c_SendByte(_Address<<1 | 0);
ucAck = i2c_WaitAck(); /* 检测设备的ACK应答 */
i2c_Stop(); /* 发送停止信号 */
return ucAck;
}
return 1; /* I2C总线异常 */
}
int Device_WriteData(uint8_t DeciveAddr,uint8_t *Data,int size)
{
int count=size;
int text=0;
uint8_t *pData=Data;
//起始信号
i2c_Start();
//发送器件地址
i2c_SendByte(((DeciveAddr<<1)&0xFE));
//等待应答
if(0!=i2c_WaitAck())
{
i2c_Stop();
return -1;
}
while(count--)
{
//发送数据
i2c_SendByte(*pData++);
//等待应答
if(0!=i2c_WaitAck())
{
i2c_Stop();
return -2;
}
}
//结束信号
I2c_Delay(I2c_delay_num);
i2c_Stop();
return 1 ;
}
int Device_ReadData(uint8_t DeciveAddr,uint8_t *Data,int size)
{
int count=size;
int text=0;
int i=0;
uint8_t *pData=Data;
if( i2c_err_fla() < 0 ){
return -2;
}
i2c_Start();
i2c_SendByte(((DeciveAddr<<1)|0x01));
if(0!=i2c_WaitAck())
{
i2c_Stop();
return -1;
}
for(i=0;i<size;i++)
{
Data[i]=i2c_ReadByte();
if( i < size-1 ){
i2c_Ack();
} else {
i2c_noAck();
}
}
i2c_Stop();
return 1 ;
}
--------------------------------------------------------------------------- H ---------------------------------------------------------------------------------
#ifndef __S_I2C__
#define __S_I2C__
#include "stm32f4xx_hal.h"
#define this_i2c_
#include "gpio.h"
#include "stdint.h"
#define I2cGrep GPIOB
#define I2cSda GPIO_PIN_14
#define I2cScl GPIO_PIN_13
static unsigned int I2c_delay_num = 8000 ;
#define I2c_Delay(x) for(Delaycount=0;Delaycount<x;Delaycount++)
void i2c_res();
void Mi2cGpioInit(void);
uint8_t i2c_CheckDevice(uint8_t _Address);
int i2c_err_fla();
int Device_WriteData(uint8_t DeciveAddr,uint8_t *Data,int size);
int Device_ReadData(uint8_t DeciveAddr,uint8_t *Data,int size);
#endif