【GD32】08 - IIC(以SHT20为例)

GD32中的IIC

今天来了解一下GD32中的硬件IIC,其实我个人是觉得软件IIC比较方便的,不过之前文章里用的都是软件IIC,今天就算是走出自己的舒适圈,我们来了解了解GD32中的硬件IIC。

我这里用的型号是GD32F407,不同型号的只需要看准自己板子的资源引脚即可。

关于IIC以及本文中演示的SHT20,在之前的文章里都有,并且也不是本文的重点,因此这里就不介绍了,不了解且感兴趣的小伙伴可以去看看之前的文章。

【STM32F103】I2C通信协议&SHT20温湿度传感器_sht20通信方式-CSDN博客文章浏览阅读2.3k次,点赞29次,收藏33次。I2C是Inter IC BUS=IIC=I²C=I2C,一般我们读作“挨方C”。简述一下I2C,是只需要两根通信线就能实现多主多从半双工的串行通信协议。传输速度会偏慢一点点,一般是100Kbps,是属于标准模式。另外还有快速模式,400Kbps;高速模式3.4Mbps;超快速模式5Mbps(后两种没接触过)。分别是SCL和SDA。SCL是Serial Clock,也就是统一时间的。SDA是Serial Data,也就是传输数据的。_sht20通信方式https://blog.csdn.net/m0_63235356/article/details/135734887?spm=1001.2014.3001.5501

接下来我们来看看GD32的IIC。

GD32F407一共有三个IIC资源,挂载在了APB1上面。

硬件IIC0的数据线在GPIOB的8和9号引脚上。因此我们首先就是要打开GPIOB的外设时钟,以及初始化一下这俩引脚,因为我们用的是硬件资源,因此要设置为复用模式。

    rcu_periph_clock_enable(RCU_GPIOB);
    gpio_af_set(GPIOB, GPIO_AF_4,GPIO_PIN_8|GPIO_PIN_9);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8|GPIO_PIN_9);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_8|GPIO_PIN_9);

引脚复用我们选择4号复用。

不同型号需要查阅自己型号的固件库手册,比如说GD32E230的I2C就是0号复用。

上一篇文章写串口的在这方面是直接跳过了,现在在这边补充一下。

包括输出模式设置成什么上一篇好像也是跳过的,其实这一点我们可以查阅手册。

甚至我们可以直接参考STM32的手册,因为STM32里在GPIO章节里直接有个表格方便我们查阅,而GD32里可能也有但是我没有找到。

关于GPIO的设置我们就说到这边,其实我们使用到硬件资源的时候初始化GPIO都是这一套流程,具体细节在文档中都能找到。

接下来就是关于IIC的固件库函数了。

i2c_deinit(I2C0);

首先一样是复位函数,在设置IIC之前我们最好都调用一遍。

i2c_clock_config(I2C0, 100000, I2C_DTCY_2);

设置IIC的时钟,参数二理论上我们可以随便填入一个32bit大小的值,但是我们最好还是按照IIC常见的速率来设置,例如100k,400k这样。

i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0X80);

接下来是设置IIC通信的模式与地址,模式我们自然是选择I2C模式的,而地址可以选择7位或者是10位的(10位的参数截图没截上,因为卡在手册的下一页了),这个根据我们通信的模块的从机地址而定。

我们今天示范的SHT20是7位从机地址,是100 000,对应到十六进制就是0x80。

i2c_ack_config(I2C0, I2C_ACK_ENABLE);

设置发送应答,我们一般都设置为发送,当发送我们结束IIC通信的上一个时序的时候我们再关闭应答。

i2c_master_addressing(I2C0,0x80,I2C_TRANSMITTER);

发送从机地址,在IIC中我们开始时序发送之后第一个要发送的数据就是从机地址。我们知道从机地址是7位,剩下一位就是读写位了,0为写,1为读,我们不用手动去修改,直接调用这个函数就可以达到设置收发状态的从机地址并发送了。

不嫌麻烦的话,调用发送时序的函数再手动修改从机地址也是一样的效果。

i2c_enable(I2C0);

使能IIC,设置完IIC后使能,我们就可以使用IIC了。

IIC时序其实不多,就是开始,结束,发送,接收。应答的话硬件IIC会自动帮我们发送接收可以不用管。接下来我们就来看看这些时序对应的固件库函数是哪一些。

i2c_start_on_bus(I2C0);

这个就是起始时序了。起始时序就是在SCL高电平的时候,SDA从高电平切换到低电平。

i2c_stop_on_bus(I2C0);

发送结束时序。结束时序就是在SCL高电平的时候,SDA从低电平切换到高电平。

i2c_data_transmit(I2C0,data);

发送时序,在SCL低电平的时候,主机将数据放置到SDA(1为高电平,0为低电平) 主机拉高SCL的时候,在SCL高电平时,从机读取SDA的数据。可以一次发送8位数据。

i2c_data_receive(I2C0)

接收时序,一次收8bit。

至此我们就集齐了IIC的时序了,可以开始IIC了……吗?

硬件IIC麻烦的地方来了。那就是每个时序我们都需要等待标志位以及清除标志位。

获取标志位的函数在上面,我们讲过的时序用到的标志位参数我用红框框出来了。

获取完之后还得清除,传入的参数和上面获取的函数基本一样,我就不贴出来了。不过有些标志位是不用我们手动清除的,这个具体要查看手册,手册中没有对应的标志位参数就代表我们不用手动清除。

那么接下来我们就可以进行IIC通信了,时序都凑齐了,我们每发完一个时序都需要等待标志位置位(获取标志位)并且清除。

接下来我直接贴出代码(GD32F407),我会尽量写出注释,关于SHT20的看不懂的部分可以回顾一下开头链接的文章。

串口部分可以参考上一篇文章。

#include "board.h"
#include <stdio.h>
#include "Z_UART.h"

float SHT20_GetData(uint8_t command){
    uint16_t res = 0;

    i2c_start_on_bus(I2C0);                             //起始时序
    while(!i2c_flag_get(I2C0,I2C_FLAG_SBSEND) );        //等待起始位发送完. 这个不用手动清除标志位
    
    i2c_master_addressing(I2C0, 0x80, I2C_TRANSMITTER); //发送从机地址(0x80)+写命令(0)
    while(!i2c_flag_get(I2C0,I2C_FLAG_ADDSEND) );       //等待从机发送完毕之后得到回应(即从机地址正确)
    i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND);              //清除标志位
    
    while(!i2c_flag_get(I2C0,I2C_FLAG_TBE));            //等待发送缓冲区空
    
    if(command == 'w')  i2c_data_transmit(I2C0,0xF3);   //发送数据,发送SHT20的指令,F3为获取温度,F5为获取湿度
    else    i2c_data_transmit(I2C0,0xF5);
    
    while(!i2c_flag_get(I2C0,I2C_FLAG_BTC) );           //等待字节传输完毕

    i2c_stop_on_bus(I2C0);                              //发送结束时序
    
    uint8_t count = 0;                                  //计数,因为SHT20采集数据需要时间,我们设置个超时时间
    do{
        i2c_start_on_bus(I2C0);                         //起始时序
        while(!i2c_flag_get(I2C0,I2C_FLAG_SBSEND));     //等待起始位发送完毕
     
        i2c_master_addressing(I2C0, 0x80, I2C_RECEIVER);//发送从机地址(0x80)+读命令(1)
        
        delay_ms(10);                                   //延时10ms
        if(++count >= 10) return 0;                     //超过100ms我们就算读取失败
    }while(!i2c_flag_get(I2C0,I2C_FLAG_ADDSEND));       //等待回应

    i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND);              //清除标志位

    i2c_ack_config(I2C0, I2C_ACK_ENABLE);               //开启应答

    while(!i2c_flag_get(I2C0,I2C_FLAG_RBNE) );          //等待接收缓冲区不为空

    res = i2c_data_receive (I2C0);                      //读取SHT传来的数据的高8位
    res <<= 8;

    i2c_ack_config(I2C0, I2C_ACK_DISABLE);              //关闭应答,因为我们就获取俩8bit数据

    while(!i2c_flag_get(I2C0,I2C_FLAG_RBNE) );          //等待接收缓冲区不为空

    res |= i2c_data_receive (I2C0);                     //读取SHT传来的数据的低8位
    
    i2c_stop_on_bus(I2C0);                              //结束时序

    res &= 0xFFFC;                                      //清除最后两位,这是SHT20要求的
    
    //根据指令的不同(获取温度/湿度)来计算数据
    if(command == 'w') return ((res / 65536.0) * 175.72 - 46.85);
    return (( res / 65536.0) * 125 - 6);
}

int main(void){
    board_init();
    //初始化串口,为了将结果打印到串口助手上,不懂怎么操作的小伙伴可以看看上一篇文章
    Z_UART_Init();
    //开启时钟
    rcu_periph_clock_enable(RCU_I2C0);
    rcu_periph_clock_enable(RCU_GPIOB);
    //初始化硬件IIC的引脚
    gpio_af_set(GPIOB, GPIO_AF_4,GPIO_PIN_8|GPIO_PIN_9);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8|GPIO_PIN_9);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_8|GPIO_PIN_9);
       
    i2c_deinit(I2C0);                                           //复位IIC0
    i2c_clock_config(I2C0, 100000, I2C_DTCY_2);                 //设置IIC速率为100k
    i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0X80);  //设置SHT20的七位地址
    i2c_ack_config(I2C0, I2C_ACK_ENABLE);                       //使能应答
    i2c_enable(I2C0);                                           //使能IIC
    
    printf("hello world!\r\n");
    while (1){
        printf("%f\t%f\r\n",SHT20_GetData('w'),SHT20_GetData('s'));
        delay_ms(1000);
    }
}

 可以正常接收数据。

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

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

相关文章

ComfyUI中运行Stable Audio Open,实现背景音乐、音效自由

&#x1f9e8;背景 stability在一个月之前默默的发布了Stable Audio Open 1.0的音频音效生成模型&#xff0c;不过好像影响力一般&#xff0c;也没有太多文章分享测试&#xff0c;而今天看comfyui作者的一篇介绍文档&#xff0c;他已经让comfyui默认支持了这个模型。 原开源地…

Linux 基于sqlite3数据库的学生管理系统

一、数据库 sqlite官网&#xff1a;www.sqlite.org 1.1 数据库的安装 离线安装&#xff1a; sudo dpkg -i sqlite3_3.22.0-1ubuntu0.4_amd64.deb //数据库软件 sudo dpkg -i libsqlite3-dev_3.22.0-1ubuntu0.4_amd64.deb //数据库的库函数 在线安装&#xff1a; sudo apt-get …

【Linux】Linux下使用套接字进行网络编程

&#x1f525;博客主页&#xff1a; 我要成为C领域大神&#x1f3a5;系列专栏&#xff1a;【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 ​ 用于网络应用开…

知识图谱——Neo4j数据库实战

数据与代码链接见文末 1.Neo4j数据库安装 JDK 安装:https://www.oracle.com/java/technologies/javase-downloads.html Neo4j 安装:https://neo4j.com/download-center/ 配置好 JDK 和 Neo4j 的环境变量

嵌入式Linux系统编程 — 4.1 字符串输入输出

目录 1 字符串输出 1.1 字符串输出函数简介 1.2 示例程序 2 字符串输入 2.1 字符串输入简介 2.2 示例程序 程序运行时&#xff0c;需打印信息至标准输出 stdout 设备 或标准错误 stderr设备&#xff08;譬如屏幕&#xff09;&#xff0c;如调试信息、报错信息、中间产生的…

数据库课程知识点总结

数据库概述 数据库基本特点&#xff1a;数据结构化&#xff0c;数据独立性&#xff0c;数据冗余小&#xff0c;易扩充&#xff0c;统一管理和控制&#xff0c;永久存储&#xff0c;有组织&#xff0c;可共享 三级模式 模式&#xff1a;一个数据库只有一个模式&#xff0c;是对…

将idea项目代码部署到Linux系统中

目录 1. 将idea与虚拟机建立连接 2. 设置上传到虚拟机的目录 3.上传项目代码 1. 将idea与虚拟机建立连接 打开idea要上传的项目,找到Tools -> Development -> Configuration 设置一个连接的名称,我这里设置为centos 将Type设置为SFTP,点击SSH configuration 开始配…

数据库物理结构设计-定义数据库模式结构(概念模式、用户外模式、内模式)、定义数据库、物理结构设计策略

一、引言 如何基于具体的DBMS产品&#xff0c;为数据库逻辑结构设计的结果&#xff0c;即关系数据库模式&#xff0c;制定适合应用要求的物理结构 1、在设计数据库物理结构前&#xff0c;数据库设计人员首先 要充分了解所用的DBMS产品的功能、性能和特点&#xff0c;包括提供…

抖音集成:通过MessageBox引领数字化营销新潮流

抖音集成&#xff1a;通过MessageBox引领数字化营销新潮流 在数字化营销的大潮中&#xff0c;企业需要不断探索新的方式来优化其营销策略&#xff0c;以抓住更多的市场机会。抖音作为一款全球知名的短视频社交平台&#xff0c;凭借其庞大的用户群体和高度互动的特性&#xff0…

亿发进销存管理系统+:多终端无缝协同,实现经营销售场景全覆盖

亿发软件凭借产品、市场、业务的深入理解&#xff0c;在进销存基础上进行了延伸&#xff0c;推出多终端、一体化的“进销存管理系统”多元产品矩阵。对企业经营中进货、出货、销售、付款等进行全程跟踪管理。有效辅助企业解决业务管理、销售管理、库存管理、财务管理等一系列问…

【论文阅读】-- TSR-TVD:时变数据分析和可视化的时间超分辨率

TSR-TVD: Temporal Super-Resolution for Time-Varying Data Analysis and Visualization 摘要1 引言2 相关工作3 我们的循环生成方法3.1 损失函数3.2 网络架构 4 结果与讨论4.1 数据集和网络训练4.2 结果4.3 讨论 5 结论和未来工作致谢参考文献附录1 训练算法及优化2 网络分析…

02.Ambari自定义服务开发-metainfo.xml介绍

文章目录 metainfo.xml 介绍配置说明Hbase metainfo.xml配置说明配置参数详细介绍配置文件样例DORIS metainfo.xml 介绍 ​ 在Ambari自定义开发中&#xff0c;metainfo.xml 配置文件起着至关重要的作用。它用于定义服务的元数据信息&#xff0c;包括服务的版本、组件、执行脚本…

RabbitMQ基本概念

RabbitMQ是AMQP协议的一个开源实现&#xff0c;所以其基本概念也就是的 AMQP 协 议中的基本概念。如图3-1所示是 RabbitMQ 的整体架构图。 Message(消息):消息是不具名的&#xff0c;它由消息头和消息体组成。消息体是不透明的&#xff0c; 而消息头则由一系列可选属性组成&…

六西格玛绿带可以跳过,直接学六西格玛黑带吗?真实情况告诉你

在现代企业管理中&#xff0c;六西格玛&#xff08;Six Sigma&#xff09;已经成为提升质量和效率的重要工具。对于很多企业而言&#xff0c;培养内部的六西格玛专家&#xff0c;特别是黑带&#xff08;Black Belt&#xff09;&#xff0c;是推动持续改进的关键。然而&#xff…

如何用Vue3和Plotly.js实现一个交互式世界地图动画

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 利用 Plotly.js 创建交互式世界生命预期地图 应用场景 本代码展示了如何使用 Plotly.js 创建一个交互式世界生命预期地图&#xff0c;允许用户按年份浏览不同国家和地区的生命预期数据。该地图可以用于研究世…

电脑文件concrt140.dll丢失要怎么恢复?靠谱修复方法分析

电脑文件concrt140.dll丢失这种情况&#xff0c;相对来说还是比较少见的&#xff01;但是不代表没有&#xff0c;既然有人出现这种情况了&#xff0c;那么小编势必要给大家详细的讲解一下concrt140.dll这个文件&#xff0c;以及我们要怎么去解决concrt140.dll文件丢失的问题。下…

技术贴 | RNA甲基化修饰m6A的检测——MeRIP-seq

01 m6A是什么 目前在细胞RNA中已经识别到了超过100种化学修饰&#xff0c;其中RNA甲基化修饰在生命活动中有着非常重要的作用(Xu et al 2020)。RNA甲基化是指在甲基转移酶的催化下&#xff0c;在RNA分子上的某一个原子上添加一个甲基基团(CH3)。RNA甲基化修饰类型有很多&#…

架构师篇-5、架构语言-ArchiMate

内容摘要&#xff1a; TOGAF内容元模型TOGAF架构语言ArchiMate3ArchiMate实践案例分享 TOGAF内容框架【核心内容元模型】 作为一个通用且开放式的标准&#xff0c;TOGAF需要采用一种非常灵活的方式来对其内容元模型进行定义&#xff0c;从而使得不同的企业可以根据自身需要对…

Swagger2及常用校验注释说明

Api(value "后台用户管理") RestController RequestMapping("bossuser") public class BossUserController {ApiOperation(value "测试接口")PostMapping("test")public String testUser(Valid RequestBody TestUser user) {LOG.inf…

vue表头字段添加鼠标悬浮提示

<el-table-column prop"jfScore" align"center" min-width"100px"><template slot"header" slot-scope"scope"><div><span>信用积分</span><el-tooltip:aa"scope"class"it…