STM32 GPIO模拟I2C的SHT20温湿度采样
要用GPIO模拟I2C,那么首先就得弄清楚I2C的时序。
1.I2C总线通信时序
2.起始与结束时序
//起始信号 uint8_t I2c_StartCondition() {uint8_t rv = NO_ERROR;SDA_OUT();SCL_OUT();/* StartCondition(S): A high to low transition on the SDA line while SCL is high._______SCL: |________SDA: |_____*/SDA_H();delay_us(2);SCL_H();delay_us(2);SDA_L();//先于SCL前拉低delay_us(2);SCL_L();//拉低SCL便于之后的操作delay_us(2);return rv;}
//终止信号 uint8_t I2c_StopCondition(void) {uint8_t rv = NO_ERROR;SDA_OUT();/* StopCondition(P): A low to high transition on the SDA line while SCL is high.————————————SCL: — — —_____SDA: ___|*/SCL_L();SDA_L();delay_us(2);SCL_H();delay_us(2);SDA_H();delay_us(2);return rv; }
3.读写时序
//写一个byte uint8_t I2c_WriteByte(uint8_t byte) {uint8_t rv = NO_ERROR;uint8_t mask;/* Data line changes must happened when SCL is low */SDA_OUT();SCL_L();/* 1Byte=8bit, MSB send: bit[7]-->bit[0] */for(mask=0x80; mask>0; mask>>=1){if((mask & byte) == 0){SDA_L();}else{SDA_H();}delay_us(5); // data set-up time (t_SU;DAT)SCL_H();delay_us(5); // SCL high time (t_HIGH)SCL_L();delay_us(5); // data hold time(t_HD;DAT)}/* clk #9 wait ACK/NAK from slave */SDA_IN();SCL_H(); // clk #9 for ackdelay_us(5); // data set-up time (t_SU;DAT)//从机应答if( READ_SDA() )rv = ACK_ERROR; OUT:SCL_L();delay_us(20);return rv; }
//读一个byte uint8_t I2c_ReadByte(uint8_t *byte, uint8_t ack) {uint8_t rv = NO_ERROR;uint8_t mask;*byte = 0x00;SDA_IN(); /* 1Byte=8bit, MSB send: bit[7]-->bit[0] */for(mask = 0x80; mask > 0; mask >>= 1){SCL_H(); // start clock on SCL-linedelay_us(2); // clock set-up time (t_SU;CLK)if(READ_SDA())*byte |= mask; // read bitSCL_L();delay_us(2); // data hold time(t_HD;DAT)}/* clk #9 send ACK/NAK to slave */if(ack == ACK){SDA_OUT();SDA_L(); // send Acknowledge if necessary}else if( ack == NAK ){SDA_OUT();SDA_H(); // send NotAcknowledge if necessary}delay_us(1); // data set-up time (t_SU;DAT)SCL_H(); // clk #9 for ackdelay_us(2); // SCL high time (t_HIGH) OUT:SCL_L();delay_us(2); // wait to see byte package on scopereturn rv; }
注意:
1.无论是写入一个byte还是读出一个byte,都是从MSB到LSB
2.要改变SDA状态时,都是在SCL为低时改变,如果在SCL为高时改变,将被视为开始或结束信号。
4.封装收发信号
//接受从机发来的信号 int I2C_Master_Receive(uint8_t addr, uint8_t *buf, int len) {int i;int rv = NO_ERROR;uint8_t byte;I2c_StartCondition();rv = I2c_WriteByte(addr);if( rv ){sht20_printf("Send I2C read address failure, rv=%d\n", rv);goto OUT;}for (i=0; i<len; i++){if( !I2c_ReadByte(&byte, ACK) ){buf[i] = byte;}elsegoto OUT;} OUT:I2c_StopCondition();return rv; }
//发送一个命令 int I2C_Master_Transmit(uint8_t addr, uint8_t *data, int bytes) {int i;int rv = NO_ERROR;if(!data){return PARM_ERROR;}sht20_printf("I2C Mastr start transimit [%d] bytes data to addr [0x%02x]\n", bytes, addr);I2c_StartCondition();rv = I2c_SendAddress(addr);if( rv ){goto OUT;}for (i=0; i<bytes; i++){if( NO_ERROR != (rv=I2c_WriteByte(data[i])) ){break;}} OUT:I2c_StopCondition();return rv; }
5.主函数
采用默认的采样精度,温度采样精度14bit,湿度采样精度12bit,采样测量时间如下图1:
图1采样测量时间
图2命令
注意:
1. I2C总线上的从机都有自己的地址,方便主机选择通信,sht20的地址为0x40,加上最后一位读写位的话,写地址为0x80,读地址为0x81。(非保持主机模式采样)
2. 发送采样命令后要等待采样测量时间之后再去读取数据。
//没有检查检验和
short sht20_sample_temp_or_hum(uint8_t cmd)
{uint8_t data[2];unsigned short sht20_data=0;int rv;
// uint8_t tran_cmd=0xF3;rv=I2C_Master_Transmit(0x80,&cmd,1);if(0!=rv)return -1;if(cmd==0xf3)HAL_Delay(85);else if(cmd==0xf5)HAL_Delay(29);rv=I2C_Master_Receive(0x81,data,sizeof(data));if(0!=rv)return -1;sht20_data=data[0];sht20_data=(sht20_data<<8);sht20_data+=data[1]&0xFC;if(cmd==0xf3){sht20_data=(short)((-46.85+175.72*sht20_data/65536)*(10));//计算}else if(cmd==0xf5){sht20_data=(short)((-6.0+125.0*sht20_data/65536)*(10));//计算}printf("sht20_data=%d\n",sht20_data);return sht20_data;
}
运行结果:
温度测量:
湿度测量:(单位用H代替)
STM32 GPIO模拟I2C的SHT20温湿度采样相关推荐
- STM32 通用GPIO模拟I2C实现
STM32 通用GPIO模拟I2C实现 通用GPIO模拟I2C通信实现样例 1 GPIO初始化 #ifdef HW_I2C1 //硬件I2C初始化//PA8-I2C1_SCLGPIO_StructIn ...
- 外设驱动库开发笔记8:GPIO模拟I2C驱动
I2C总线简单方便,是我们经常使用的一种总线.但有时候我们的MCU没有足够多的I2C控制器来实现我们的应用,所幸我可以使用普通的GPIO引脚来模拟低速的I2C总线通信.这一节我们就来实现使用软件通过普 ...
- STM32实现基于I2C的AHT20温湿度采集
STM32实现基于I2C的AHT20温湿度采集 I2C通信协议 软件I2C与 硬件I2C 代码实现 烧录 硬件连接 烧录并运行 参考 I2C通信协议 I2C协议简介 IC( Inter-- Integ ...
- STM32使用模拟I2C读取硒翔30mL流量传感器
使用模拟I2C读取硒翔30mL/min流量传感器 该工程使用某些采样次数和时间不同会采集到的报文有问题. 我建议是可以换个次数和时间调下. 如果报文有问题的话 就修改延时就好了,延时指的是I2C每发送 ...
- STM32单片机硬件I2C读取AHT10温湿度传感器数据
STM32使用硬件IIC读取AHT10温湿度传感器的数据并显示在0.96寸OLED屏上. 我用的单片机是STM32F103C8T6,程序用的是ST标准库写的. STM32使用硬件I2C读取SHTC3温 ...
- GPIO模拟I2C程序实现
GPIO模拟I2C程序实现. I2C是由Philips公司发明的一种串行数据通信协议,仅使用两根信号线:SerialClock(简称SCL)和SerialData(简称SDA).I2C是总线结构,1个 ...
- Linux I2C子系统分析之(一) ----- 用GPIO模拟I2C总线
在drivers/i2c/busses下包含各种I2C总线驱动,如S3C2440的I2C总线驱动i2c-s3c2410.c,使用GPIO模拟I2C总线的驱动i2c-gpio.c,这里只分析i2c-gp ...
- S5PV210之GPIO模拟I2c时序之pcf8591与at24xx linux3.0.8驱动
目录:一. 说明 二. 驱动程序说明及问题 三. 案例一 四. 案例二 一. 说明 mini210开发板上带了at24c08, 看了linux内核自带的at24.c的驱动程序,编译下载到看 ...
- linux源码gpio模拟i2c,linux内核gpio模拟i2c实例.doc
linux内核gpio模拟i2c实例.doc linux内核GPIO模拟I2C实例2010-10-11作者:cvip302814来源:cvip302814的blog前言:在许多情况下,我们并没有足够的 ...
- i2c 驱动五:gpio模拟i2c
有关linux的i2c相关文章有一下几篇,他们互相关联,应该一同看: - i2c 驱动一:简介 - i2c 驱动二:devfs文件系统 - i2c 驱动三:自己实现设备和驱动分离 - i2c 驱动四: ...
最新文章
- 新车模、新舵机、新体验
- The NVIDIA driver on your system is too old
- 印发 指南 通知_通知设计的综合指南
- 获取可用密码算法的列表
- java random用法_JAVA面试题(1)
- 计算机网络第七版总结报告,计算机网络(第七版)第一章总结(超详细!)
- Kubernetes 版本锁定到1.12.3
- 大数据系列之分布式数据库HBase-1.2.4+Zookeeper 安装及增删改查实践
- Java开发环境搭建及开发软件和服务器安装与配置
- 云南省电子计算机高级,计算机基础知识-云南省电子信息高级技工学校.ppt
- 苹果手机壳_潮牌刺绣苹果8 Plus手机壳,让爱机焕然一新
- 微信公众号验签过程详解--前端和后端的操作
- centos 6.5 安装qt5.2
- 气象报告是什么计算机领域,计算机辅助翻译系统在亚运气象服务方面的应用报告...
- 【论文】 各高校的毕业论文的Latex模板链接
- S1200和博途软件通讯测试,S7-1200博途和组态王软件通讯(高端培训).pdf
- qt 设计师界面 图片_如果没有设计界面,设计师会发生什么?
- ZOJ 1428 Magazine Delivery
- 【操作系统基础】操作系统的分类与发展
- 关于三角形面积的公式与格点多边形面积计算算法的讨论