cortex-A7核IIC实验
iic.h:
#ifndef __IIC_H__
#define __IIC_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"/* 通过程序模拟实现I2C总线的时序和协议* GPIOF ---> AHB4* I2C1_SCL ---> PF14* I2C1_SDA ---> PF15** */#define SET_SDA_OUT do{GPIOF->MODER &= (~(0x3 << 30)); \GPIOF->MODER |= (0x1 << 30);}while(0)
#define SET_SDA_IN do{GPIOF->MODER &= (~(0x3 << 30));}while(0)#define I2C_SCL_H do{GPIOF->BSRR |= (0x1 << 14);}while(0)
#define I2C_SCL_L do{GPIOF->BRR |= (0x1 << 14);}while(0)#define I2C_SDA_H do{GPIOF->BSRR |= (0x1 << 15);}while(0)
#define I2C_SDA_L do{GPIOF->BRR |= (0x1 << 15);}while(0)#define I2C_SDA_READ (GPIOF->IDR & (0x1 << 15))void delay_us(void);
void i2c_init(void);
void i2c_start(void);
void i2c_stop(void);
void i2c_write_byte(unsigned char dat);
unsigned char i2c_read_byte(unsigned char ack);
unsigned char i2c_wait_ack(void);
void i2c_ack(void);
void i2c_nack(void);#endif
iic.c:
#include "iic.h"extern void printf(const char* fmt, ...);
/** 函数名 : delay_us* 函数功能:延时函数* 函数参数:无* 函数返回值:无* */
void delay_us(void)
{unsigned int i = 2000;while(i--);
}
/** 函数名 : i2c_init* 函数功能: i2C总线引脚的初始化, 通用输出,推挽输出,输出速度,* 函数参数:无* 函数返回值:无* */
void i2c_init(void)
{// 使能GPIOF端口的时钟RCC->MP_AHB4ENSETR |= (0x1 << 5);// 设置PF14,PF15引脚为通用的输出功能GPIOF->MODER &= (~(0xF << 28));GPIOF->MODER |= (0x5 << 28);// 设置PF14, PF15引脚为推挽输出GPIOF->OTYPER &= (~(0x3 << 14));// 设置PF14, PF15引脚为高速输出GPIOF->OSPEEDR |= (0xF << 28);// 设置PF14, PF15引脚的禁止上拉和下拉GPIOF->PUPDR &= (~(0xF << 28));// 空闲状态SDA和SCL拉高 I2C_SCL_H;I2C_SDA_H;
}/** 函数名:i2c_start* 函数功能:模拟i2c开始信号的时序* 函数参数:无* 函数返回值:无* */
void i2c_start(void)
{/** 开始信号:时钟在高电平期间,数据线从高到低的变化* --------* SCL \* --------* ----* SDA \* --------* */ SET_SDA_OUT;//1.设置数据线为输出模式I2C_SCL_H;//2.在SCL为高电平delay_us();I2C_SDA_H;//3.SDA高电平delay_us();I2C_SDA_L;//4.SDA低电平I2C_SCL_L;//5.起始信号产生之后,总线处于占用状态
}/** 函数名:i2c_stop* 函数功能:模拟i2c停止信号的时序* 函数参数:无* 函数返回值:无* */void i2c_stop(void)
{/** 停止信号 : 时钟在高电平期间,数据线从低到高的变化 * ----------* SCL /* --------* --- -------* SDA X /* --- -------* */SET_SDA_OUT;//1.设置数据线为输出模式I2C_SCL_L;//2.SCL为低电平,数据线上数据发生变化delay_us();I2C_SDA_L;//3.SDA为低电平 delay_us();I2C_SCL_H;//4.SCL为高电平delay_us();I2C_SDA_H;//5.SDA为高电平 delay_us();
}/** 函数名: i2c_write_byte* 函数功能:主机向i2c总线上的从设备写8bits数据* 函数参数:dat : 等待发送的字节数据* 函数返回值: 无* */void i2c_write_byte(unsigned char dat)
{/** 数据信号:时钟在低电平期间,发送器向数据线上写入数据* 时钟在高电平期间,接收器从数据线上读取数据 * ---- --------* SCL \ / \* -------- --------* -------- ------------------ ---* SDA X X* -------- ------------------ ---** 先发送高位在发送低位 * */unsigned int i;SET_SDA_OUT;//1.设置数据线为输出模式for(i=0;i<8;i++){I2C_SCL_L; //2.SCL为低电平,可以向数据线上写入数据delay_us();if(dat & 0x80) //先发送高位在发送低位I2C_SDA_H;//3.向数据线上写入高电平elseI2C_SDA_L;//4.向数据线上写入低电平delay_us();I2C_SCL_H; //5.等待从机从数据线上读取数据delay_us();delay_us();dat <<= 1; //6.移位}
}/** 函数名:i2c_read_byte* 函数功能: 主机从i2c总线上的从设备读8bits数据, * 主机发送一个应答或者非应答信号* 函数参数: 0 : 应答信号 1 : 非应答信号* 函数返回值:读到的有效数据** */
unsigned char i2c_read_byte(unsigned char ack)
{/** 数据信号:时钟在低电平期间,发送器向数据线上写入数据* 时钟在高电平期间,接收器从数据线上读取数据 * ---- --------* SCL \ / \* -------- --------* -------- ------------------ ---* SDA X X* -------- ------------------ ---** 先接收高位, 在接收低位 * */unsigned int i;unsigned char dat; //读取到有效数据SET_SDA_IN;//1.设置数据线为输入模式for(i=0;i<8;i++){I2C_SCL_L;//2.保证发送器,向数据线上写入数据完成delay_us();delay_us();I2C_SCL_H; //3.时钟线在高电平期间,从数据线上读取数据delay_us();dat <<= 1; //4.移位必须放在if前面if(I2C_SDA_READ)dat |= 1;//5.读取数据为1elsedat |= 0; //6.读取数据为0 delay_us();}if(!ack)i2c_ack(); //7.主机给从机返回应答信号elsei2c_nack();//8.主机给从机返回非应答信号return dat;
}/** 函数名: i2c_wait_ack* 函数功能: 主机作为发送器时,等待接收器返回的应答信号* 函数参数:无* 函数返回值:* 0:接收到的应答信号* 1:接收到的非应答信号* */
unsigned char i2c_wait_ack(void)
{/** 主机发送一个字节之后,从机给主机返回一个应答信号** -----------* SCL / M:读 \* ------------- --------* --- ---- --------------------* SDA X X* --- --------------------* 主 释 从机 主机* 机 放 向数据 读数据线* 总 线写 上的数据* 线 数据* */ I2C_SCL_L;//1.时钟线为低电平delay_us();I2C_SDA_H;//2.数据线为高电平,释放总线delay_us();SET_SDA_IN;//3.设置数据线为输入模式delay_us();I2C_SCL_H;//4.时钟为高电平期间delay_us();if(I2C_SDA_READ)//5.从总线上读取数据return 1;// 读1 非应答信号I2C_SCL_L; //6.时钟线为低电平,总线处于占用状态return 0;//7.读0 应答信号
} /** 函数名: iic_ack* 函数功能: 主机作为接收器时,给发送器发送应答信号* 函数参数:无* 函数返回值:无* */
void i2c_ack(void)
{/* --------* SCL / \* ------- ------* ---* SDA X * --- -------------* */SET_SDA_OUT;//1.设置数据线为输出模式I2C_SCL_L; //2.SCL为低电平,改变数据线上数据delay_us();I2C_SDA_L; //3.应答信号 ==> 0delay_us();I2C_SCL_H; //4.等待从机器读取应答信号delay_us();delay_us();I2C_SCL_L;//5.总线处于占用状态
}/** 函数名: iic_nack* 函数功能: 主机作为接收器时,给发送器发送非应答信号* 函数参数:无* 函数返回值:无* */
void i2c_nack(void)
{/* --------* SCL / \* ------- ------* --- ---------------* SDA X * --- * */ SET_SDA_OUT;//1.设置数据线为输出模式I2C_SCL_L; //2.SCL为低电平,改变数据线上数据delay_us();I2C_SDA_H; //3.非应答信号 ==> 1delay_us();I2C_SCL_H; //4.等待从机器读取应答信号delay_us();delay_us();I2C_SCL_L;//5.总线处于占用状态
}
si7006.h:
#ifndef __SI7006_H__
#define __SI7006_H__#include "iic.h"
#define SI7006_SLAVE 0x40void si7006_init(void);unsigned short si7006_read_hum_data(unsigned char slave_addr, unsigned char reg_addr);
short si7006_read_temp_data(unsigned char slave_addr, unsigned char reg_addr);#endif //__SI7006_H__
si7006.c:
#include "iic.h"
#include "si7006.h"
extern void delay_ms(unsigned int ms);
/** 函数名:si7006_init* 函数功能:SI7006芯片的初始化* 函数参数:无* 函数返回值:无
*/
void si7006_init(void)
{i2c_init();i2c_start();i2c_write_byte(0x40 << 1 | 0);i2c_wait_ack();i2c_write_byte(0xE6);i2c_wait_ack();i2c_write_byte(0x3A);i2c_wait_ack();i2c_stop();
}
/** 函数名:si7006_read_data* 函数功能:读取SI7006的转换结果* 函数参数:* slave_addr : 从机地址* reg_addr : 寄存器地址* 函数返回值:无
*/unsigned short si7006_read_hum_data(unsigned char slave_addr, unsigned char reg_addr)
{unsigned short dat;unsigned char dat_h;unsigned char dat_l;i2c_start();i2c_write_byte(slave_addr << 1 | 0);i2c_wait_ack();i2c_write_byte(reg_addr);i2c_wait_ack();i2c_start();i2c_write_byte(slave_addr << 1 | 1);i2c_wait_ack();//延时函数delay_ms(5000);dat_h = i2c_read_byte(0);dat_l = i2c_read_byte(1);i2c_stop();dat = dat_h;dat <<= 8;dat |= dat_l;return dat;
}short si7006_read_temp_data(unsigned char slave_addr, unsigned char reg_addr)
{short dat;unsigned char dat_h;unsigned char dat_l;i2c_start();i2c_write_byte(slave_addr << 1 | 0);i2c_wait_ack();i2c_write_byte(reg_addr);i2c_wait_ack();i2c_start();i2c_write_byte(slave_addr << 1 | 1);i2c_wait_ack();//延时函数dat_h = i2c_read_byte(0);dat_l = i2c_read_byte(1);i2c_stop();dat = dat_h;dat <<= 8;dat |= dat_l;return dat;}
main.c:
#include "si7006.h"extern void printf(const char *fmt, ...);
void delay_ms(int ms)
{int i,j;for(i = 0; i < ms;i++)for (j = 0; j < 1800; j++);
}int main()
{unsigned short hum;short temp;si7006_init();while(1){hum = si7006_read_hum_data(SI7006_SLAVE,0xE5);temp = si7006_read_temp_data(SI7006_SLAVE,0xE3);printf("hum = %d\n",hum*125/65536 - 6);printf("temp = %d\n",temp*176/65536 - 47);}return 0;
}
相关文章:
cortex-A7核IIC实验
iic.h: #ifndef __IIC_H__ #define __IIC_H__ #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_rcc.h"/* 通过程序模拟实现I2C总线的时序和协议* GPIOF ---> AHB4* I2C1_SCL ---> PF14* I2C1_SDA ---> PF15** */#define SET_SDA_…...
task.run()和 await task.run() 区别 await 运行机制
Task.Run() 和 await Task.Run() 都涉及异步编程,但它们在使用场景和效果上有一些区别。1. **Task.Run():**- Task.Run() 是一个用于在后台线程上执行代码块的方法。它将指定的代码块包装在一个新的Task中,并在后台线程上运行。它不会阻塞调用…...

LeetCode面试经典150题(day 2)
26. 删除有序数组中的重复项 难度:简单 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯…...

阿里云机器学习PAI全新推出特征平台 (Feature Store),助力AI建模场景特征数据高效利用
推荐算法与系统在全球范围内已得到广泛应用,为用户提供了更个性化和智能化的产品推荐体验。在推荐系统领域,AI建模中特征数据的复用、一致性等问题严重影响了建模效率。阿里云机器学习平台 PAI 推出特征平台(PAI-FeatureStore) 。…...

网络安全工具和资源推荐: 介绍网络安全领域中常用的工具、框架、资源和学习资料
章节1: 前言 随着数字化时代的不断深入,网络安全的重要性愈发凸显。在这个信息爆炸的时代,我们必须保护个人隐私、敏感数据以及网络基础设施免受各种威胁。本文将为您介绍一些网络安全领域中常用的工具、框架、资源和学习资料,帮助您更好地入…...
『C语言入门』探索C语言函数
文章目录 导言一、函数概述定义与作用重要性 二、函数分类库函数自定义函数定义使用好处 三、函数参数实际参数(实参)形式参数(形参)内存分配 四、函数调用传值调用传址调用 五、函数嵌套调用与链式访问嵌套调用链式访问 六、函数…...

Django基础3——视图函数
文章目录 一、基本了解1.1 Django内置函数1.2 http请求流程 二、HttpRequest对象(接受客户端请求)2.1 常用属性2.2 常用方法2.3 服务端接收URL参数2.4 QueryDict对象2.5 案例2.5.1 表单GET提交2.5.2 表单POST提交2.5.3 上传文件 三、HttpResponse对象&am…...
python 基础篇 day 4 选择结构—— if 结构
文章目录 if 基础结构单 if 语句if-else 语句if-elif-else 语句嵌套的 if 语句 if 进阶用法使用比较运算符使用逻辑运算符使用 in 关键字range() 函数使用 is 关键字使用 pass 语句 三目运算符语法例子注意补充举例注意 if 基础结构 单 if 语句 if 条件: 执行条件为真时的代码…...

科技赋能,教育革新——大步迈向体育强国梦
在 "全民健身"、"体育强国建设"战略的推进下,体育考试成绩被纳入重要升学考试且分值不断提高,体育科目的地位逐步上升到前所未有的高度,在此趋势下,体育教学正演变出更多元化、个性化的需求。然而现实中却面临…...
【秋招基础】后端开发——笔面试常见题目
综述: 💞目的:本系列是个人整理为了秋招算法的,整理期间苛求每个知识点,平衡理解简易度与深入程度。 🥰来源:材料主要源于网上知识点进行的,每个代码参考热门博客和GPT3.5࿰…...

自定义loadbalance实现feignclient的自定义路由
自定义loadbalance实现feignclient的自定义路由 项目背景 服务A有多个同事同时开发,每个同事都在dev或者test环境发布自己的代码,注册到注册中心有好几个(本文nacos为例),这时候调用feign可能会导致请求到不同分支的服务上面,会…...

论文笔记:从不平衡数据流中学习的综述: 分类、挑战、实证研究和可重复的实验框架
0 摘要 论文:A survey on learning from imbalanced data streams: taxonomy, challenges, empirical study, and reproducible experimental framework 发表:2023年发表在Machine Learning上。 源代码:https://github.com/canoalberto/imba…...
C#设计模式六大原则之--迪米特法则
设计模式六大原则是单一职责原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特法则、开闭原则。它们不是要我们刻板的遵守,而是根据实际需要灵活运用。只要对它们的遵守程度在一个合理的范围内,努为做到一个良好的设计。本文主要介绍一下.NET(C#)…...
一次js请求一般情况下有哪些地方会有缓存处理?
目录 1、DNS缓存 2、CDN缓存 3、浏览器缓存 4、服务器缓存 1、DNS缓存 DNS缓存指DNS返回了正确的IP之后,系统就会将这个结果临时储存起来。并且它会为缓存设定一个失效时间 (例如N小时),在这N小时之内,当你再次访问这个网站时࿰…...
CSDN编程题-每日一练(2023-08-24)
CSDN编程题-每日一练(2023-08-24) 一、题目名称:计算公式二、题目名称:蛇形矩阵三、题目名称:小玉家的电费一、题目名称:计算公式 时间限制:1000ms内存限制:256M 题目描述: 给定整数n。 计算公式: n i-1 ∑ ∑ [gcd(i + j, i - j) = 1] i=1 j=1 输入描述: 输入整数n…...

怎么把PDF转成Word?需要注意什么事项?
PDF是一种常见的文档格式,但是与Word文档不同,PDF文件通常不能直接编辑。如果您想编辑PDF文件中的文本,或者想将PDF文件转换为Word文档,下面我们就来看一看把PDF转成Word有哪些方法和注意事项。 PDF转Word工具 有许多将PDF转换为…...
USACO22OPEN Pair Programming G
P8273 [USACO22OPEN] Pair Programming G 题目大意 一个程序由一系列指令组成,每条指令的类型如下: d \times d d,其中 d d d是一个 [ 0 , 9 ] [0,9] [0,9]范围内的整数 s s s,其中 s s s是一个表示变量名称的字符串ÿ…...
实战分享之springboot+easypoi快速业务集成
1.依赖引入 <!--引入EasyPOI--><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.1.0</version></dependency><dependency><groupId>cn.afterturn</group…...
金字塔原理(思考的逻辑)
前言:前面学习了表达的逻辑,那在表达之前,如何组织内容?如何进行思考?接下来看第二篇——思考的逻辑。 目录 应用逻辑顺序 时间顺序 结构顺序 程度顺序 概括各组思想 什么是概括? 思想表达方式 如…...
机器学习之前向传播(Forward Propagation)和反向传播(Back propagation)
前向传播(Forward Propagation)和反向传播(Back propagation)是深度学习中神经网络训练的两个关键步骤。 前向传播(Forward Propagation): 定义:前向传播是指从神经网络的输入层到输…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...

【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
13.10 LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析
LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析 LanguageMentor 对话式训练系统架构与实现 关键词:多轮对话系统设计、场景化提示工程、情感识别优化、LangGraph 状态管理、Ollama 私有化部署 1. 对话训练系统技术架构 采用四层架构实现高扩展性的对话训练…...

Linux操作系统共享Windows操作系统的文件
目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项,设置文件夹共享为总是启用,点击添加,可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download(这是我共享的文件夹)&…...

【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录
#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...
Netty自定义协议解析
目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...

C# WPF 左右布局实现学习笔记(1)
开发流程视频: https://www.youtube.com/watch?vCkHyDYeImjY&ab_channelC%23DesignPro Git源码: GitHub - CSharpDesignPro/Page-Navigation-using-MVVM: WPF - Page Navigation using MVVM 1. 新建工程 新建WPF应用(.NET Framework) 2.…...