软件模拟I2C的接口函数的通用改善

// header file
#ifndef __MYI2C_H_
#define __MYI2C_H_
// if cpp
#ifdef __cplusplus
extern "C" {
#endif

#include "delay.h"
#include "main.h"


typedef struct
{
    uint16_t      Device_Address;
    GPIO_TypeDef* SDA_Gpiox;
    uint16_t      SDA_pin;
    GPIO_TypeDef* SCL_Gpiox;
    uint16_t      SCL_pin;
} I2C_Device_t;

#define EEPROM_DEVICE_ID 0
#define EEPROM_DEVICE_ADDRESS 0xA0

const I2C_Device_t I2C_Device[0] = {{EEPROM_DEVICE_ADDRESS, GPIOB, GPIO_PIN_8, GPIOB, GPIO_PIN_9}, {}};

#ifdef __cplusplus
}
#endif

#endif
// fuc
#include "myi2c.h"

void I2C_Init(uint16_t deviceid)
{

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    HAL_GPIO_WritePin(I2C_Device[deviceid].SDA_Gpiox, SDA_pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, SCL_pin, GPIO_PIN_SET);

    GPIO_InitStruct.Pin   = SDA_pin;
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_OD;
    GPIO_InitStruct.Pull  = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(I2C_Device[deviceid].SDA_Gpiox, &GPIO_InitStruct);
    GPIO_InitStruct.Pin = SCL_pin;
    HAL_GPIO_Init(I2C_Device[deviceid].SCL_Gpiox, &GPIO_InitStruct);
    MY_I2C_Stop(deviceid);
}

void I2C_Start(uint16_t deviceid)
{
    HAL_GPIO_WritePin(I2C_Device[deviceid].SDA_Gpiox, I2C_Device[deviceid].SDA_pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_SET);
    delay_us(10);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SDA_Gpiox, I2C_Device[deviceid].SDA_pin, GPIO_PIN_RESET);
    delay_us(4);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_RESET);
}

void I2C_Stop(uint16_t deviceid)
{
    HAL_GPIO_WritePin(I2C_Device[deviceid].SDA_Gpiox, I2C_Device[deviceid].SDA_pin, GPIO_PIN_RESET);
    delay_us(4);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_SET);
    delay_us(1);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SDA_Gpiox, I2C_Device[deviceid].SDA_pin, GPIO_PIN_SET);
}

uint8_t waitAck(uint16_t deviceid)
{
    HAL_GPIO_WritePin(I2C_Device[deviceid].SDA_Gpiox, I2C_Device[deviceid].SDA_pin, GPIO_PIN_SET);
    delay_us(4);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_SET);
    if (HAL_GPIO_ReadPin(I2C_Device[deviceid].SDA_Gpiox, I2C_Device[deviceid].SDA_pin) == GPIO_PIN_RESET)
    {
        delay_us(4);
        HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_RESET);
        return 1;
    }
    delay_us(4);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_RESET);
    return 0;
}

void SendByte(uint16_t deviceid, uint8_t byte)
{
    for (int i = 0; i < 8; i++)
    {
        HAL_GPIO_WritePin(I2C_Device[deviceid].SDA_Gpiox, I2C_Device[deviceid].SDA_pin, (GPIO_PinState)((byte >> 7 - i) & 0x01));
        delay_us(2);
        HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_SET);
        delay_us(4);
        HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_RESET);
    }
    if (waitAck(deviceid) == 1) return;
    I2C_Stop(deviceid);
}

void Ack(uint16_t deviceid)
{
    HAL_GPIO_WritePin(I2C_Device[deviceid].SDA_Gpiox, I2C_Device[deviceid].SDA_pin, GPIO_PIN_RESET);
    delay_us(4);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_SET);
    delay_us(4);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_RESET);
    delay_us(2);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SDA_Gpiox, I2C_Device[deviceid].SDA_pin, GPIO_PIN_SET);
    delay_us(4);
}

void NAck(uint16_t deviceid)
{
    HAL_GPIO_WritePin(I2C_Device[deviceid].SDA_Gpiox, I2C_Device[deviceid].SDA_pin, GPIO_PIN_SET);
    delay_us(4);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_SET);
    delay_us(4);
    HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_RESET);
}

void reciveByte(uint16_t deviceid, uint8_t* byte, uint8_t ack)
{
    *byte = 0;
    for (int i = 0; i < 8; i++)
    {
        HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_SET);
        if (HAL_GPIO_ReadPin(I2C_Device[deviceid].SDA_Gpiox, I2C_Device[deviceid].SDA_pin) == GPIO_PIN_SET)
        {
            *byte += 1;
        }
        *byte <<= 1;
        delay_us(4);
        HAL_GPIO_WritePin(I2C_Device[deviceid].SCL_Gpiox, I2C_Device[deviceid].SCL_Gpiox, GPIO_PIN_RESET);
        delay_us(4);
    }
    if (ack == 1)
        Ack(deviceid);
    else
    {
        NAck(deviceid);
        I2C_Stop(deviceid);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值