STM32 IIC开发学习

1IIC总线时序图

在这里插入图片描述
① 起始信号
当 SCL 为高电平期间,SDA 由高到低的跳变。起始信号是一种电平跳变时序信号,而不是
一个电平信号。该信号由主机发出,在起始信号产生后,总线就会处于被占用状态,准备数据
传输。
② 停止信号
当 SCL 为高电平期间,SDA 由低到高的跳变。停止信号也是一种电平跳变时序信号,而不
是一个电平信号。该信号由主机发出,在停止信号发出后,总线就会处于空闲状态。
③ 应答信号
发送器每发送一个字节,就在时钟脉冲 9 期间释放数据线,由接收器反馈一个应答信号。
应答信号为低电平时,规定为有效应答位(ACK 简称应答位),表示接收器已经成功地接收了
该字节。应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成
功。
观察上图标号③就可以发现,有效应答的要求是从机在第 9 个时钟脉冲之前的低电平期间
将 SDA 线拉低,并且确保在该时钟的高电平期间为稳定的低电平。如果接收器是主机,则在它
收到最后一个字节后,发送一个 NACK 信号,以通知被控发送器结束数据发送,并释放 SDA
线,以便主机接收器发送一个停止信号。
④ 数据有效性
IIC 总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在
时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。数据在 SCL 的上
升沿到来之前就需准备好。并在下降沿到来之前必须稳定。
⑤ 数据传输
在 IIC 总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在 SCL 串行
时钟的配合下,在 SDA 上逐位地串行传送每一位数据。数据位的传输是边沿触发。
⑥ 空闲状态
IIC 总线的 SDA 和 SCL 两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个
器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉
高。

IIC写操作

下面介绍一下 IIC 的基本的读写通讯过程,包括主机写数据到从机即写
操作,主机到从机读取数据即读操作。
在这里插入图片描述
主机首先在 IIC 总线上发送起始信号,那么这时总线上的从机都会等待接收由主机发出的
数据。主机接着发送从机地址+0(写操作)组成的 8bit 数据,所有从机接收到该 8bit 数据后,自
行检验是否是自己的设备的地址,假如是自己的设备地址,那么从机就会发出应答信号。主机
在总线上接收到有应答信号后,才能继续向从机发送数据。注意:IIC 总线上传送的数据信号是广义的,既包括地址信号,又包括真正的数据信号。

IIC读操作

在这里插入图片描述

主机向从机读取数据的操作,一开始的操作与写操作有点相似,观察两个图也可以发现,
都是由主机发出起始信号,接着发送从机地址+1(读操作)组成的 8bit 数据,从机接收到数据验
证是否是自身的地址。 那么在验证是自己的设备地址后,从机就会发出应答信号,并向主机返
回 8bit 数据,发送完之后从机就会等待主机的应答信号。假如主机一直返回应答信号,那么从
机可以一直发送数据,也就是图中的(n byte + 应答信号)情况,直到主机发出非应答信号,从
机才会停止发送数据。

STM32 完成IIC的各个阶段的c代码

myiic.h

#ifndef _MYIIC_H
#define _MYIIC_H

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"

/****************************************************************************************************/
/* 引脚 定义 */

#define IIC_SCL_GPIO_PORT               GPIOB
#define IIC_SCL_GPIO_PIN                GPIO_PIN_10
#define IIC_SCL_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* PB口时钟使能 */

#define IIC_SDA_GPIO_PORT               GPIOB
#define IIC_SDA_GPIO_PIN                GPIO_PIN_3
#define IIC_SDA_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* PB口时钟使能 */

/****************************************************************************************************/

/*IO 高低电平*/


#define IIC_SCL(x) do{x ? \
                     HAL_GPIO_WritePin(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN, GPIO_PIN_SET) : \
                     HAL_GPIO_WritePin(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN, GPIO_PIN_RESET); \
                     }while(0)  /* SCL */

#define IIC_SDA(x) do{x ? \
                     HAL_GPIO_WritePin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, GPIO_PIN_SET) : \
                     HAL_GPIO_WritePin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, GPIO_PIN_RESET); \
                     }while(0)  /* SDA */                     

#define IIC_READ_SDA  HAL_GPIO_ReadPin(IIC_SDA_GPIO_PORT,IIC_SDA_GPIO_PIN) /* 读取SDA */
                     
                     
void iic_start(void);
void iic_stop(void);
static void iic_delay(void);
uint8_t iic_wait_ack(void);
void iic_ack(void);
void iic_nack(void);
void iic_send_byte(uint8_t data);
uint8_t iic_read_byte(uint8_t ack);

#endif

myiic.c

#include "myiic.h"

/**
 * @brief       初始化IIC 初始化GPIO
 * @param       无
 * @retval      无
 */
 
 void iic_init(void)
 {
    GPIO_InitTypeDef gpio_init_struct;

    IIC_SCL_GPIO_CLK_ENABLE();                          /* SCL引脚时钟使能 */
    IIC_SDA_GPIO_CLK_ENABLE();                          /* SDA引脚时钟使能 */

    gpio_init_struct.Pin = IIC_SCL_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;        /* 推挽输出 */
    gpio_init_struct.Pull = GPIO_PULLUP;                /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; /* 快速 */
    HAL_GPIO_Init(IIC_SCL_GPIO_PORT, &gpio_init_struct);/* SCL */

    gpio_init_struct.Pin = IIC_SDA_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD;        /* 推挽输出 */
    HAL_GPIO_Init(IIC_SDA_GPIO_PORT, &gpio_init_struct);/* SDA */
    /* SDA引脚模式设置,开漏输出,上拉, 这样就不用再设置IO方向了, 开漏输出的时候(=1), 也可以读取外部信号的高低电平 */

    iic_stop(); 
 }
 
 
 /**
 * @brief       IIC延时函数,用于控制IIC读写速度
 * @param       无
 * @retval      无
 */
 
static void iic_delay(void)
{
    delay_us(2);
}    

/**
 * @brief       产生IIC起始信号
 * @param       无
 * @retval      无
 */

void iic_start(void)
{
    IIC_SCL(1);
    IIC_SDA(1);
    iic_delay();
    IIC_SDA(0);     /* START信号: 当SCL为高时, SDA从高变成低, 表示起始信号 */
    iic_delay();
    IIC_SCL(0);     /* 钳住I2C总线,准备发送或接收数据 */
    iic_delay();
}

/**
 * @brief       产生IIC停止信号
 * @param       无
 * @retval      无
 */
void iic_stop(void)
{
    IIC_SDA(0);
    iic_delay();
    IIC_SCL(1); /* STOP信号: 当SCL为高时, SDA从低变成高, 表示停止信号 */
    iic_delay();
    IIC_SDA(1);
    iic_delay();
}

/**
 * @brief       等待应答信号到来
 * @param       无
 * @retval      1,接收应答失败
 *              0,接收应答成功
 */

uint8_t iic_wait_ack(void)
{
    uint8_t waittime =0;
    uint8_t rack =0;
    
    IIC_SDA(1);     /* 主机释放SDA线(此时外部器件可以拉低SDA线) */
    iic_delay();
    IIC_SCL(1);     /* SCL=1, 此时从机可以返回ACK */
    iic_delay();
    
    while(IIC_READ_SDA) /* 等待应答 */
    {
        waittime++;
        if(waittime>250)
        {
          iic_stop();
          rack=1;
          break;
        }
    }
    IIC_SCL(0);     /* SCL=0, 结束ACK检查 */
    iic_delay();
    return rack;
}

/**
 * @brief       产生ACK应答
 * @param       无
 * @retval      无
 */


void iic_ack(void)
{
   /* SCL 0 -> 1  时 SDA = 0,表示应答 */
   IIC_SDA(0);
   iic_delay();
   IIC_SCL(1);
   iic_delay();
   IIC_SCL(0);
   iic_delay();
   IIC_SDA(1);     /* 主机释放SDA线 */
   iic_delay();
}


/**
 * @brief       不产生ACK应答
 * @param       无
 * @retval      无
 */

void iic_nack(void)
{
   /* SCL 0 -> 1  时 SDA = 1,表示非应答 */
   IIC_SDA(1);
   iic_delay();
   IIC_SCL(1);
   iic_delay();
   IIC_SCL(0);
   iic_delay();

}

/**
 * @brief       IIC发送一个字节
 * @param       data: 要发送的数据
 * @retval      无
 */

void iic_send_byte(uint8_t data)
{
    uint8_t i;
    for(i=0;i<8;i++)
    {
      IIC_SDA((data&0x80)>>7);  /* 高位先发送 */
      iic_delay();
      IIC_SCL(1);
      iic_delay();
      IIC_SCL(0);
      data<<=1; /* 左移1位,用于下一次发送 */
    }
    IIC_SDA(1);/* 发送完成, 主机释放SDA线 */

}

/**
 * @brief       IIC读取一个字节
 * @param       ack:  ack=1时,发送ack; ack=0时,发送nack
 * @retval      接收到的数据
 */

uint8_t iic_read_byte(uint8_t ack)
{
    uint8_t i;
    uint8_t rec=0;
    for(i=0;i<8;i++) /* 接收1个字节数据 */
    {
        rec<<=1; /* 高位先输出,所以先收到的数据位要左移 */
        IIC_SCL(1);
        iic_delay();
        
        if(IIC_READ_SDA)
        {
          rec++;
        }
        IIC_SCL(0);
        iic_delay();
    }
    if(!ack)
    {
      iic_nack();
    }
    else
    {
      iic_ack();
    }
    
    return rec;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/274701.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ios环境搭建_xcode安装及运行源码

目录 1 xcode 介绍 2 xcode 下载 3 xocde 运行ios源码 1 xcode 介绍 Xcode 是运行在操作系统Mac OS X上的集成开发工具&#xff08;IDE&#xff09;&#xff0c;由Apple Inc开发。Xcode是开发 macOS 和 iOS 应用程序的最快捷的方式。Xcode 具有统一的用户界面设计&#xff0…

矿泉水硝酸盐和溴酸盐超标解决工艺

在当今社会&#xff0c;人们对健康和优质生活的追求不断提升&#xff0c;使得瓶装饮用水的安全问题受到了广泛关注。溴酸盐和硝酸盐作为自然水体中常见的物质&#xff0c;若在矿泉水中含量过高&#xff0c;可能会对消费者的健康构成潜在威胁。因此&#xff0c;探究有效去除矿泉…

【OpenCV】告别人工目检:深度学习技术引领工业品缺陷检测新时代

目录 前言 机器视觉 缺陷检测 工业上常见缺陷检测方法 内容简介 作者简介 目录 读者对象 如何阅读本书 获取方式 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站 机器视觉…

WPF项目创建HTTP WEB服务,不使用IIS业务 WPF桌面程序WebApi WPF 集成WebApi C# 创建HTTP Web API服务

在C# WPF应用程序中直接创建HTTP服务或WebAPI服务有以下优点&#xff1a; 自托管服务&#xff1a; 简化部署&#xff1a;无需依赖外部服务器或IIS&#xff08;Internet Information Services&#xff09;&#xff0c;可以直接在应用程序内部启动和运行Web服务。 集成紧密&…

如何在无公网IP环境使用Windows远程桌面Ubuntu

文章目录 一、 同个局域网内远程桌面Ubuntu二、使用Windows远程桌面连接三、公网环境系统远程桌面Ubuntu1. 注册cpolar账号并安装2. 创建隧道&#xff0c;映射3389端口3. Windows远程桌面Ubuntu 四、 配置固定公网地址远程Ubuntu1. 保留固定TCP地址2. 配置固定的TCP地址3. 使用…

「Kafka」入门篇

「Kafka」入门篇 基础架构 Kafka 快速入门 集群规划 集群部署 官方下载地址&#xff1a;http://kafka.apache.org/downloads.html 解压安装包&#xff1a; [atguiguhadoop102 software]$ tar -zxvf kafka_2.12-3.0.0.tgz -C /opt/module/修改解压后的文件名称&#xff1a; [a…

深入浅出:分布式、CAP 和 BASE 理论(荣耀典藏版)

大家好&#xff0c;我是月夜枫&#xff0c;一个漂泊江湖多年的 985 非科班程序员&#xff0c;曾混迹于国企、互联网大厂和创业公司的后台开发攻城狮。 在计算机科学领域&#xff0c;分布式系统是一门极具挑战性的研究方向&#xff0c;也是互联网应用中必不可少的优化实践&…

网站显示不安全警告怎么办?消除网站不安全警告超全指南

网站显示不安全警告怎么办&#xff1f;当用户访问你的网站&#xff0c;而您的网站没有部署SSL证书实现HTTPS加密时&#xff0c;网站就会显示不安全警告&#xff0c;这种警告&#xff0c;不仅有可能阻止用户继续浏览网站&#xff0c;影响网站声誉&#xff0c;还有可能影响网站在…

easycython和cython将py编译为pyd对比

前提了解 为了实验的准确性&#xff0c;在全过程使用的python环境版本都为同一版本 easycython和cython编译为pyd文件的不同在于&#xff0c;easycython编译的原始文件后缀为pyx&#xff0c;cython编译的原始文件为py 1.cython 1.1原始文件 def ZWHCythonTest():print(&qu…

中职网络安全Server2002——Web隐藏信息获取

B-2&#xff1a;Web隐藏信息获取 任务环境说明&#xff1a; 服务器场景名&#xff1a;Server2002&#xff08;关闭链接&#xff09;服务器场景用户名&#xff1a;未知 有问题需要环境加q 通过本地PC中渗透测试平台Kali使用Nmap扫描目标靶机HTTP服务子目录&#xff0c;将扫描子…

【15.5K⭐】QuickLook—文件快速预览工具

【15.5K⭐】QuickLook—文件快速预览工具 在我们日常的工作和生活中&#xff0c;经常会遇到需要快速查看不同类型文件内容的情况。这可能包括文档、图片、视频、音频甚至是代码文件。在这种情况下&#xff0c;为了省去了打开文件或应用等繁琐步骤&#xff0c;一款高效的文件预…

JAVA语言—AOP基础

1、AOP概述 AOP&#xff1a;AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff0c;即面向切面编程&#xff0c;可以说是OOP&#xff08;Object Oriented Programming&#xff0c;面向对象编程&#xff09;的补充和完善。 场景&#xff1a;案例部分功能运行较慢&…

Springboot+vue的医疗报销系统(有报告),Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的医疗报销系统&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的医疗报销系统&#xff0c;采用M&#xff08;model&a…

Windows/Linux环境登入mysql、mysqldump命令等多方式解决方案之简易记录

Windows/Linux环境登入mysql、mysqldump命令等多方式解决方案之简易记录 之前发布过Window方式,这次结合以上主题,完善下Linux相关登入方式过程,纯属做个记录,有需要的朋友可以做个学习参考。 一、Windows环境提示“‘mysql’ 不是内部或外部命令,也不是可运行的程序或批…

Flask 账号管理列表

Flask 账号管理列表 web/controllers/account/Account.py /index route_account Blueprint( account_page,__name__ )route_account.route( "/index" ) def index():resp_data {}req request.valuespage int( req[p] ) if ( p in req and req[p] ) else 1qu…

详细讲解Java使用EasyExcel函数来操作Excel表(附实战)

目录 前言1. EasyExcel类2. 原理分析3. demo4. 实战 前言 前阵时间好奇下载Excel&#xff0c;特意学习实战了该功能&#xff1a;详细讲解Java使用HSSFWorkbook函数导出Excel表&#xff08;附实战&#xff09; 现在发觉还有个EasyExcel也可专门用来读写Excel表 1. EasyExcel类…

vue3+luckyexcel+php在线编辑excel文件

开发过程中&#xff0c;需要开发一个在线编辑excel文档的功能&#xff0c;找到了这个合适的组件 Luckysheet &#xff0c;一款纯前端类似excel的在线表格&#xff0c;功能强大、配置简单、完全开源。 可以导入文档&#xff0c;预览、编辑、保存、导出等功能&#xff0c;可以满…

关于“Python”的核心知识点整理大全45

目录 15.4.6 绘制直方图 die_visual.py 注意 15.4.7 同时掷两个骰子 dice_visual.py 15.4.8 同时掷两个面数不同的骰子 different_dice.py 15.5 小结 第 16 章 16.1 CSV 文件格式 16.1.1 分析 CSV 文件头 highs_lows.py 注意 16.1.2 打印文件头及其位置 highs_l…

电影“AI化”已成定局,华为、小米转战入局又将带来什么?

从华为、Pika、小米等联合打造电影工业化实验室、到Pika爆火&#xff0c;再到国内首部AI全流程制作《愚公移山》开机……业内频繁的新动态似乎都在预示着2023年国内电影开始加速进入新的制片阶段&#xff0c;国内AI电影热潮即将来袭。 此时以华为为首的底层技术科技企业加入赛…

OCP NVME SSD规范解读-2.复位与控制器配置要求-part2

Maximum Data Transfer Size (MDTS)&#xff1a;设备应支持至少256KB的最大数据传输大小。 CSTS.CFS Reporting: 设备固件应支持报告CSTS.CFS&#xff08;Controller Status and Capabilities Field in the Status Register&#xff09;。 Queue Depths: 每个提交队列的SQ最小…