HAL库&STM32cubeMX工程软件模拟IIC,改改引脚即可直接使用

由于stm32后续的库文件只有hal库了,为了使代码更方便,也做了一个移植性很高的库文件,拿到手之后改改引脚就可以快速使用

c文件如下

/**
 * @file     softwareiic.c
 * @brief    适用于STM32 HAL库及CUBEMX生成工程的软件模拟IIC
 * @version  V1.0.0
 * @author   Sundea
 * @date     2023/5/8
 */
#include "softwareIIC.h"

/**
 * @brief IIC延时
 * @param  无
 * @return 无
 */
void IIC_Delay(uint8_t time)
{
    uint32_t i = time * 800; // 用户根据自己的MCU时钟进行设置倍数

    while (i--)
    {
        ;
    }
}

/**
 * @brief IIC初始化
 * @param  无
 * @return 无
 */
void Soft_IIC_Init(void)
{
    IIC_SDA_H();
    IIC_SCL_H();
}

/**
 * @brief SDA引脚设置输出模式
 * @param  无
 * @return 无
 */
static void Soft_IIC_Output(void)
{
    GPIO_InitTypeDef SOFT_IIC_GPIO_STRUCT;
    SOFT_IIC_GPIO_STRUCT.Mode = GPIO_MODE_OUTPUT_PP;
    SOFT_IIC_GPIO_STRUCT.Pin = IIC_SDA_PIN;
    SOFT_IIC_GPIO_STRUCT.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(IIC_SDA_PORT, &SOFT_IIC_GPIO_STRUCT);
}

/**
 * @brief SDA引脚设置输入模式
 * @param  无
 * @return 无
 */
static void Soft_IIC_Input(void)
{
    GPIO_InitTypeDef SOFT_IIC_GPIO_STRUCT;
    SOFT_IIC_GPIO_STRUCT.Mode = GPIO_MODE_INPUT;
    SOFT_IIC_GPIO_STRUCT.Pin = IIC_SDA_PIN;
    SOFT_IIC_GPIO_STRUCT.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(IIC_SDA_PORT, &SOFT_IIC_GPIO_STRUCT);
}

/**
 * @brief IIC起始信号
 * @param  无
 * @return 无
 */
void Soft_IIC_Start(void)
{
    Soft_IIC_Output();
    IIC_SCL_L();
    IIC_SDA_H();
    IIC_SCL_H();
    IIC_Delay(IIC_DELAY_TIME);
    IIC_SDA_L();
    IIC_Delay(IIC_DELAY_TIME);
    IIC_SCL_L();
}

/**
 * @brief IIC停止信号
 * @param  无
 * @return 无
 */
void Soft_IIC_Stop(void)
{
    Soft_IIC_Output();
    IIC_SCL_L();
    IIC_SDA_L();
    IIC_SCL_H();
    IIC_Delay(IIC_DELAY_TIME);
    IIC_SDA_H();
    IIC_Delay(IIC_DELAY_TIME);
}

/**
 * @brief IIC应答信号
 * @param  无
 * @return 无
 */
void Soft_IIC_ACK(void)
{
    Soft_IIC_Output();
    IIC_SCL_L();
    IIC_SDA_L();
    IIC_Delay(IIC_DELAY_TIME);
    IIC_SCL_H();
    IIC_Delay(IIC_DELAY_TIME);
    IIC_SCL_L();
}

/**
 * @brief IIC无应答信号
 * @param  无
 * @return 无
 */
void Soft_IIC_NACK(void)
{
    Soft_IIC_Output();
    IIC_SCL_L();
    IIC_SDA_H();
    IIC_Delay(IIC_DELAY_TIME);
    IIC_SCL_H();
    IIC_Delay(IIC_DELAY_TIME);
}

/**
 * @brief IIC等待应答信号
 * @param  无
 * @return 0无应答  1有应答
 */
uint8_t Soft_IIC_Wait_ACK(void)
{
    uint8_t wait;
    Soft_IIC_Output();
    IIC_SDA_H();
    Soft_IIC_Input();
    IIC_SCL_H();
    IIC_Delay(IIC_DELAY_TIME);
    while (HAL_GPIO_ReadPin(IIC_SDA_PORT, IIC_SDA_PIN))
    {
        wait++;
        if (wait > 200)
        {
            Soft_IIC_Stop();
            return 0;
        }
    }
    IIC_SCL_L();
    return 1;
}

/**
 * @brief IIC写数据1
 * @param  无
 * @return 无
 */
void Soft_IIC_Write_High(void)
{
    IIC_SCL_L();
    IIC_SDA_H();
    IIC_Delay(IIC_DELAY_TIME);
    IIC_SCL_H();
    IIC_Delay(IIC_DELAY_TIME);
    IIC_SCL_L();
}

/**
 * @brief IIC写数据0
 * @param  无
 * @return 无
 */
void Soft_IIC_Write_Low(void)
{
    IIC_SCL_L();
    IIC_SDA_L();
    IIC_Delay(IIC_DELAY_TIME);
    IIC_SCL_H();
    IIC_Delay(IIC_DELAY_TIME);
    IIC_SCL_L();
}

/**
 * @brief IIC写入单个数据
 * @param  无
 * @return 应答信号, 0无应答 1有应答
 */
uint8_t Soft_IIC_Write_Byte(uint8_t Byte)
{
    uint8_t i;
    Soft_IIC_Output();
    for (i = 0x80; i != 0; i >>= 1)
    {
        if (Byte & i)
        {
            Soft_IIC_Write_High();
        }
        else
        {
            Soft_IIC_Write_Low();
        }
    }
    return (Soft_IIC_Wait_ACK());
}

/**
 * @brief IIC读一个数据
 * @param  ACK:应答 NACK:不应答
 * @return 返回读到的数据
 */
uint8_t Soft_IIC_Recv_Byte(ACK_STATUS ack_sta)
{
    uint8_t data = 0, i;
    Soft_IIC_Input();
    IIC_SCL_H();
    IIC_Delay(IIC_DELAY_TIME);
    for (i = 0x80; i != 0; i >>= 1)
    {
        if (HAL_GPIO_ReadPin(IIC_SDA_PORT, IIC_SDA_PIN) == 1)
        {
            data |= i;
        }
        IIC_Delay(IIC_DELAY_TIME);
        IIC_SCL_L();
        IIC_Delay(IIC_DELAY_TIME);
        IIC_SCL_H();
        IIC_Delay(IIC_DELAY_TIME);
    }
    if (ack_sta == ACK)
    {
        Soft_IIC_ACK();
    }
    else
    {
        Soft_IIC_NACK();
    }
    return data;
}

h文件如下

#ifndef _SOFTWAREIIC_H_
#define _SOFTWAREIIC_H_

#include "main.h"

typedef enum{
    NACK = 0,
    ACK  = 1
}ACK_STATUS;

#define IIC_DELAY_TIME 10

#define IIC_SCL_PIN GPIO_PIN_2
#define IIC_SCL_PORT GPIOB

#define IIC_SDA_PIN GPIO_PIN_1
#define IIC_SDA_PORT GPIOB

// #define IIC_SDA_H() GPIOB->BSRR = 0x010
// #define IIC_SDA_L() GPIOB->BRR = 0x010
// #define IIC_SCL_H() GPIOB->BSRR = 0x100
// #define IIC_SCL_L() GPIOB->BRR = 0x100

#define IIC_SCL_H()     HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_SET)
#define IIC_SCL_L()     HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET)
#define IIC_SDA_H()     HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET)
#define IIC_SDA_L()     HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET)


void Soft_IIC_Init(void);
void Soft_IIC_Start(void);
void Soft_IIC_Stop(void);
void Soft_IIC_ACK(void);
void Soft_IIC_NACK(void);
uint8_t Soft_IIC_Wait_ACK(void);
uint8_t Soft_IIC_Write_Byte(uint8_t Byte);
uint8_t Soft_IIC_Recv_Byte(ACK_STATUS ack_sta);

#endif

  • 8
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值