STM32实例源码剖析(软件模拟IIC)

基本的驱动都是一样的,延时时间是之前遇到的一个小问题
代码都是之前做项目写的,基本可以完全复制使用

#include "I2C1_soft.h"
// Software I2C1_ driver
// I2C1 pinout (SCL: PB8, SDA: PB9)

void I2C1_delay(void)
{
    volatile int i = 14;//这个值可能影响协议,调试关注
    while (i) {
        i--;
    }
}

bool I2C1_Start(void)
{
    I2C1_SDA_H;
    I2C1_SCL_H;
    I2C1_delay();
    if (!I2C1_SDA_read)
        {
        return false;
    }
    I2C1_SDA_L;
    I2C1_delay();
    if (I2C1_SDA_read)
        {
        return false;
        }
    I2C1_SDA_L;
    I2C1_delay();
    return true;
}

void I2C1_Stop(void)
{
    I2C1_SCL_L;
    I2C1_delay();
    I2C1_SDA_L;
    I2C1_delay();
    I2C1_SCL_H;
    I2C1_delay();
    I2C1_SDA_H;
    I2C1_delay();
}

void I2C1_Ack(void)
{
    I2C1_SCL_L;
    I2C1_delay();
    I2C1_SDA_L;
    I2C1_delay();
    I2C1_SCL_H;
    I2C1_delay();
    I2C1_SCL_L;
    I2C1_delay();
}

void I2C1_NoAck(void)
{
    I2C1_SCL_L;
    I2C1_delay();
    I2C1_SDA_H;
    I2C1_delay();
    I2C1_SCL_H;
    I2C1_delay();
    I2C1_SCL_L;
    I2C1_delay();
}

bool I2C1_WaitAck(void)
{
    I2C1_SCL_L;
    I2C1_delay();
    I2C1_SDA_H;
    I2C1_delay();
    I2C1_SCL_H;
    I2C1_delay();
    if (I2C1_SDA_read) {
        I2C1_SCL_L;
        return false;
    }
    I2C1_SCL_L;
    return true;
}

void I2C1_SendByte(uint8_t byte)
{
    uint8_t i = 8;
    while (i--) {
        I2C1_SCL_L;
        I2C1_delay();
        if (byte & 0x80) {
            I2C1_SDA_H;
        } else {
            I2C1_SDA_L;
        }
        byte <<= 1;
        I2C1_delay();
        I2C1_SCL_H;
        I2C1_delay();
    }
    I2C1_SCL_L;
}

uint8_t I2C1_ReceiveByte(void)
{
    uint8_t i = 8;
    uint8_t byte = 0;

    I2C1_SDA_H;
    while (i--) {
        byte <<= 1;
        I2C1_SCL_L;
        I2C1_delay();
        I2C1_SCL_H;
        I2C1_delay();
        if (I2C1_SDA_read) {
            byte |= 0x01;
        }
    }
    I2C1_SCL_L;
    return byte;
}


bool I2C1_WriteBuffer(uint8_t addr, uint8_t reg, uint8_t len, uint8_t * data)
{
    int i;
    if (!I2C1_Start()) {
        return false;
    }
    I2C1_SendByte(addr << 1 | I2C1_Direction_Transmitter);
    if (!I2C1_WaitAck()) {
        I2C1_Stop();
        return false;
    }
    I2C1_SendByte(reg);
    I2C1_WaitAck();
    for (i = 0; i < len; i++) {
        I2C1_SendByte(data[i]);
        if (!I2C1_WaitAck()) {
            I2C1_Stop();
            return false;
        }
    }
    I2C1_Stop();
    return true;
}

bool I2C1_Write(uint8_t addr, uint8_t reg, uint8_t data)
{
    if (!I2C1_Start()) {
        return false;
    }
    I2C1_SendByte(addr << 1 | I2C1_Direction_Transmitter);
    if (!I2C1_WaitAck()) {
        I2C1_Stop();
        return false;
    }
    I2C1_SendByte(reg);
    I2C1_WaitAck();
    I2C1_SendByte(data);
    I2C1_WaitAck();
    I2C1_Stop();
    return true;
}

bool I2C1_Write_1(uint8_t addr, uint8_t data)
{
    if (!I2C1_Start())
        {
        return false;
        }
        
    I2C1_SendByte(addr << 1 | I2C1_Direction_Transmitter);
    if (I2C1_WaitAck())
        {
        I2C1_Stop();
        return false;
    }
    I2C1_SendByte(data);
    I2C1_WaitAck();
    I2C1_Stop();
    return true;
}

bool I2C1_Read(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf)
{
    if (!I2C1_Start()) {
        return false;
    }
    I2C1_SendByte(addr << 1 | I2C1_Direction_Transmitter);
    if (!I2C1_WaitAck()) {
        I2C1_Stop();
        return false;
    }
    I2C1_SendByte(reg);
    I2C1_WaitAck();
    I2C1_Start();
    I2C1_SendByte(addr << 1 | I2C1_Direction_Receiver);
    I2C1_WaitAck();
    while (len) {
        *buf = I2C1_ReceiveByte();
        if (len == 1) {
            I2C1_NoAck();
        } else {
            I2C1_Ack();
        }
        buf++;
        len--;
    }
    I2C1_Stop();
    return true;
}

bool I2C1_Read_buf(uint8_t addr, uint8_t len, uint8_t *buf)
{
  if (!I2C1_Start())
    {
      return false;
    }
  I2C1_SendByte(addr << 1 | I2C1_Direction_Receiver);
  I2C1_WaitAck();
  while (len)
    {
        *buf = I2C1_ReceiveByte();
    if (len == 1)
        {
        I2C1_NoAck();
    }
        else
        {
        I2C1_Ack();
      }
    buf++;
    len--;
  }
  I2C1_Stop();
  return true;
}

其.h

#ifndef __I2C1_SOFT_H__
#define __I2C1_SOFT_H__

#include 
#include "stm32f4xx_hal.h"

#define I2C1_SCL_H         HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET)
#define I2C1_SCL_L         HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET)

#define I2C1_SDA_H         HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET)
#define I2C1_SDA_L         HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)

#define I2C1_SCL_read      HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8)
#define I2C1_SDA_read      HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9)

#define I2C1_Direction_Transmitter    0x00
#define I2C1_Direction_Receiver       0x01

void I2C1_SendByte(uint8_t byte);
uint8_t I2C1_ReceiveByte(void);

bool I2C1_WriteBuffer(uint8_t addr, uint8_t reg, uint8_t len, uint8_t * data);
bool I2C1_Write(uint8_t addr, uint8_t reg, uint8_t data);
bool I2C1_Read(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf);
bool I2C1_Read_buf(uint8_t addr, uint8_t len, uint8_t *buf);
bool I2C1_Write_1(uint8_t addr, uint8_t data);

bool I2C1_Start(void);
bool I2C1_WaitAck(void);
void I2C1_Stop(void);
void I2C1_Ack(void);
void I2C1_NoAck(void);
#endif

你可能感兴趣的:(STM32深入剖析实践)