STM32 IIC协议实现

1.0 宏定义引脚


cpp 复制代码
#define GET_IIC_SDA() GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9)
#define SET_IIC_SCL() GPIO_SetBits(GPIOB, GPIO_Pin_8)
#define CLR_IIC_SCL() GPIO_ResetBits(GPIOB, GPIO_Pin_8) 
#define SET_IIC_SDA() GPIO_SetBits(GPIOB, GPIO_Pin_9)   
#define CLR_IIC_SDA() GPIO_ResetBits(GPIOB, GPIO_Pin_9)

#define ONE_BYTE_NUM (8)

2.0 初始化GPIO


注:此处表示对应的SCL与SDA引脚

cpp 复制代码
void IIC_Init(void)
{
    /*开启时钟*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 开启GPIOB的时钟

    /*GPIO初始化*/
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure); // 将PB10和PB11引脚初始化为开漏输出

    /*设置默认电平*/
    GPIO_SetBits(GPIOB, GPIO_Pin_8 | GPIO_Pin_9); // 设置PB8和PB9引脚初始化后默认为高电平(释放总线状态)
}

3.0 IIC起始信号


cpp 复制代码
void IIC_Start(void)
{
    SET_IIC_SDA();
    SET_IIC_SCL();
    Delay_us(10);
    CLR_IIC_SDA();
    Delay_us(10);
    CLR_IIC_SCL();
}

4.0 IIC停止信号


cpp 复制代码
void IIC_Stop(void)
{
    CLR_IIC_SDA();
    Delay_us(10);
    SET_IIC_SCL();
    Delay_us(10);
    SET_IIC_SDA();
}

5.0 IIC发送一个字节


cpp 复制代码
void IIC_SendByte(uint8_t byte)
{
    for (uint8_t i = 0; i < ONE_BYTE_NUM; i++)
    {
        if  (byte & 0x80) 
        {
            SET_IIC_SDA();
        }
        else
        {
            CLR_IIC_SDA();
        }

        byte <<= 1;
        Delay_us(10);
        SET_IIC_SCL();
        Delay_us(10);
        CLR_IIC_SCL();
        Delay_us(10);
    }
}

6.0 IIC接收一个字节


cpp 复制代码
uint8_t IIC_ReceiveByte(void)
{
    uint8_t byte = 0x00;
    SET_IIC_SDA(); // 释放SDA
    for (uint8_t i = 0; i < ONE_BYTE_NUM; i++)
    {
        SET_IIC_SCL();
        Delay_us(10);
        byte <<= 1;

        if (GET_IIC_SDA())
        {
            byte++;
        }
        CLR_IIC_SCL();
        Delay_us(10);
    }
    return byte;
}

7.0 IIC接收应答


cpp 复制代码
// IIC 接收应答
bool IIC_Wait_Ack(void)
{
    uint8_t errTime = 0;
    SET_IIC_SDA();
    Delay_us(10);

    SET_IIC_SCL();
    Delay_us(10);

    while (GET_IIC_SDA())
    {
        errTime++;

        if (errTime > 250)
        {
            IIC_Stop();
            return false;
        }
    }
    CLR_IIC_SCL();
    Delay_us(5);

    return true;
}

8.0 IIC发送应答


cpp 复制代码
// IIC 发送应答
void IIC_SendAck(void)
{
    CLR_IIC_SDA();
    Delay_us(10);
    SET_IIC_SCL();
    Delay_us(10);
    CLR_IIC_SCL();
    Delay_us(10);
    SET_IIC_SDA();
}

9.0 IIC 发送非应答


cpp 复制代码
// IIC 发送非应答
void IIC_SendNoAck(void)
{
    SET_IIC_SDA();
    Delay_us(5);
    SET_IIC_SCL();
    Delay_us(5);
    CLR_IIC_SCL();
    Delay_us(5);
}

10.0完整程序


cpp 复制代码
#include "stm32f10x.h"
#include <stdint.h>
#include "stdbool.h"

#define GET_IIC_SDA() GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9)
#define SET_IIC_SCL() GPIO_SetBits(GPIOB, GPIO_Pin_8)
#define CLR_IIC_SCL() GPIO_ResetBits(GPIOB, GPIO_Pin_8) 
#define SET_IIC_SDA() GPIO_SetBits(GPIOB, GPIO_Pin_9)   
#define CLR_IIC_SDA() GPIO_ResetBits(GPIOB, GPIO_Pin_9)

#define ONE_BYTE_NUM (8)

void IIC_Init(void)
{
    /*开启时钟*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 开启GPIOB的时钟

    /*GPIO初始化*/
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure); // 将PB10和PB11引脚初始化为开漏输出

    /*设置默认电平*/
    GPIO_SetBits(GPIOB, GPIO_Pin_8 | GPIO_Pin_9); // 设置PB8和PB9引脚初始化后默认为高电平(释放总线状态)
}

void IIC_Start(void)
{
    SET_IIC_SDA();
    SET_IIC_SCL();
    Delay_us(10);
    CLR_IIC_SDA();
    Delay_us(10);
    CLR_IIC_SCL();
}

void IIC_Stop(void)
{
    CLR_IIC_SDA();
    Delay_us(10);
    SET_IIC_SCL();
    Delay_us(10);
    SET_IIC_SDA();
}

void IIC_SendByte(uint8_t byte)
{
    for (uint8_t i = 0; i < ONE_BYTE_NUM; i++)
    {
        if  (byte & 0x80) 
        {
            SET_IIC_SDA();
        }
        else
        {
            CLR_IIC_SDA();
        }

        byte <<= 1;
        Delay_us(10);
        SET_IIC_SCL();
        Delay_us(10);
        CLR_IIC_SCL();
        Delay_us(10);
    }
}

uint8_t IIC_ReceiveByte(void)
{
    uint8_t byte = 0x00;
    SET_IIC_SDA(); // 释放SDA
    for (uint8_t i = 0; i < ONE_BYTE_NUM; i++)
    {
        SET_IIC_SCL();
        Delay_us(10);
        byte <<= 1;

        if (GET_IIC_SDA())
        {
            byte++;
        }
        CLR_IIC_SCL();
        Delay_us(10);
    }
    return byte;
}

// IIC 接收应答
bool IIC_Wait_Ack(void)
{
    uint8_t errTime = 0;
    SET_IIC_SDA();
    Delay_us(10);

    SET_IIC_SCL();
    Delay_us(10);

    while (GET_IIC_SDA())
    {
        errTime++;

        if (errTime > 250)
        {
            IIC_Stop();
            return false;
        }
    }
    CLR_IIC_SCL();
    Delay_us(5);

    return true;
}

// IIC 发送应答
void IIC_SendAck(void)
{
    CLR_IIC_SDA();
    Delay_us(10);
    SET_IIC_SCL();
    Delay_us(10);
    CLR_IIC_SCL();
    Delay_us(10);
    SET_IIC_SDA();
}

// IIC 发送非应答
void IIC_SendNoAck(void)
{
    SET_IIC_SDA();
    Delay_us(5);
    SET_IIC_SCL();
    Delay_us(5);
    CLR_IIC_SCL();
    Delay_us(5);
}

......

相关推荐
v先v关v住v获v取1 小时前
草莓采摘机器人结构设计2张cad+设计说明书+三维图
科技·单片机·51单片机
沐风听雨_A1 小时前
海康IP摄像头激活与配置笔记
笔记·嵌入式硬件
liujing102329291 小时前
stm32 开发的 c_cpp_properties.json 配置
c语言·stm32·嵌入式硬件
一支闲人1 小时前
单片机学习的前提知识储备
单片机·基础知识
d111111111d1 小时前
STM32平衡车工具-匿名助手+虚拟串口如何使用。
笔记·stm32·单片机·嵌入式硬件·学习
xingzhemengyou11 小时前
STM32 Cortex-M3和Cortex-M4内核差异
stm32
电化学仪器白超2 小时前
20251209Ver8调试记录(补充电路板编号8-3)
python·单片机·嵌入式硬件·自动化
Lester_11012 小时前
单片机 IAP(可实现OTA), ISP, ICP
单片机·嵌入式硬件·iap·ota
恶魔泡泡糖2 小时前
51单片机蜂鸣器应用
单片机·嵌入式硬件·51单片机