STM32Cube MX 下IIC的配置与使用--GPIO模拟

发布者:创意梦者最新更新时间:2019-07-09 来源: eefocus关键字:STM32Cube  MX  IIC  GPIO模拟 手机看文章 扫描二维码
随时随地手机看文章

本文介绍了在STM32下的IIC的基本使用方法,通过对板载具备IIC接口EEPROM的读写,完成对IIC驱动程序的测试。


硬件平台:STM32F107VCT6开发板


软件平台:STM32Cube MX + MDK5.22


1. 进行STM32Cube MX的配置



配置PB6和PB7为输出模式,同时配置了USART1进行串口调试使用。然后生成工程。




2. 打开工程,可以看到GPIO的初始化状态



3. 模拟IIC驱动程序源文件代码


/**

  * @file  iic_dup.c

  * @brief IIC上层程序

  * @par   date        version    author    remarks

  *        2016-03-21  v1.0       zbt       初次创建

  *

  */

 

/** 头文件包含区 ------------------------------------------------ */

#include "iic_dup.h"

 

/** 私有宏(类型定义) -------------------------------------------- */ 

#define IIC1_SCL(pin_status)        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, pin_status);

#define IIC1_SDA(pin_status)        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, pin_status);

#define IIC1_SCL_IS_HIGH()          (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) != GPIO_PIN_RESET)

#define IIC1_SDA_IS_HIGH()          (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) != GPIO_PIN_RESET)

 

/** 私有变量 --------------------------------------------------- */

 

 

/** 外部变量 --------------------------------------------------- */

 

/** 私有函数原型 ----------------------------------------------- */

static void iic_delay(void);

 

/** 公有函数 --------------------------------------------------- */

/**

  * @brief  IIC启动

  * @param  None

  * @retval None

  * @note   当SCL处于高电平状态时,SDA出现一个下降沿

            即产生IIC启动信号

  */

void iic_start(void)

{

    IIC1_SCL(GPIO_PIN_SET);

    /** SDA产生一个下降沿 */

    IIC1_SDA(GPIO_PIN_SET);

    iic_delay(); 

    

    IIC1_SDA(GPIO_PIN_RESET);

    iic_delay(); 

    IIC1_SCL(GPIO_PIN_RESET);   /**< 拉低准备发送数据 */

    iic_delay();   

}

 

/**

  * @brief  IIC停止

  * @param  None

  * @retval None

  * @note   当SCL处于高电平状态时,SDA出现一个上升沿

            即产生IIC停止信号

  */

void iic_stop(void)

{

    IIC1_SCL(GPIO_PIN_RESET);

    iic_delay();

    /** SDA产生一个上升沿 */

    IIC1_SDA(GPIO_PIN_RESET);

    iic_delay();

    

    IIC1_SCL(GPIO_PIN_SET);

    iic_delay();

    IIC1_SDA(GPIO_PIN_SET);

    iic_delay();

}

 

/**

  * @brief  IIC发送1byte数据

  * @param  None

  * @retval None

  * @note   

  */

void iic_sendbyte(uint8_t byte)

{

    uint8_t i;

    

    /** 发送一个字节的高7位 */

    for (i = 0; i < 8; i++)

    {

        if (byte & 0x80)

        {

            IIC1_SDA(GPIO_PIN_SET);

        }

        else

        {

            IIC1_SDA(GPIO_PIN_RESET);

        }

        

        iic_delay();

        IIC1_SCL(GPIO_PIN_SET);

        iic_delay();

        IIC1_SCL(GPIO_PIN_RESET);

        

        if (i == 7)

        {

            IIC1_SDA(GPIO_PIN_SET);

        }

        

        byte <<= 1;

        iic_delay();

    }      

}

 

/**

  * @brief  IIC读取1byte数据

  * @param  None

  * @retval None

  * @note             

  */

uint8_t iic_readbyte(void)

{

    uint8_t i;

    uint8_t recv_value = 0;

    

    IIC1_SDA(GPIO_PIN_SET);

    iic_delay();

    

    for (i = 0; i < 8; i++)

    {

        IIC1_SCL(GPIO_PIN_SET);

        iic_delay();

        recv_value <<= 1;

        if (IIC1_SDA_IS_HIGH())

        {

            recv_value |= 0x01;

        }

        else

        {

            recv_value &= ~0x01;

        }

        

        iic_delay();

        IIC1_SCL(GPIO_PIN_RESET);

    }

    

    return recv_value;

}

 

/**

  * @brief  IIC等待应答信号

  * @param  None

  * @retval ack_status: 应答状态,0表示应答,1表示设备无响应

  */

uint8_t iic_wait_ack(void)

{

    uint8_t ack_status = 0;

    

    /** 在等待应答信号之前,要释放总线,即将SDA置位 */

    IIC1_SDA(GPIO_PIN_SET);

    iic_delay();

    IIC1_SCL(GPIO_PIN_SET);

    iic_delay();

    

    if (IIC1_SDA_IS_HIGH())

    {    

        ack_status = 1;

        iic_stop();

    }

    else

    {

        ack_status = 0;

    }

    

    IIC1_SCL(GPIO_PIN_RESET);

    iic_delay();

    

    return ack_status;

}

 

/**

  * @brief  主机(主控制器)产生应答信号

  * @param  None

  * @retval None

  */

void iic_ack(void)

{

    IIC1_SDA(GPIO_PIN_RESET);

    iic_delay();

    

    IIC1_SCL(GPIO_PIN_SET);

    iic_delay();

    IIC1_SCL(GPIO_PIN_RESET);

    iic_delay();

    

    IIC1_SDA(GPIO_PIN_SET);

}

 

/**

  * @brief  主机(主控制器)产生不应答信号

  * @param  None

  * @retval None

  */

void iic_nack(void)

{

    IIC1_SDA(GPIO_PIN_SET);

    iic_delay();

    

    IIC1_SCL(GPIO_PIN_SET);

    iic_delay();

    IIC1_SCL(GPIO_PIN_RESET);

    iic_delay();

}

 

/**

  * @brief  检测IIC总线上的设备状态

  * @param  device_addr: 从机设备地址 

  * @retval ack_status: 0 (正常)or 1(异常)

  * @note   主机发送设备地址等待从机应答,若有从机正确的应答信号

            则表明IIC总线上挂接了设备,否则表示IIC总线上未检测到

            设备

  */

uint8_t iic_check_device_status(uint8_t device_addr)

{

    uint8_t ack_status;

    

    if (IIC1_SCL_IS_HIGH() && IIC1_SDA_IS_HIGH())

    {

        iic_start();

        

        iic_sendbyte(device_addr | IIC_WRITE);

        ack_status = iic_wait_ack();

 

        iic_stop();

        

        return ack_status;

    }

    

    return 1;

}

 

/** 私有函数 --------------------------------------------------- */

/**

  * @brief  用于模拟IIC时的简单延时

  * @param  None

  * @retval None

  */

static void iic_delay(void)

{

    uint8_t i = 0;

    uint8_t delay = 5;

    

    while (delay--)

    {

        i = 10;

        while (i--);

    }

}


4. AT24C02部分驱动代码


/**

  * @file  at24c02.c

  * @brief at24c02驱动程序

  * @par   date        version    author    remarks

  *        2016-03-21  v1.0       zbt       初次创建

  *

  */

 

/** 头文件包含区 ------------------------------------------------ */

#include "at24c02.h"

#include "iic_dup.h"

 

/** 私有宏(类型定义) -------------------------------------------- */ 

#define AT24C02_DEVICE_ADDR         0xA0

#define AT24C02_PAGE_SIZE           8

#define AT24C02_MEM_SIZE            256

#define AT24C02_ADDR_BYTE           1

 

/** 私有变量 --------------------------------------------------- */

uint8_t test_buffer[AT24C02_MEM_SIZE];

 

/** 外部变量 --------------------------------------------------- */

 

/** 私有函数原型 ----------------------------------------------- */

//static void AT24C02_ack(void);

static void AT24C02_error_handle(void);

static void AT24C02_read_test(void);

static void AT24C02_write_test(void);

static void AT24C02_erase_test(void);

 

/** 公有函数 --------------------------------------------------- */

/**

  * @brief  AT24C02与主控制器的IIC通讯测试代码

  * @param  None

  * @retval None

  */

void AT24C02_iic_test(void)

{

    iic_stop();     /**< 必须先复位IIC总线上的设备到待机模式 */

    HAL_Delay(10);

    

    /** 检测总线上是否挂接了IIC设备(此处为AT24C02) */

    if (iic_check_device_status(AT24C02_DEVICE_ADDR) == 0)

    {

        printf("iic device existsn");

    }

    else

    {

        printf("no iic device existsn");

    }

    

    AT24C02_write_test();

    HAL_Delay(5);

    AT24C02_read_test();

    HAL_Delay(5);

    AT24C02_erase_test();

}

 

/**

  * @brief  从AT24C02中读取数据

  * @param  read_data: 读取到的数据

  * @param  start_addr: 读取数据的起始地址

  * @param  data_length: 数据的长度

  * @retval None

  */

void AT24C02_read_data(uint8_t *read_data, uint16_t start_addr, uint16_t data_length)

{

    uint16_t i;

    

    iic_start();

    iic_sendbyte(AT24C02_DEVICE_ADDR | IIC_WRITE);

//    AT24C02_ack();

[1] [2]
关键字:STM32Cube  MX  IIC  GPIO模拟 引用地址:STM32Cube MX 下IIC的配置与使用--GPIO模拟

上一篇:使用STM32hal库usart的接收中断分析及出现部分问题的解决
下一篇:基于HAL库 Stm32虚拟IIC总线

推荐阅读最新更新时间:2024-11-06 05:20

ZDS2022示波器百集实操特辑之32:如何用示波器对IIC解码?
IIC作为一种常用协议,ZDS2022示波器考虑到用户的需求,毅然决然地加入了完全开放的IIC触发与解码功能!那如何进行操作呢? 按下【Decode】键,将解码类型设置为IIC协议,将协议触发设为ON,由于在自动触发模式下,波形显示会不稳定。按下面板上的【Auto/Normal】键,将触发方式切换为普通触发,打开协议参数,可进行总线和触发设置。 触发模式包括3种模式:起始位、结束位和地址值,我们选中地址值,设置触发地址为0×50,写模式,响应类型设为ACK,将时基调大,仔细观察触发位置,此时由于没有识别到完整帧使协议无效解码,可通过按下【Horiz】键,将储存深度设为56Mpts,增大存储深度,即可有效解码,从屏幕协议可清
[测试测量]
ZDS2022示波器百集实操特辑之32:如何用示波器对<font color='red'>IIC</font>解码?
stm32专题十六:IIC(三)stm32 IIC 固件库函数分析
因为I2C通讯非常重要,因此要详细的分析每一个库函数 IIC初始化结构体 /** * @brief I2C Init structure definition */ typedef struct { // 指定时钟频率,这个值不能超过400kHz uint32_t I2C_ClockSpeed; /*! Specifies the clock frequency. This parameter must be set to a value lower than 400kHz */ // IIC模式:可以有3种选择:I2C_Mode_I2C I2C_Mo
[单片机]
stm32专题十六:<font color='red'>IIC</font>(三)stm32 <font color='red'>IIC</font> 固件库函数分析
IIC专题(二)——STM32驱动AT24C02
1.概述 MiniSTM32 开发板板载的 EEPROM 芯片型号为 24C02。该芯片的总容量是 256个字节,该芯片通过 IIC 总线与外部连接。这里直接采用原子板上的 AT24C02 ,主要是软件编程方面的学习。 2.硬件连接 A2、A1、A0 三个引脚直接接地。供电: (VCC = 2.7V to 5.5V) 器件地址设置: 对于AT24C02:Addr— 0xA0(写)/ 0xA1(读)。 单字节写入: 按页写入: 从当前地址读出数据; 随机读取: 顺序读出: 3.例程分析 (一)IIC 部分实现代码 包括 IIC 的初始化(I
[单片机]
<font color='red'>IIC</font>专题(二)——STM32驱动AT24C02
飞思卡尔i.MX 6SoloX将应用处理器的安全性提升到全新水平
异构多核i.MX 6SoloX将世界一流的安全性和卓越性能与效率完美结合,现在可批量供货 飞思卡尔半导体(NYSE:FSL)日前宣布i.MX 6SoloX现在可批量供货,i.MX 6SoloX是高度集成、面向多个市场的应用处理器,支持安全互联家庭、物联网和车联网应用。 i.MX 6SoloX的一大特点是其强大的安全性。该SoC包含加密密码引擎和可配置的资源域控制器,支持CPU内核锁定或共享外设。安全的消息信号装置可增大域控制器信号,使合作式、多操作系统的软件能够安全接入共用的外设。该处理器还具有耐用的物理安全性,包括先进的安全启动和受保护的数据存储。借助这些先进的硬件功能,用户可以基于独特的市场需求设计定制安全解决方
[嵌入式]
纯黑色可开启背壳 魅族MX4真机谍照曝光
    昨日,有微博网友爆出了魅族MX4的真机照片,随着9月2日魅族MX4发布会的日益临近,目前关于魅族新一代旗舰的信息也是遍布网络。从此次曝光的照片中MX4与之前曝光基本一致,也初步可以认定MX4的真容为何样了。 图片来源于网络 图片来源于网络   从曝光照片中我们不难看出,此次曝光的MX4为黑色版本,同时在底部Micro USB接口旁边我们可以看到一个开启后盖的开口,所以基本可以确定MX4将不再采用卡针开启后盖的方式。同时机身的背部被打磨的十分平整。另外纯黑色的背 面似乎也宣示着魅族将要告别做熊猫机的时代了。9月2日魅族MX4发布会将要在北京召开,届时关于MX4所有的传闻都将一一被揭开。就让我们拭目以待吧。
[手机便携]
魅族MX将采用4核处理器 效果图曝光
    魅族官方论坛消息,J.Wong在销声匿迹将近一个月之后又放出了重磅消息。根据J.Wong最新帖子显示,魅族下一款手机MX将会在今年9月底发布,支持换壳,其中16GB版本为双核处理器,32GB版本则直接用上四核处理器。     魅族并未透露具体的处理器型号,从目前各家移动处理器厂商的路线图来看,魅族使用Tegra 2和Tegra 3的可能性较大,其中Tegra 2方案已经非常成熟,Tegra 3也是呼声最高的四核处理器。当然采用高通方案也不是没有可能,如果你相信魅族真的用的是四个核心的处理器而不是什么伪四核。     另外还需要注意发布时间,如果真的是9月份,将会有两种情况:首先是16GB版本和32GB版本一起发布,
[手机便携]
MSP430F5529硬件IIC驱动IIC接口的OLED
//****************************************************************************** // MSP430F552x Demo - USCI_B0, I2C Master multiple byte TX/RX // // Description: I2C master communicates to I2C slave sending and receiving // 3 different messages of different length. I2C master will enter LPM0 mode // while waiting
[单片机]
GPIO模拟I2C-1
GPIO模拟I2C是嵌入式中较为常用的一种应用。各个地方有各种不同的做法,按照我自己的个人理解,最好是把I2C的各种状态分割开来,比如起始条件终止条件,读数据和写数据,然后根据具体的使用场合组合起来。 这里需要注意两点:一是SCL的波形并不规律,不能将它理解为方波,它本身只是一段段独立的波形。二是每段操作时,之前和之后的SCL和SDA波形是可以不用计较的;通常情况下I2C开始之前和I2C结束之后,两者都是高电平,而在正常工作时两者不受控制的情况下都是默认低电平。 (1)基础宏定义 #define GPIO_SCL S3C2410_GPF3 #define GPIO_SDA S3C2
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved