当前位置: 首页 > news >正文

arm:day9

1。思维导图

 2..I2C实验,检测温度和湿度

iic.h

#ifndef __IIC_H__
#define __IIC_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "gpio.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 

si7006.h

#ifndef __SI7006_H__
#define __SI7006_H__#include "iic.h"
#define        SI7006_SLAVE      0x40void si7006_init(void);//short si7006_read_data(unsigned char slave_addr, unsigned char reg_addr);
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__

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.c

#include "iic.h"
#include "si7006.h"
extern void delay_ms(unsigned int ms);
/** 函数名:si7006_init* 函数功能:SI7006芯片的初始化* 函数参数:无* 函数返回值:无
*/
void si7006_init(void)
{i2c_start();i2c_init();i2c_write_byte(SI7006_SLAVE << 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, 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(1000);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, 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(1000);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 "iic.h"
#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", 125 * hum / 65536 - 6);printf("temp = %d\n", 175 * temp / 65536 - 47);}return 0;
}

 

相关文章:

arm:day9

1。思维导图 2..I2C实验&#xff0c;检测温度和湿度 iic.h #ifndef __IIC_H__ #define __IIC_H__ #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_rcc.h" #include "gpio.h" /* 通过程序模拟实现I2C总线的时序和协议* GPIOF ---> AHB4…...

【大模型AIGC系列课程 1-2】创建并部署自己的ChatGPT机器人

OpenAI API 调用 获取 openai api api-key https://platform.openai.com/account/api-keys 利用 python requests 请求 openai 参考 openai 接口说明:https://platform.openai.com/docs/api-reference/chat/create import json # 导入json包 import requests # 导入req…...

启动metastore服务报错

启动Metastore的时候报错&#xff1a; 简略的报错信息&#xff1a; MetaException(message:Error creating transactional connection factory)Caused by: MetaException(message:Error creating transactional connection factory)Caused by: javax.jdo.JDOFatalInternalExce…...

c 语言 算法 技巧 之 用移位来代替乘除

除法 当你需要计算一个数的一半时&#xff0c;通常我们会考虑使用除法运算&#xff08;/&#xff09;来实现。然而&#xff0c;计算机内部的运算中&#xff0c;除法通常比加法和乘法运算慢得多&#xff0c;因为除法需要更多的处理步骤。 位运算在这种情况下可以提供一个快速的…...

python爬虫实战零基础(3)——某云音乐

爬取某些云网页音乐&#xff0c;无需app 分析网页第二种方式批量爬取 声明&#xff1a;仅供参考学习&#xff0c;参考&#xff0c;若有不足&#xff0c;欢迎指正 你是不是遇到过这种情况&#xff0c;在pc端上音乐无法下载&#xff0c;必须下载客户端才能下载&#xff1f; 那么&…...

渗透测试漏洞原理之---【XSS 跨站脚本攻击】

文章目录 1、跨站 脚本攻击1.1、漏洞描述1.2、漏洞原理1.3、漏洞危害1.4、漏洞验证1.5、漏洞分类1.5.1、反射性XSS1.5.2、存储型XSS1.5.3、DOM型XSS 2、XSS攻防2.1、XSS构造2.1.1、利用<>2.1.2、JavaScript伪协议2.1.3、时间响应 2.2、XSS变形方式2.2.1、大小写转换2.2.2…...

【浮点数二分】

数的三次方根 #include<iostream> using namespace std;double n;int main(){cin>>n;double l -10000;double r 10000;while((r-l)>1e-8){double mid (lr)/2;if((mid*mid*mid)>n) r mid;else l mid;}printf("%lf",l);return 0; }...

基于FPGA的FIR低通滤波器实现(附工程源码),matlab+vivado19.2+simulation

基于FPGA的FIR低通滤波器实现(附工程源码) 文章目录 基于FPGA的FIR低通滤波器实现(附工程源码)前言一、matlab设计FIR滤波器&#xff0c;生成正弦波1.设计FIR滤波器1.生成正弦波.coe 二、vivado1.fir滤波器IP核2.正弦波生成IP核3.时钟IP核设置4.顶层文件/测试文件代码 三.simul…...

c++ qt--事件(第六部分)

c qt–事件&#xff08;第六部分&#xff09; 一.编辑伙伴&#xff0c;编辑顺序&#xff08;按TAB进行切换&#xff09; 1.编辑伙伴 此功能在设计界面如下的位置 1.设置伙伴关系 鼠标左键长按一个Label组件然后把鼠标移到另一个组件上 2.伙伴关系的作用 伙伴关系的作用就是…...

嵌入式系统入门实战:探索基本概念和应用领域

嵌入式系统是一种专用的计算机系统,它是为了满足特定任务而设计的。这些系统通常具有较低的硬件资源(如处理器速度、内存容量和存储容量),但具有较高的可靠性和实时性。嵌入式系统广泛应用于各种领域,如家用电器、汽车、工业控制、医疗设备等。 嵌入式系统的基本概念 微控…...

关于hive sql进行调优的理解

这是一个面试经常面的问题&#xff0c;很不幸&#xff0c;在没有准备的时候&#xff0c;我面到了这个题目&#xff0c;反思了下&#xff0c;将这部分的内容进行总结&#xff0c;给大家一点分享。 hive其实是基于hadoop的数据库管理工具&#xff0c;底层是基于MapReduce实现的&a…...

十大排序算法

一、冒泡排序 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单直观的排序算法。它重复地走访要排序的数列&#xff0c;一次比 较两个元素&#xff0c;如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换&#xff0c;也就是说该数列已经…...

PIP 常用操作汇总

1. 升级 python -m pip install --upgrade pip2. 列出所有安装包 pip list3. 查找特定包 pip list | findstr xxx4. 查看特定包 pip show xxx5. 安装软件包 pip install pyzmq24.0.16. 卸载软件包 pip uninstall -y pyzmq7. 查看配置 # 生效的配置&#xff08;global -&…...

线性代数的本质笔记(3B1B课程)

文章目录 前言向量矩阵行列式线性方程非方阵点积叉积基变换特征向量与特征值抽象向量空间 前言 最近在复习线代&#xff0c;李永乐的基础课我刷了一下&#xff0c;感觉讲的不够透彻&#xff0c;和我当年学线代的感觉一样&#xff0c;就是不够形象。 比如&#xff0c;行列式为…...

快速掌握MQ消息中间件rabbitmq

快速掌握MQ消息中间件rabbitmq 目录概述需求&#xff1a; 设计思路实现思路分析1.video 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for change,c…...

Git push拦截

遇到的问题 今天想提交代码到gitee&#xff0c;结果发现被拦截了&#xff0c;有段提示“forbidden by xxxx”… 我记得xxxx好像是公司的一个防泄密的东西… 这个东西是怎么实现的呢&#xff1f; 解决 原来git提供很多hook&#xff0c;push命令就有一个pre-push的hook&#x…...

拼多多anti-token分析

前言&#xff1a;拼多多charles抓包分析发现跟商品相关的请求头里都带了一个anti-token的字段且每次都不一样,那么下面的操作就从分析anti-token开始了 1.jadx反编译直接搜索 选中跟http相关的类对这个方法进行打印堆栈 结合堆栈方法调用的情况找到具体anti-token是由拦截器类f…...

基于微信小程序的中医体质辨识文体活动的设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于微信小程序的中医体质辨识文体活动的设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java s…...

4.16 TCP 协议有什么缺陷?

目录 升级 TCP 的工作很困难 TCP 建立连接的延迟 TCP 存在队头阻塞问题 网络迁移需要重新建立 TCP 连接 升级 TCP 的工作很困难&#xff1b;TCP 建立连接的延迟&#xff1b;TCP 存在队头阻塞问题&#xff1b;网络迁移需要重新建立 TCP 连接&#xff1b; 升级 TCP 的工作很…...

VMware 修改ip地址 虚拟机静态ip设置 centos动态ip修改为静态ip地址 centos静态ip地址 vmware修改ip地址

虚拟机的centos服务器经常变换ip&#xff0c;测试起来有些麻烦&#xff0c;故将动态ip修改为静态ip 1. 查看vmware 虚拟机网络配置&#xff1a; 点击编辑&#xff0c;打开虚拟网络配置 2. 选中nat模式&#xff0c;点击nat设置&#xff0c;最终获取网关ip: 192.168.164.2 3. 进…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...