模拟I2C程序,带多字节连收、多字节连发,适用于各个平台

--------------------------------------------------------------------------- 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

 


 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值