当前位置:网站首页>Software I2C based on Hal Library

Software I2C based on Hal Library

2022-07-06 11:22:00 Clear glass, brilliant orange

 Insert picture description here

I2C Transmission timing

#include <stdio.h>
#include "main.h"
#include "driver_i2c.h"
#include "driver_timer.h"
#include "driver_usart.h"

#define I2C_Delay() us_timer_delay(5) // Clock Pulse Width >5us

/* *  Function name :void I2C_Init(void) *  Input parameters : *  Output parameters : nothing  *  Return value : nothing  *  Function function : Initialize simulation I2C The pin of is in the output state and SCL/SDA Are initially high level  */
void I2C_Init(void)
{
    
    GPIO_InitTypeDef  GPIO_InitStruct = {
    0};
    
    SCL_PIN_CLK_EN();  /* __HAL_RCC_GPIOB_CLK_ENABLE() */
    SDA_PIN_CLK_EN();  /* __HAL_RCC_GPIOB_CLK_ENABLE() */
    
    GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
    
    GPIO_InitStruct.Pin       = SCL_PIN; /* SCL_PIN by  GPIO_PIN_6 */
    HAL_GPIO_Init(SCL_PORT, &GPIO_InitStruct); 
    
    GPIO_InitStruct.Pin       = SDA_PIN; /* SDA_PIN by GPIO_PIN_7 */
    HAL_GPIO_Init(SDA_PORT, &GPIO_InitStruct);
    
    SCL_H();  /*  Set up  SCL_PIN High level HAL_GPIO_WritePin(SCL_PORT, SCL_PIN, GPIO_PIN_SET) */
    SDA_H();   /* Set up  SDA_PIN High level  HAL_GPIO_WritePin(SDA_PORT, SDA_PIN, GPIO_PIN_SET) */
}

/*

  • Function name :static void I2C_SDA_OUT(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function : To configure SDA Pin is output
    */
static void I2C_SDA_OUT(void)
{
    
    GPIO_InitTypeDef  GPIO_InitStruct = {
    0};
    
    GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull      = GPIO_PULLUP;
    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
    
    GPIO_InitStruct.Pin       = SDA_PIN;
    HAL_GPIO_Init(SDA_PORT, &GPIO_InitStruct);
}

/*

  • Function name :static void I2C_SDA_IN(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function : To configure SDA Pin is input
    */
static void I2C_SDA_IN(void)
{
    
    GPIO_InitTypeDef  GPIO_InitStruct = {
    0};
        
    GPIO_InitStruct.Mode      = GPIO_MODE_INPUT;
    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
    
    GPIO_InitStruct.Pin       = SDA_PIN;
    HAL_GPIO_Init(SDA_PORT, &GPIO_InitStruct);
}

/*

  • Function name :void I2C_Start(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function :I2C Start signal
    */
void I2C_Start(void)
{
    
    I2C_SDA_OUT();
    
    SCL_H();  /*  Pull up the clock line  HAL_GPIO_WritePin(SCL_PORT, SCL_PIN, GPIO_PIN_SET) */
	I2C_Delay();
    
    SDA_H();
    I2C_Delay();
    
    SDA_L();
    I2C_Delay();
    
    SCL_L();
    I2C_Delay();
}

/*

  • Function name :void I2C_Stop(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function :I2C Stop signal
    */
void I2C_Stop(void)
{
    
    I2C_SDA_OUT();
    
    SDA_L();
    I2C_Delay();
    
    SCL_H();
    I2C_Delay();
    
    SDA_H();
    I2C_Delay();
}

 Insert picture description here

/*

  • Function name :void I2C_ACK(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function :I2C Send a reply signal
    */
void I2C_ACK(void)
{
    
    I2C_SDA_OUT();  /*  Set up SDA For export  */
    
    SCL_L();
    I2C_Delay();
    
    SDA_L();
    I2C_Delay();
    
    SCL_H();  /*  Pull the clock cable high , Generate rising edge data transmission  */
    I2C_Delay(); 
    
    SCL_L();
    I2C_Delay();
}

/*

  • Function name :void I2C_NACK(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function :I2C Send a non reply signal
    */
void I2C_NACK(void)
{
    
    I2C_SDA_OUT();
    
    SCL_L();
    I2C_Delay();
    
    SDA_H();
    I2C_Delay();
    
    SCL_H();
    I2C_Delay();
    
    SCL_L();
    I2C_Delay();
}

/*

  • Function name :uint8_t I2C_GetACK(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value :1 No response ,0 There's a response
  • Function function :I2C Wait for the response signal from the slave
    */
uint8_t I2C_GetACK(void)
{
    
    uint8_t time = 0;
    I2C_SDA_IN();
    
    SCL_L();
	I2C_Delay();
    
    SDA_H();
	I2C_Delay();
    
	SCL_H();
	I2C_Delay();
    
    while(SDA_INPUT())  
    {
    
        time++;
        if(time>250)
        {
    
            SCL_L();
            return 1;
        }
    }
    SCL_L();
    
    return 0;
}

/*

  • Function name :void I2C_SendByte(uint8_t data)
  • Input parameters :data-> Data sent
  • Output parameters : nothing
  • Return value : nothing
  • Function function :I2C Send a byte
    */
void I2C_SendByte(uint8_t data)
{
    
    uint8_t cnt = 0;
    
    I2C_SDA_OUT();
    
    for(cnt=0; cnt<8; cnt++)
    {
    
        SCL_L();
        I2C_Delay();
        
        if(data & 0x80)
        {
    
            SDA_H();
        }
        else
        {
    
            SDA_L();
        }
        data = data<<1;
        
        SCL_H();
        I2C_Delay();
    }
    
    SCL_L();
    I2C_Delay();
    I2C_GetACK();
}

/*

  • Function name :uint8_t I2C_ReadByte(uint8_t ack)
  • Input parameters :ack-> Sent reply flag ,1 The reply ,0 Non response
  • Output parameters : nothing
  • Return value : Return the read bytes
  • Function function :I2C Read a byte
    */
uint8_t I2C_ReadByte(uint8_t ack)
{
    
    uint8_t cnt;
    uint8_t data = 0xFF;
    
    SCL_L();    
    I2C_Delay();

    for(cnt=0; cnt<8; cnt++)
    {
    
        SCL_H();                 //SCL high ( Reading data )
        I2C_Delay();
        
        data <<= 1;
        if(SDA_INPUT())
        {
    
            data |= 0x01;        //SDA high ( The data is 1)
        }
        SCL_L(); 
        I2C_Delay();
    }
    // Send reply signal , Answer for low , High representative non response 
    if(ack == 0)
    {
    
        I2C_ACK();
    }
    else
    {
    
        I2C_NACK();
    }
    return data;                 // Return the data 
}

i2c.h file

#ifndef __DRIVER_I2C_H
#define __DRIVER_I2C_H

#include "stm32f1xx_hal.h"

/************************* I2C Hardware related definitions *************************/

#define ACK (0)
#define NACK (1)

#define SCL_PIN GPIO_PIN_6
#define SCL_PORT GPIOB
#define SCL_PIN_CLK_EN() __HAL_RCC_GPIOB_CLK_ENABLE()

#define SDA_PIN GPIO_PIN_7
#define SDA_PORT GPIOB
#define SDA_PIN_CLK_EN() __HAL_RCC_GPIOB_CLK_ENABLE()

#define SCL_H() HAL_GPIO_WritePin(SCL_PORT, SCL_PIN, GPIO_PIN_SET)
#define SCL_L() HAL_GPIO_WritePin(SCL_PORT, SCL_PIN, GPIO_PIN_RESET)
#define SCL_INPUT() HAL_GPIO_ReadPin(SCL_PORT, SCL_PIN)
                            
#define SDA_H() HAL_GPIO_WritePin(SDA_PORT, SDA_PIN, GPIO_PIN_SET)
#define SDA_L() HAL_GPIO_WritePin(SDA_PORT, SDA_PIN, GPIO_PIN_RESET)
#define SDA_INPUT() HAL_GPIO_ReadPin(SDA_PORT, SDA_PIN)

/************************* I2C End of hardware related definitions ************************/
/

  • Function name :void I2C_Init(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function : Initialize simulation I2C The pin of is in the output state and SCL/SDA Are initially high level
    */
extern void I2C_Init(void);

/*

  • Function name :void I2C_Start(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function :I2C Start signal
    */
extern void I2C_Start(void);

/*

  • Function name :void I2C_Stop(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function :I2C Stop signal
    */
extern void I2C_Stop(void);

/*

  • Function name :void I2C_ACK(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function :I2C Send a reply signal
    */
extern void I2C_ACK(void);

/*

  • Function name :void I2C_NACK(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function :I2C Send a non reply signal
    */
extern void I2C_NACK(void);

/*

  • Function name :uint8_t I2C_GetACK(void)
  • Input parameters :
  • Output parameters : nothing
  • Return value : nothing
  • Function function :I2C Wait for the response signal from the slave
    */
extern uint8_t I2C_GetACK(void);

/*

  • Function name :void I2C_SendByte(uint8_t data)
  • Input parameters :data-> Data sent
  • Output parameters : nothing
  • Return value : nothing
  • Function function :I2C Send a byte
    */
extern void I2C_SendByte(uint8_t data);

/*

  • Function name :uint8_t I2C_ReadByte(uint8_t ack)
  • Input parameters :ack-> Sent reply flag ,1 The reply ,0 Non response
  • Output parameters : nothing
  • Return value : Return the read bytes
  • Function function :I2C Read a byte
    */
extern uint8_t I2C_ReadByte(uint8_t ack);

#endif

原网站

版权声明
本文为[Clear glass, brilliant orange]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202131627245918.html