STMF4 硬件IIC(天空星开发板)

news2024/11/15 15:46:28

                                        前言:笔记参考立创开发文档,连接放在最后

#IIC概念介绍

#IIC介绍

        IIC通信协议,一种常见的串行通信协议,英文全程是 Inter-Integrated Circuit  使用这种通信方式的模块,通常有SCL(Serial Clock Line)  和SDA(Serial Date)两个引脚  ,也就是当看到这两个引脚也就知道,使用的IIC通信。        

        IIC通信分为硬件IIC通信   软件IIC通信,本篇介绍硬件IIC通信 ,想要了解软件IIC的可以看另一篇文章,IIC通信SDA数据线 高电平电压范围在 2.5V~5.5V  低电平范围 0V~0.3V 

#软件IIC介绍

        软件IIC指的是,通过GPIO引脚模拟IIC通信的波形时序,也就是控制引脚的电平变化来传输数据还有时序信号,达到IIC通信的效果目的,软件IIC通信好处是,在MCU内部没有集成硬件IIC电路的时候,可以使用软件IIC通信,只要MCU支持GPIO就能使用软件IIC通信

        软件IIC的性能相对于硬件IIC较低,通常使用在低速通信还有简单通信的情况下去使用。

#硬件IIC介绍

        硬件IIC指的是芯片内部集成的IIC硬件外设,硬件IIC效率远高于软件IIC, STMF4VET6上带有3个硬件IIC,允许与外部IIC接口进行通信,STMF4的硬件IIC使用特定的引脚复位,来进行数据和时钟信号的传输。

       硬件IIC的通信时序波形,是通过硬件电路还有寄存器来实现的,这些电路还有寄存器负责生成时钟,还有数据线电平变化,使其符合IIC通信协议的要求,这个就是IIC通信的硬件控制流程,具体可以参考下图硬件IIC的框图。

                        

        硬件IIC框图里面,可以发现硬件IIC,也支持中断 还有 DMA输出传输数据。

#配置硬件IIC相关流程

#硬件IIC发送流程

        软件初始化:硬件IIC的通信时序,由内部的寄存器 控制器,来负责所以首先要配置IIC控制器的参数,需要设置 IIC速率  地址模式    设备地址

        START设置:发送起始信号到IIC总线,设置硬件IIC控制器开始位来启动发送过程,通过标志位SBSEND判断起始信号是否发送完毕,发送完毕标志位(SBSEND)会置一。

        清除SBSEND:当起始信号发送完成,SBSEND这个标志位会被硬件置1,10位地址模式,需要清除标志位才能进行下一步,7位地址模式,该标志位不能清除。

        清除ADDSEND:如果地址为10位模式,要发送 地址高位地址低位,发送完成ADD10SEND 和 ADDSEND 会由硬件置1,这个时候需要清除 ADD10SEND 和 ADDSEND 如果地址为 7位模式则只需要发送一次地址,并等待ADDSEND硬件置1后,清除ADDSEND标志位。

        传输数据:为了防止数据溢出,需要判断发送寄存器的数据是否为空,也就是查询TBE标志位的值,当发送数据寄存器为空的时候,TBE寄存器会被硬件置1,主机接受从机应答信号,此时发送数据成功,BTC标志位会被硬件置1

        设置STOP:当数据发送完成,这个时候要停止IIC通信,设置STOP也就是发送停止信号。

#硬件IIC接收流程

        硬件IIC,接收数据跟发送数据过程大致相同, 设置START   清除SBSEND  清除ADDEND  读取字节数据  清除ACKEN   设置STOP 。下面只介绍不同的部分。

        在此设置START:这里其实信号发送之前,硬件IIC必须是空闲状态才能发送,负责没有办法进行下一步。

        读取数据字节:RBNE标志位,当接收数据寄存器中,如果有数据,会将RBNE自动硬件置1,这个时候通过读取标志位信息,停止发送信息,防止数据溢出。取出寄存器里面的数据之后,通过使能ACK应答位,硬件会自动发送,这个时候从机才会继续发送数据。

#软件IIC实验

            硬件IIC通常来说不为常用,一般通过软件IIC进行通信,也就是通过控制GPIO引脚电平,模拟IIC通信时序,电平。

#宏定义 IIC引脚  调用函数

       使用宏定义,去写代码,这种函数是能够提升程序的执行速度,因为宏定义是预处理指令,在程序执行前,开始执行的,如果是将函数在次封装在调用,这种程序执行速度是比不上,宏定义函数,宏定义常量的。

#define RCU_SCL          RCC_AHB1Periph_GPIOB
#define PORT_SCL         GPIOB
#define GPIO_SCL         GPIO_Pin_6

#define RCU_SDA          RCC_AHB1Periph_GPIOB
#define PORT_SDA         GPIOB
#define GPIO_SDA         GPIO_Pin_7


#define SDA_IN()  {SHT20_MODE_SET( GPIO_Mode_IN  );}  //SDA输入模式
#define SDA_OUT() {SHT20_MODE_SET( GPIO_Mode_OUT );}  //SDA输出模式

#define SCL(BIT)  GPIO_WriteBit(PORT_SCL, GPIO_SCL, BIT)
#define SDA(BIT)  GPIO_WriteBit(PORT_SDA, GPIO_SDA, BIT)
#define SDA_GET() GPIO_ReadInputDataBit(PORT_SDA, GPIO_SDA)
void SHT20_GPIO_INIT(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

        GPIO_InitStructure.GPIO_Pin = GPIO_SCL;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(PORT_SCL, &GPIO_InitStructure);
        
        GPIO_InitStructure.GPIO_Pin = GPIO_SDA;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(PORT_SDA, &GPIO_InitStructure);
}

        这里使用了宏定义常量 重定义了函数,同时初始化了 GPIO 引脚 用它作为 IIC通信数据线。

#配置IIC通信时序

void IIC_Start(void)
{
        SDA_OUT();
        
        SCL(0);
        SDA(1);
        SCL(1);
        
        delay_us(5);
        
        SDA(0);
        delay_us(5);
        SCL(0);
        delay_us(5);
        
        
}
void IIC_Stop(void)
{
        SDA_OUT();
        
        SCL(0);
        SDA(0);
        
        SCL(1);
        delay_us(5);
        SDA(1);
        delay_us(5);
        
}
void IIC_Send_Ack(uint8_t ack)
{
        SDA_OUT();
        SCL(0);
        SDA(0);
        delay_us(5);
        if(!ack) SDA(0);
        else         SDA(1);
        SCL(1);
        delay_us(5);
        SCL(0);
        SDA(1);
}
uint8_t IIC_Wait_Ack(void)
{
        char ack = 0;
        unsigned char ack_flag = 10;
        SDA_IN();
    SDA(1);
        delay_us(5);
        SCL(1);
        delay_us(5);
        while( (SDA_GET()==1) && ( ack_flag ) )
        {
                ack_flag--;
                delay_us(5);
        }
        
        if( ack_flag <= 0 )
        {
                IIC_Stop();
                return 1;
        }
        else
        {
                SCL(0);
                SDA_OUT();
        }
        return ack;
}
void IIC_Write(uint8_t data)
{
        int i = 0;
        SDA_OUT();
        SCL(0);//拉低时钟开始数据传输
        
        for( i = 0; i < 8; i++ )
        {
                SDA( (data & 0x80) >> 7 );
                delay_us(2);
        data<<=1;
        delay_us(6); 
                SCL(1);
                delay_us(4);
                SCL(0);
                delay_us(4);
                
        }
}

uint8_t IIC_Read(void)
{
        unsigned char i,receive=0;
    SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
        {
        SCL(0);
        delay_us(5);
        SCL(1);
        delay_us(5);
        receive<<=1;
        if( SDA_GET() )
        {        
            receive|=1;   
        }
        delay_us(5); 
    }                
  return receive;
}

        上面配置了IIC通信时序,接下来,根据温度湿度公式,计算实际温度还是湿度定义函数输出即可。

#配置温度湿度函数

float SHT20_Read(uint8_t regaddr)
{        
    unsigned char data_H = 0;
    unsigned char data_L = 0;
    float temp = 0;
    IIC_Start();
    IIC_Write(0x80|0);
    if( IIC_Wait_Ack() == 1 ) printf("error -1\r\n");
    IIC_Write(regaddr);
    if( IIC_Wait_Ack() == 1 ) printf("error -2\r\n");
       
    do{
    delay_us(10);
    IIC_Start();
    IIC_Write(0x80|1);
    
    }while( IIC_Wait_Ack() == 1 );

    delay_us(20);
    
    data_H = IIC_Read();
    IIC_Send_Ack(0);
    data_L = IIC_Read();
    IIC_Send_Ack(1);
    IIC_Stop();
    
    if( regaddr == 0xf3 )
    {
        temp = ((data_H<<8)|data_L) / 65536.0 * 175.72 - 46.85;
    }
    if( regaddr == 0xf5 )
    {
        temp = ((data_H<<8)|data_L) / 65536.0 * 125.0 - 6;
    }
   return temp;

}
int main(void)
{    
    board_init();
    uart1_init(115200U);
    
    //引脚初始化
    SHT20_GPIO_INIT();
    
    //等待传感器上电初始化完成
    delay_ms(20);
    
    while(1)
    {
        //采集温度
        printf("temp = %.2f\r\n", SHT20_Read(0xf3) );
        //采集湿度
        printf("humi = %.2f\r\n", SHT20_Read(0xf5) );
        printf("\r\n");
        delay_ms(500);
    }
}

 ⁠​‬​‍​‍‬​‍‌‍⁠​​‬‌‬​‬​‍‌​‬​⁠‍‌‌​​‍​​​​​‬​‌⁠​                  【立创·天空星STM32F407VET6】入门手册 - 飞书云文档 (feishu.cn)

                                     欢迎指正,希望对你,有所帮助!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

请编写函数,删除字符串中指定位置下的字符,删除成功函数返回被删字符,否则返回空值

char arr_del(char* p, int pos) {if (pos> strlen(p) || pos<0){printf("这是一个无效下标\n");exit(1);}//到这里就是有效下标char ch p[pos];//把要删除的下标存储for (int i pos; p[i] ! \0; i){p[i] p[i 1];}return ch; } int main() {char arr[100];…

昂科烧录器支持ZhiXin智芯半导体的中低端微控制器Z20K118M

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中ZhiXin智芯半导体的中低端微控制器Z20K118M已经被昂科的通用烧录平台AP8000所支持。 Z20K118M基于ARMCortex-M0内核&#xff0c;支持内部64MHz或外部40MHz主频&#xff0c;内部…

多GPU系统中的CUDA设备不可用问题

我们在使用多GPU系统时遇到了CUDA设备不可用的问题&#xff0c;详细情况如下&#xff1a; 问题描述&#xff1a; 我们在一台配备有8块NVIDIA GeForce RTX 3090显卡的服务器上运行CUDA程序时&#xff0c;遇到了如下错误&#xff1a; cudaErrorDevicesUnavailable: CUDA-capabl…

RedHat Linux8 修改root管理员账户密码命令

RedHat Linux8 修改root管理员账户密码命令&#xff1a; sudo passwd root RedHat重置root管理员密码&#xff1a; 1. 查看Linux系统版本信息 cat /etc/redhat-release2. 重置密码 2.1 进入内核编辑界面 重启Linux系统并出现引导界面&#xff0c;按下键盘上的e键进入内…

PostgreSQL 中如何处理数据的并发更新冲突解决?

文章目录 一、并发更新冲突的场景二、PostgreSQL 中的并发控制机制&#xff08;一&#xff09; 封锁机制&#xff08;二&#xff09; 事务隔离级别 三、并发更新冲突的解决方法&#xff08;一&#xff09; 重试机制&#xff08;二&#xff09; 使用乐观并发控制&#xff08;三&…

一句歌词描述夏天

夏天总是带着一种奇特的魔力&#xff0c;既能让人沉醉在阳光和海浪的浪漫中&#xff0c;也能在炎热与燥热中让人心生烦闷。特别是在夏日里情绪低落时&#xff0c;那些可以抚平心情的歌曲显得尤为珍贵。音乐&#xff0c;这个神奇的存在&#xff0c;总能在最需要的时候带来心灵的…

[激光原理与应用-107]:南京科耐激光-激光焊接-焊中检测-智能制程监测系统IPM介绍 - 10 - 什么是虚焊,如何检测虚焊?

目录 一、前言&#xff1a;虚焊概述 1.定义与特征 2.产生原因 3.危害与影响 4.预防措施 二、虚焊的检测方法 2.1 概述 1. 直观检查法 2. 晃动法 3. 敲击法 4. 补焊法 5. 非破坏性检测方法 6. 电性能测试 2.2 示例 一、前言&#xff1a;虚焊概述 虚焊是一种常见的…

Java SQL 连接(初级)

实训Day3 记实 实训第三天&#xff0c;今天是头脑风暴的第二天&#xff0c;课程将SQL与Java&#xff08;idea&#xff09;代码结合&#xff0c;这是一项具有挑战性的代码课程。课程将两个应用结合起来&#xff0c;展现了Java代码的跨平台性&#xff0c;展现了Java语言的封装性…

关于数组的常见算法

一、案例一 案例说明 案例&#xff1a;定义一个int型的一维数组&#xff0c;包含10个元素&#xff0c;分别赋一些随机整数&#xff0c;然后求出所有元素的最大值&#xff0c;最小值&#xff0c;总和&#xff0c;平均值&#xff0c;并输出出来 要求&#xff1a;所有随机数都是两…

Windows环境人大金仓数据库命令常规操作

Windows环境人大金仓数据库命令常规操作 下文将介绍人大金仓数据库常见命令操作&#xff0c;包括具体使用命令如创建数据库、创建用户、授权等相关操作。 1、打开命令提示符窗口 找到数据库安装目录进入server/bin目录&#xff0c;输入cmd,打开命令提示符窗口&#xff0c;如…

如何批量更改很多个文件夹里的文件名中包含文件夹名?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

【论文速读】《面向深度学习的联合消息传递与自编码器》

这篇文章来自华为的渥太华无线先进系统能力中心和无线技术实验室&#xff0c;作者中有大名鼎鼎的童文。 一、自编码架构的全局收发机面临的主要问题 文章对我比较有启发的地方&#xff0c;是提到自编码架构的全局收发机面临的主要问题&#xff1a; 问题一&#xff1a;基于随…

Nature Renderer 2022(植被渲染工具插件)

渲染大量详细的植被。 自然渲染器通过替换Unity的默认地形细节和树系统来提高植被渲染的质量。一切都适用于现有数据:使用相同的草地、植被和树木,并保留现有地形。我们只是升级您的渲染器。 Unity验证的解决方案 Nature Renderer受到25000多名开发人员的信任,是Unity验证的…

洛谷P1498 南蛮图腾[递归好题]

南蛮图腾 题目背景 自从到了南蛮之地&#xff0c;孔明不仅把孟获收拾的服服帖帖&#xff0c;而且还发现了不少少数民族的智慧&#xff0c;他发现少数民族的图腾往往有着一种分形的效果&#xff0c;在得到了酋长的传授后&#xff0c;孔明掌握了不少绘图技术&#xff0c;但唯独…

鼠标哪款好用?2024年选这几款鼠标不会出错

鼠标可是我们电脑的好伙伴&#xff0c;它能大大提高我们的工作效率。现在&#xff0c;无线鼠标变得越来越受欢迎&#xff0c;因为没有乱七八糟的线缆&#xff0c;用起来既方便又省空间。对于爱玩游戏的朋友们来说&#xff0c;挑选一个称心如意的鼠标可是件头疼的事。别急&#…

蓝牙控制小车

demo.main.c motor.c uart.c motor.h uart.h 实物图

c++:面向对象的继承特性

什么是继承 (1)继承是C源生支持的一种语法特性&#xff0c;是C面向对象的一种表现 (2)继承特性可以让派生类“瞬间”拥有基类的所有&#xff08;当然还得考虑权限&#xff09;属性和方法 (3)继承特性本质上是为了代码复用 (4)类在C编译器的内部可以理解为结构体&#xff0c;派…

初学SpringMVC之 RestFul 风格、重定向和转发

RestFul 风格改变 URL 形式 比如之前是&#xff1a;http://localhost:8080/add?a1&b2 现在是&#xff1a;http://localhost:8080/add/a/b&#xff08;全是斜杠&#xff09; package com.demo.controller;import org.springframework.stereotype.Controller; import org…

鸿蒙系统创建签名文件及使用创建签名文件打包并安装

* 第一步 第二步&#xff1a;创建.p12文件&#xff0c;点击New如果有的话就Choose Existing 填好下面信息 点击Next进入到下面界面 开始生成csr文件如下图 点击OK–>Finish 文件保存在了下面目录 第三步 1.访问华为开发者平台&#xff0c;登录开发者账号&#xff0c;进…

应急响应-ELK日志分析系统

&#x1f3bc;个人主页&#xff1a;金灰 &#x1f60e;作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持&#xff01;❤️ &#x1f34a;易编橙终身成长社群&#…