ARM day8

1.题目:主机获取从机里面的温湿度数据,并打印出来

结果:

 

代码:

main.c

#include "iic.h"#include "si7006.h"void delay(int ms){int i,j;for(i=0;i<ms;i++){for(j=0;j<2000;j++);}}int main(){short tem;//用于保存 温度数据和湿度数据unsigned short hum;//进行SI7006的初始化si7006_init();while(1){//读取温度tem=si7006_read_temp_data(0X40,0XE3);hum=si7006_read_hum_data(0x40,0XE5);//读取湿度//数据转换tem=tem*175.72/65536-46.85;hum=hum*125/65536-6;//数据输出delay(1000);printf("tem:%d\n",tem);printf("hum:%d\n",hum);}return 0;}

si7006.c

#include "iic.h"
#include "si7006.h"
void deley(int ms)
{int i,j;for(i=0;i<ms;i++){for(j=0;j<2000;j++);}
}
/** 函数名:si7006_init* 函数功能:SI7006芯片的初始化* 函数参数:无* 函数返回值:无
*/ 
//往SI7006芯片0XE6写入0X3A
void si7006_init(void)
{//I2初始化i2c_init();//发送起始信号i2c_start();//主机发送7位从机地址+1位写位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_hum_data* 函数功能:读取SI7006的湿度转换结果* 函数参数:*     slave_addr : 从机地址*     cmd_code : 命令码* 函数返回值:湿度测量的数字量
*/
unsigned short si7006_read_hum_data(unsigned char slave_addr, unsigned char cmd_code)
{unsigned short dat;//保存读取到的湿度数据unsigned char dat_h,dat_l;//保存读取到的数据的高八位和低八位//发送起始信号i2c_start();//主机发送7位从机地址+1位写位i2c_write_byte(slave_addr<<1|0);//等待从机回应i2c_wait_ack();//发送寄存器地址i2c_write_byte(cmd_code);//等待从机回应i2c_wait_ack();//发送第二次起始信号i2c_start();//主机发送7位从机地址+1位写位i2c_write_byte(slave_addr<<1|1);//等待从机回应i2c_wait_ack();//延时等待从机测量数据deley(100);//读取数据的高8位dat_h=i2c_read_byte(0);//读取完毕发送应答信号//读取数据的低8位dat_l=i2c_read_byte(1);//读取完毕发送非应答信号//发送停止信号i2c_stop();//将读取到的数据整合到一起dat=(dat_h<<8)|dat_l;return dat;
}
/** 函数名:si7006_read_temp_data* 函数功能:读取SI7006的温度转换结果* 函数参数:*     slave_addr : 从机地址*     cmd_code : 命令码 寄存器地址* 函数返回值:温度测量的数字量
*/
short si7006_read_temp_data(unsigned char slave_addr, unsigned char cmd_code)
{short dat;//保存读取到的温度数据char dat_h,dat_l;//保存读取到的数据的高八位和低八位//发送起始信号i2c_start();//主机发送7位从机地址+1位写位i2c_write_byte(slave_addr<<1|0);//等待从机回应i2c_wait_ack();//发送寄存器地址i2c_write_byte(cmd_code);//等待从机回应i2c_wait_ack();//发送第二次起始信号i2c_start();//主机发送7位从机地址+1位写位i2c_write_byte(slave_addr<<1|1);//等待从机回应i2c_wait_ack();//延时等待从机测量数据deley(100);//读取数据的高8位dat_h=i2c_read_byte(0);//读取完毕发送应答信号//读取数据的低8位dat_l=i2c_read_byte(1);//读取完毕发送非应答信号//发送停止信号i2c_stop();//将读取到的数据整合到一起dat=(dat_h<<8)|dat_l;return dat;
}

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 cmd_code);short si7006_read_temp_data(unsigned char slave_addr, unsigned char cmd_code);#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     \*          --------* */   //保证数据线PF15是输出SET_SDA_OUT;//空闲状态时钟线和数据线拉高I2C_SCL_H;I2C_SDA_H;delay_us();I2C_SDA_L;//数据线拉低delay_us();I2C_SCL_L;//时钟线拉低,此时I2C总线处于被占用状态
}/** 函数名:i2c_stop* 函数功能:模拟i2c停止信号的时序* 函数参数:无* 函数返回值:无* */void i2c_stop(void)
{/** 停止信号 : 时钟在高电平期间,数据线从低到高的变化 *             ----------* SCL        /*    --------*    ---         -------* SDA   X       /*    --- -------* *///确保SDA是输出状态 PF15输出SET_SDA_OUT;//时钟线拉低I2C_SCL_L;//方便一会儿将数据线电平拉低delay_us();//延时等待一段时间I2C_SDA_L;//数据线拉低delay_us();//延时等待一段时间//时钟线拉高I2C_SCL_H;delay_us();//延时等待一段时间I2C_SDA_H;//数据线拉高}/** 函数名: i2c_write_byte* 函数功能:主机向i2c总线上的从设备写8bits数据* 函数参数:dat : 等待发送的字节数据* 函数返回值: 无* */void i2c_write_byte(unsigned char dat)
{/** 数据信号:时钟在低电平期间,发送器向数据线上写入数据*          时钟在高电平期间,接收器从数据线上读取数据 *      ----          --------*  SCL     \        /        \*           --------          --------*      -------- ------------------ ---*  SDA         X                  X*      -------- ------------------ ---**      先发送高位在发送低位 * *///确保SDA是输出状态 PF15输出SET_SDA_OUT;unsigned int i;for(i=0;i<8;i++){//时钟线拉低I2C_SCL_L;delay_us();//延时//0X3A->0011 1010   0X80->10000000if(dat&0X80)//最高位为1{//发送1I2C_SDA_H;}else  //最高位为0{I2C_SDA_L;//发送0}delay_us();//延时//时钟线拉高,接收器接收I2C_SCL_H;delay_us();//延时,用于等待接收器接收数据delay_us();//延时//将数据左移一位,让原来第6位变为第7位dat = dat<<1;}}/** 函数名: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;for(i=0;i<8;i++){//先把时钟线拉低,等一段时间,保证发送器发送完毕数据I2C_SCL_L;delay_us();delay_us();//保证发送器发送完数据//时钟线拉高,读取数据I2C_SCL_H;       delay_us();dat=dat<<1;//数值左移  0000 0000if(I2C_SDA_READ)//pf15管脚得到了一个高电平输入{dat |=1; //0000 0110}else{dat &=(~0X1);}delay_us();}if(ack){i2c_nack();//发送非应答信号,不再接收下一次数据}else{i2c_ack();//发送应答信号 }return dat;
}
/** 函数名: i2c_wait_ack* 函数功能: 主机作为发送器时,等待接收器返回的应答信号* 函数参数:无* 函数返回值:*                  0:接收到的应答信号*                  1:接收到的非应答信号* */
unsigned char i2c_wait_ack(void)
{/** 主机发送一个字节之后,从机给主机返回一个应答信号**                   -----------* SCL              /   M:读    \*     -------------             --------*     --- ---- --------------------* SDA    X    X*     ---      --------------------*     主  释   从机    主机*     机  放   向数据  读数据线*         总   线写    上的数据*         线   数据* */   //时钟线拉低,接收器可以发送信号I2C_SCL_L;I2C_SDA_H;//先把数据线拉高,当接收器回应应答信号时,数据线会拉低delay_us();SET_SDA_IN;//设置数据线为输入delay_us();//等待接收方向数据线写入delay_us();I2C_SCL_H;//用于读取数据线数据if(I2C_SDA_READ)//PF15得到一个高电平输入,收到非应答信号return 1;I2C_SCL_L;//时钟线拉低,让数据线处于占用状态return 0;
} 
/** 函数名: iic_ack* 函数功能: 主机作为接收器时,给发送器发送应答信号* 函数参数:无* 函数返回值:无* */
void i2c_ack(void)
{/*            --------* SCL       /        \*    -------          ------*    ---* SDA   X *    --- -------------* *///保证数据线是输出SET_SDA_OUT;I2C_SCL_L;//拉低时钟线delay_us();I2C_SDA_L;//数据线拉低,表示应答信号delay_us();I2C_SCL_H;//时钟线拉高,等待发送器读取应答信号delay_us();delay_us();I2C_SCL_L;//数据线处于占用状态,发送器发送下一次数据
}
/** 函数名: iic_nack* 函数功能: 主机作为接收器时,给发送器发送非应答信号* 函数参数:无* 函数返回值:无* */
void i2c_nack(void)
{/*            --------* SCL       /        \*    -------          ------*    --- ---------------* SDA   X *    --- * */   //保证数据线是输出SET_SDA_OUT;I2C_SCL_L;//拉低时钟线delay_us();I2C_SDA_H;//数据线拉高,表示非应答信号delay_us();I2C_SCL_H;//时钟线拉高,等待发送器读取应答信号delay_us();delay_us();I2C_SCL_L;//数据线处于占用状态,发送器发送下一次数据
}

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 

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

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

相关文章

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

目录 ​编辑 6.2.4 修改字典中的值 6.2.5 删除键—值对 注意 删除的键—值对永远消失了。 6.2.6 由类似对象组成的字典 6.3 遍历字典 6.3.1 遍历所有的键—值对 6.3.2 遍历字典中的所有键 往期快速传送门&#x1f446;&#xff08;在文章最后&#xff09;&#xff1a; 6.…

【网络编程之初出茅庐】

前言&#xff1a;本章主要先讲解一些基本的网络知识&#xff0c;先把基本的知识用起来&#xff0c;后续会更深入的讲解底层原理。 网络编程的概念 网络编程&#xff0c;指网络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的方式实现网络通信&#xff08;或称为网络数…

网络基础(九):VLAN的概述及配置

目录 前言 一、分割广播域的方法 二、VLAN 1、VLAN的概述及优势 1.1VLAN的概述 1.2VLAN的优势 2、VLAN的种类 3、VLAN的三种端口类型 4、VLAN 的工作原理 4.1VLAN数据帧 4.2VLAN的范围 4.2VLAN的access类型工作原理 4.3VLAN的trunk类型工作原理 4.4VLAN的Hybird类…

CentOS7安装MySQL8.0

一、使用Yum安装 1. 使用wget下载MySQL的rpm包 wget https://repo.mysql.com//mysql80-community-release-el7-3.noarch.rpm2. 安装下载好的rpm包 yum localinstall mysql80-community-release-el7-3.noarch.rpm 3. 安装mysql&#xff08;该步可能出现问题&#xff09; yum…

JAVAEE-8-线程池

池 我们之前也接触过,比如说常量池,数据库连接池,线程池,进程池,内存池等等, 池的共性: 1.提前把要用的对象准备好 2.把用完的对象也不要立即释放,先留着以备下次使用 来提高效率!!! 最开始,进程能够解决并发编程的问题,因为频繁创建销毁进程的开销成本太大了,所以我们引…

新版Spring Security6.2案例 - Basic HTTP Authentication

前言&#xff1a; 书接上文&#xff0c;翻译官网Authentication的Username/Password这页&#xff0c;接下来继续翻译basic的这页&#xff0c;因为官网说的都是原理性的&#xff0c;这边一个小案例关于basic http authentication。 Basic Authentication 本节介绍 HTTP 基本身…

Unity 通过鼠标控制模拟人物移动和旋转视角

要通过鼠标控制并模拟人物移动和转换视角&#xff0c;将会使用射线检测、鼠标点击和鼠标水平移动&#xff0c;配合物体旋转和移动方法共同实现。 首先搭建个由一个Plane地板和若干cube组成的简单场景&#xff1a; 其次创建一个Capsule作为移动物体&#xff0c;并把摄像头拉到该…

腾讯云优惠券领取指南

腾讯云优惠券是降低云服务成本的有效手段&#xff0c;无论是新用户还是老用户&#xff0c;都可以通过下面方法领取到适合自己的优惠券。 1、腾讯云优惠券领取 领取入口&#xff1a;txy.ink 2、腾讯云优惠券介绍 腾讯云优惠券包括代金券和折扣券&#xff0c;代金券可以在结算…

【CCF BDCI 2023】多模态多方对话场景下的发言人识别 Baseline 0.71 CNN 部分

【CCF BDCI 2023】多模态多方对话场景下的发言人识别 Baseline 0.71 CNN 部分 概述CNN 简介数据预处理查看数据格式加载数据集 图像处理限定图像范围图像转换加载数据 CNN 模型Inception 网络ResNet 残差网络总结参数设置 训练 Train模型初始化数据加载训练超参数训练循环 验证…

Python 从入门到精通 学习笔记 Day04

Python 从入门到精通 第四天 今日目标 数据类型-又见str、数据类型-又见list 列表切片&排序&反转&循环、字典 数据类型 - 又见str 字符串定义 字符串是一个有序的字符的集合&#xff0c;用于在计算机里存储和表示文本信息 创建 a "Hello ,my name is Ha…

Android---Kotlin 学习005

substring 字符串截取。相加与 java&#xff0c;kt 里面的 substring 函数支持 IntRange 类型&#xff08;表示一个整数范围的类型&#xff09;的参数&#xff0c;until 创建的范围不包括上限值。 const val NAME "Jimmys friend" fun main(){val index NAME.ind…

TrustGeo代码理解(二)test.py

代码链接&#xff1a;https://github.com/ICDM-UESTC/TrustGeo 一、加载检查点&#xff08;checkpoint&#xff09;并进行测试 # -*- coding: utf-8 -*-"""load checkpoint and then test """ 该脚本的目的是加载之前训练过的模型的检查点&am…

【Linux】基于sed正则指令修改application.properties属性值

文章目录 背景sed介绍演示结果 背景 服务器上搭建了SpringCloud微服务&#xff0c;每个服务中都有application.properties文件&#xff0c;在部署过程中需要修改每个微服务的redis.ip和redis.port。如果手动去修改会很麻烦&#xff0c;所以下面写了一个shell脚本&#xff08;基…

idea的快捷键

1.调整字体的大小 文件夹的循序:setting-Editor-Font 界面: 2.删除当前行 文件夹的循序:setting-Keymap-DeleteLine 界面: 3.导入该行需要的类 文件夹的循序:setting-Editor-General-Auto import 界面: 4.格式化代码 文件夹的循序:setting-keymap-Reformat 界面: 5.快速…

大模型微调方法:冻结方法 Freeze、P-Tuning 系列、LoRA、QLoRA

大模型微调方法 冻结方法 FreezeP-Tuning 系列Prefix-TuningPrompt TuningP-Tuning v1P-Tuning v2 LoRAQLoRA 冻结方法 Freeze 方法意思是&#xff0c;只用少部分参数训练&#xff0c;把模型的大部分参数冻结。 只要设置微调层的参数&#xff1a; # 遍历模型的所有参数和名称…

程序员的养生之道:延寿健康的十大秘诀(下)

程序员的养生之道&#xff1a;延寿健康的十大秘诀&#xff08;上&#xff09;-CSDN博客 目录 6. 心理调节&#xff0c;减轻压力 6.1 程序员常见的心理问题 6.2 压力管理的重要性 6.3 放松技巧与应对策略 6.4 积极心态与心理健康 7. 正确坐姿&#xff0c;保护颈椎腰椎 …

VLAN协议与单臂路由

文章目录 VLAN协议与单臂路由一、VLAN的概念及优势1、分割广播域2、VLAN的优势3、VLAN数据帧 二、VLAN的种类1、静态VLAN2、动态VLAN3、VLAN划分方式 三、静态VLAN的配置1、VLAN的范围2、静态VLAN的配置2.1 配置静态VLAN的步骤2.2 vlan三种端口类型举例&#xff1a;配置静态VLA…

VR全景直播来临,沉浸式代入吸引百万人目光

如今&#xff0c;VR技术正在不断改变着直播行业的面貌&#xff0c;为观众提供沉浸式的观看体验。在5G技术的快速发展背景下&#xff0c;VR全景直播作为5G应用的场景&#xff0c;被广泛应用在体育赛事、新闻会议、演唱会、教育医疗等场景&#xff0c;通过VR技术进行全景直播&…

c语言结构体调用格式与对齐

1.声明形式&#xff1a; struct 结构体名字 { 结构体成员 }结构体变量名&#xff1b; 2.赋值方法 3.结构体对齐&#xff1a; 1.起始偏移量&#xff1a;默认结构体第一个元素对齐0起始偏移量&#xff0c;第一个元素占一个字节&#xff0c;此时偏移量为1. 2.标准数&#xff…

基于stm32 FP-AUD-SMARTMIC1 音频系统开发

基于stm32 FP-AUD-SMARTMIC1 音频系统开发 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,+群赠送语音信号处理降噪算法,蓝牙耳机音频,DSP音频项目核心开发资料, FP-AUD-SMARTMIC1 是一个用于 STM32F4Discovery …