STM32F407单片机HAL库模拟软件IIC(可移植到其他单片机)

注:以下文件进行移植,直接修改IIC.H的引脚,就可以使用了

IIC.C

/*
 * softiic.c
 *
 *  Created on: 2024年6月12日
 *      Author: Administrator
 */
 
#include "softiic.h"
 
uint8_t send_data[]={0x01,0x02,0x03,0x04,0x05,0x06};
uint8_t receive_data[]={0x00,0x00,0x00,0x00,0x00,0x00};
 
 
 
uint32_t delay1us;
 
/**
 * @brief: 1us延时
 * @param {uint32_t} delay_1us
 * @return {*}
 */
void delay_1us(uint32_t delay_1us)
{
	  __IO uint32_t Delay = delay_1us * 168 / 8;//(SystemCoreClock / 8U / 1000000U)
	    //见stm32f1xx_hal_rcc.c -- static void RCC_Delay(uint32_t mdelay)
	  do
	  {
	    __NOP();
	  }
	  while (Delay --);
}
 
/**
 * @brief: IIC延时时间
 * @return {*}
 */
 
 
void analog_i2c_delay(void)
{
    delay_1us(5);
}
 
/**
 * @brief: 软件模拟I2C初始化
 * @return {*}
 */
void bsp_analog_i2c_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
 
    __HAL_RCC_GPIOD_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
 
    /*Configure GPIO pins : PD6 */
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
    /*Configure GPIO pins : PC1 */
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    i2c_sda_high();
    i2c_scl_high();
   // bsp_analog_i2c_stop();
}
 
/**
 * @brief: I2C 开始,SCL为高电平的时候SDA产生一个下降沿信号
 * @return {*}
 */
void bsp_analog_i2c_start(void)
{
    /*    _____
     *SDA      \_____________
     *    __________
     *SCL           \________
     */
    SDA_OUT();
    i2c_sda_high();
    i2c_scl_high();
    analog_i2c_delay();
    i2c_sda_low();
    analog_i2c_delay();
    i2c_scl_low();
    analog_i2c_delay();
}
 
/**
 * @brief: I2C 停止,SCL为高电平的时候SDA产生一个上升沿信号
 * @return {*}
 */
void bsp_analog_i2c_stop(void)
{
    /*               _______
     *SDA __________/
     *          ____________
     *SCL _____/
     */
    SDA_OUT();
    i2c_sda_low();
    i2c_scl_high();
    analog_i2c_delay();
    i2c_sda_high();
    analog_i2c_delay();
}
 
/**
 * @brief: I2C 等待响应
 * @return {*}
 */
uint8_t bsp_analog_i2c_wait_ack(void)
{
    uint32_t timeout = 0;
    i2c_sda_high();
    SDA_IN();
    analog_i2c_delay();
    i2c_scl_high();
    analog_i2c_delay();
    while(i2c_read_sda())
    {
        timeout++;
        if(timeout > 255)
        {
            bsp_analog_i2c_stop();
 
            return 1;
        }
  	  //printf("timeout=%d\r\n",timeout);
 
    }
    i2c_scl_low();
    analog_i2c_delay();
    return 0;
}
 
/**
 * @brief: I2C 响应
 * @return {*}
 */
void bsp_analog_i2c_ack(void)
{
    /*           ____
     *SCL ______/    \______
     *    ____         _____
     *SDA     \_______/
     */
    SDA_OUT();
    i2c_sda_low();
    analog_i2c_delay();
    i2c_scl_high();
    analog_i2c_delay();
    i2c_scl_low();
    analog_i2c_delay();
    i2c_sda_high();
}
 
/**
 * @brief: I2C 不响应
 * @return {*}
 */
void bsp_analog_i2c_nack(void)
{
    /*           ____
     *SCL ______/    \______
     *    __________________
     *SDA
     */
    SDA_OUT();
    i2c_sda_high();
    analog_i2c_delay();
    i2c_scl_high();
    analog_i2c_delay();
    i2c_scl_low();
    analog_i2c_delay();
}
 
/**
 * @brief: I2C 发送一个字节数据
 * @param {uint8_t} data
 * @return {*}
 */
void bsp_analog_i2c_send_byte(uint8_t data)
{
    uint8_t i;
 
    SDA_OUT();
    for(i = 0; i < 8; i++)
    {
        if(data & 0x80)
        {
           i2c_sda_high();
        }
        else
        {
            i2c_sda_low();
        }
 
        analog_i2c_delay();
        i2c_scl_high();
        analog_i2c_delay();
        i2c_scl_low();
        if(i == 7)
        {
            i2c_sda_high();
        }
        data <<= 1;
        analog_i2c_delay();
    }
}
 
/**
 * @brief: I2C 读一个字节数据
 * @return {*}
 */
uint8_t bsp_analog_i2c_read_byte(void)
{
    uint8_t i, data = 0;
 
    i2c_sda_high();
    SDA_IN();
    for(i = 0; i < 8; i++ )
    {
        data <<= 1;
        i2c_scl_high();
        analog_i2c_delay();
        if(i2c_read_sda())
        {
            data++;
        }
        i2c_scl_low();
        analog_i2c_delay();
    }
 
    return data;
}
 
 
 
void WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite)
{
	  bsp_analog_i2c_start();
	  bsp_analog_i2c_send_byte(salve_address_write);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_send_byte(WriteAddr);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_send_byte(DataToWrite);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_stop();
}
 
 
uint8_t ReadOneByte(uint8_t ReadAddr)
{
	  uint8_t temp=0;
	  bsp_analog_i2c_start();
	  bsp_analog_i2c_send_byte(salve_address_write);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_send_byte(ReadAddr);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_start();
	  bsp_analog_i2c_send_byte(salve_address_read);
	  bsp_analog_i2c_wait_ack();
	  temp= bsp_analog_i2c_read_byte();
	  bsp_analog_i2c_nack();
	  bsp_analog_i2c_stop();
   return temp;
}
 
 
/*连续写*/
void sequence_write(uint8_t WriteAddr,uint8_t* data,int length)
{
	bsp_analog_i2c_start();
	bsp_analog_i2c_send_byte(salve_address_write);
	bsp_analog_i2c_wait_ack();
	bsp_analog_i2c_send_byte(WriteAddr);
	bsp_analog_i2c_wait_ack();
    for (int i = 0; i < length; i++)
    {
		bsp_analog_i2c_send_byte(*(data+i));
		bsp_analog_i2c_wait_ack();
    }
	bsp_analog_i2c_nack();
	bsp_analog_i2c_stop();
}
 
 
/*连续读*/
void sequence_read(uint8_t ReadAddr,uint8_t *data,int length)
{
	  bsp_analog_i2c_start();
	  bsp_analog_i2c_send_byte(salve_address_write);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_send_byte(ReadAddr);
	  bsp_analog_i2c_wait_ack();
	  bsp_analog_i2c_start();
	  bsp_analog_i2c_send_byte(salve_address_read);
	  bsp_analog_i2c_wait_ack();
	    for (int i = 0; i < length; i++)
	    {
	      *(data+i)= bsp_analog_i2c_read_byte();
		  bsp_analog_i2c_ack();
	    }
	  bsp_analog_i2c_stop();
}

IIC.H

/*
 * softiic.h
 *
 *  Created on: 2024年6月12日
 *      Author: Administrator
 */
 
#ifndef __SOFTIIC_H_
#define __SOFTIIC_H_
 
#include "main.h"
//使用IICX   PD6,PC1
 
#define salve_address_write 0xC0
#define salve_address_read 0xC1
 
#define SDA_IN()  {GPIOC->MODER &= ~(3 << 1 * 2);GPIOC->MODER = (0 << 1 * 2);}
#define SDA_OUT() {GPIOC->MODER &= ~(3 << 1 * 2);GPIOC->MODER = (1 << 1 * 2);}
 
 
//void SDAIN(void);
 
//IO操作函数
#define i2c_scl_low()    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_RESET)
#define i2c_scl_high()   HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_SET)
 
#define i2c_sda_low()    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET)
#define i2c_sda_high()   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET)
 
#define i2c_read_sda()   HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_1)
 
extern uint32_t delay1us;
 
void delay_1us(uint32_t delay_1us);
 
void analog_i2c_delay(void);
 
void bsp_analog_i2c_init(void);
 
void bsp_analog_i2c_start(void);
 
void bsp_analog_i2c_stop(void);
 
uint8_t bsp_analog_i2c_wait_ack(void);
 
void bsp_analog_i2c_ack(void);
 
void bsp_analog_i2c_nack(void);
 
void bsp_analog_i2c_send_byte(uint8_t data);
 
uint8_t bsp_analog_i2c_read_byte(void);
 
void WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite);
 
uint8_t ReadOneByte(uint8_t ReadAddr);
 
void sequence_write(uint8_t WriteAddr,uint8_t* data,int length);
 
void sequence_read(uint8_t ReadAddr,uint8_t data[],int length);
 
#endif

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值