STM32之IIC通讯升级版--SHT30温湿度读取

发布者:CelestialLight最新更新时间:2021-10-14 来源: eefocus关键字:STM32  IIC通讯  SHT30 手机看文章 扫描二维码
随时随地手机看文章

针对上篇文章对于程序可移植性不强的问题进行优化,基本思路是首先搭建好IIC底层驱动程序,该程序可用于任何IIC通讯设备,然后针对不同的IIC设备单独编写应用程序,本篇文章仍以SHT30为例。


一、IIC底层驱动之myiic.h


#ifndef __MYIIC_H

#define __MYIIC_H

#include "sys.h"

           

//IO方向设置

#define SDA_IN()  {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}

#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}


//IO操作函数  

#define IIC_SCL    PCout(12) //SCL

#define IIC_SDA    PCout(11) //SDA  

#define READ_SDA   PCin(11)  //输入SDA 


//IIC所有操作函数

void IIC_Init(void);                //初始化IIC的IO口  

void IIC_Start(void); //发送IIC开始信号

void IIC_Stop(void);   //发送IIC停止信号

void IIC_Send_Byte(u8 txd); //IIC发送一个字节

u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节

u8 IIC_Wait_Ack(void); //IIC等待ACK信号

void IIC_Ack(void); //IIC发送ACK信号

void IIC_NAck(void); //IIC不发送ACK信号


void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);

u8 IIC_Read_One_Byte(u8 daddr,u8 addr);   


#endif


二、IIC底层驱动之myiic.c


#include "myiic.h"

#include "delay.h"



//初始化IIC

void IIC_Init(void)

{      

GPIO_InitTypeDef GPIO_InitStructure;

//RCC->APB2ENR|=1<<4;//先使能外设IO PORTC时钟 

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );

   

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_11;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure);

 

IIC_SCL=1;

IIC_SDA=1;


}

//产生IIC起始信号

void IIC_Start(void)

{

SDA_OUT();     //sda线输出

IIC_SDA=1;     

IIC_SCL=1;

delay_us(4);

  IIC_SDA=0;//START:when CLK is high,DATA change form high to low 

delay_us(4);

IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 

}   

//产生IIC停止信号

void IIC_Stop(void)

{

SDA_OUT();//sda线输出

IIC_SCL=0;

IIC_SDA=0;//STOP:when CLK is high DATA change form low to high

  delay_us(4);

IIC_SCL=1; 

IIC_SDA=1;//发送I2C总线结束信号

delay_us(4);    

}

//等待应答信号到来

//返回值:1,接收应答失败

//        0,接收应答成功

u8 IIC_Wait_Ack(void)

{

u8 ucErrTime=0;

SDA_IN();      //SDA设置为输入  

IIC_SDA=1;delay_us(1);    

IIC_SCL=1;delay_us(1);  

while(READ_SDA)

{

ucErrTime++;

if(ucErrTime>250)

{

IIC_Stop();

return 1;

}

}

IIC_SCL=0;//时钟输出0    

return 0;  

//产生ACK应答

void IIC_Ack(void)

{

IIC_SCL=0;

SDA_OUT();

IIC_SDA=0;

delay_us(2);

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

}

//不产生ACK应答     

void IIC_NAck(void)

{

IIC_SCL=0;

SDA_OUT();

IIC_SDA=1;

delay_us(2);

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

}      

//IIC发送一个字节

//返回从机有无应答

//1,有应答

//0,无应答   

void IIC_Send_Byte(u8 txd)

{                        

    u8 t;   

SDA_OUT();     

    IIC_SCL=0;//拉低时钟开始数据传输

    for(t=0;t<8;t++)

    {              

        IIC_SDA=(txd&0x80)>>7;

        txd<<=1;   

delay_us(2);   //对TEA5767这三个延时都是必须的

IIC_SCL=1;

delay_us(2); 

IIC_SCL=0;

delay_us(2);

    }  

}     

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   

u8 IIC_Read_Byte(unsigned char ack)

{

unsigned char i,receive=0;

SDA_IN();//SDA设置为输入

    for(i=0;i<8;i++ )

{

        IIC_SCL=0; 

        delay_us(2);

IIC_SCL=1;

        receive<<=1;

        if(READ_SDA)receive++;   

delay_us(1); 

    }  

    if (!ack)

        IIC_NAck();//发送nACK

    else

        IIC_Ack(); //发送ACK   

    return receive;

}


三、IIC设备之SHT30.H


#ifndef SHT30_H

#define SHT30_H

#include "delay.h"

#include "sys.h"

#include "stdio.h"

#include "usart.h"

#include "string.h"


extern u8 humiture_buff1[20];

void SHT30_read_result(u8 addr);

 

#endif



四、IIC设备之SHT30.c


#include "SHT30.h" 

#include "myiic.h"



#define write 0

#define read  1


float humiture[4];

u8 humiture_buff1[20];


/*******************************************************************

 温湿度获取函数               

函数原型: SHT30_read_result(u8 addr);

功能: 用来接收从器件采集并合成温湿度

********************************************************************/ 

void SHT30_read_result(u8 addr)

{

u16 tem,hum;

u16 buff[6];

float Temperature=0;

float Humidity=0;

IIC_Start();

IIC_Send_Byte(addr<<1 | write);//写7位I2C设备地址加0作为写取位,1为读取位

IIC_Wait_Ack();

IIC_Send_Byte(0x2C);

IIC_Wait_Ack();

IIC_Send_Byte(0x06);

IIC_Wait_Ack();

IIC_Stop();

delay_ms(50);

IIC_Start();

IIC_Send_Byte(addr<<1 | read);//写7位I2C设备地址加0作为写取位,1为读取位

if(IIC_Wait_Ack()==0)

{

buff[0]=IIC_Read_Byte(1);

buff[1]=IIC_Read_Byte(1);

buff[2]=IIC_Read_Byte(1);

buff[3]=IIC_Read_Byte(1);

buff[4]=IIC_Read_Byte(1);

buff[5]=IIC_Read_Byte(0);

IIC_NAck();

IIC_Stop();

}

tem = ((buff[0]<<8) | buff[1]);//温度拼接

hum = ((buff[3]<<8) | buff[4]);//湿度拼接

/*转换实际温度*/

Temperature= (175.0*(float)tem/65535.0-45.0) ;// T = -45 + 175 * tem / (2^16-1)

Humidity= (100.0*(float)hum/65535.0);// RH = hum*100 / (2^16-1)

if((Temperature>=-20)&&(Temperature<=125)&&(Humidity>=0)&&(Humidity<=100))//过滤错误数据

{

// humiture[0]=Temperature;

// humiture[2]=Humidity;

sprintf(humiture_buff1,"%6.2f*C %6.2f%%",Temperature,Humidity);//111.01*C 100.01%(保留2位小数)

}

printf("温湿度:%sn",humiture_buff1);

hum=0;

tem=0;


五、主函数之main.c


#include "delay.h"

#include "sys.h"

#include "usart.h"

#include "myiic.h"

#include "SHT30.h"



 int main(void)

 { 

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2

delay_init();     //延时函数初始化  

uart_init(9600); //串口初始化为9600

IIC_Init();

  

while(1)

{

    SHT30_read_result(0x44);

}

}


六、串口显示实验结果

关键字:STM32  IIC通讯  SHT30 引用地址:STM32之IIC通讯升级版--SHT30温湿度读取

上一篇:STM32的I2C通讯配置(硬件实现)——学习笔记(6-2)
下一篇:STM32串口通讯协议浅析

推荐阅读最新更新时间:2024-11-20 06:13

STM32学习——矩阵键盘
在之前的学习中就学过了IO口的操作,矩阵键盘就是对IO口的操作,还有一个就是扫描模式。 方法一: 逐行扫描:通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。 方法二: 行列扫描:通过高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。 在这里用到了中断的方法,行输出高电平,列做模拟输入口。当有按键按
[单片机]
<font color='red'>STM32</font>学习——矩阵键盘
STM32之霍尔检测电机归位时掉电
一、简介 本文介绍如何在STM32上使用霍尔传感器模块检测电机运行位置,当电机归位时自动断开电源。 二、实验平台 库版本:STM32F10x_StdPeriph_Lib_V3.5.0 编译软件:MDK4.53 硬件平台:STM32开发板(主芯片stm32f103c8t6) 仿真器:JLINK 三、版权声明 四、实验前提 在进行本文步骤前,请先阅读并实现以下博文: 1、《STM32之系统滴答定时器》:http://blog.csdn.net/feilusia/article/details/52835711 2、《STM32之DRV8834电机驱动》:http://blog.csdn.ne
[单片机]
<font color='red'>STM32</font>之霍尔检测电机归位时掉电
STM32串口通信printf重定向方法
在源程序中加入如下代码,包含“stdio.h”。 默认使用USART1,确认串口已经初始化成功、 #pragma import(__use_no_semihosting) _sys_exit(int x) { x = x; } struct __FILE { int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is r
[单片机]
stm32中断服务函数名称表速查
*参考启动文件 startup_stm32f10x_xl.s
[单片机]
<font color='red'>stm32</font>中断服务函数名称表速查
STM32通用定时器详解
1. STM32定时器分类 STM32定时器可以分为3类: A)高级控制定时器TIM1和TIM8 高级定时器适合多种用途,包含输入捕获、输出比较、PWM、带死区控制的PWM等,所以可以用来做电机控制。 B)通用定时器TIM2、TIM3、TIM4、TIM5 通用定时器就是基本的定时器,同51单片机中定时器的概念。 C)基本定时器TIM6和TIM7 基本定时器可以为通用定时提供时间基准,可以为DAC提供时钟。 2. 通用定时器功能介绍 3. 通用定时器操作步骤 操作通用定时器时主要有如下几部: A)打开定时器的时钟 定时器的时钟控制寄存器为:APB1ENR,如下: 操作方式为RCC- APB1ENR |= (1 0); //打开T
[单片机]
<font color='red'>STM32</font>通用定时器详解
如何基于Keil、STM32用C++编写流水灯程序?
通常来说,在单片机上编程,要么汇编,要么C语言,而用C++进行开发的很少,那么究竟能不能用C++开发单片机呢? 答案肯定是可以的,下面讲讲基于Keil、STM32,用C++编写流水灯程序的一些内容。 1 为什么很少用C++开发单片机 不知道大家对面向过程和面向对象的理解有多少? C语言是面向过程的语言,C++是面向对象的编程语言。结合本文来说,面向过程相比面向对象的编程,生成代码量(bin文件)更小,运行效率更高。 所以,C语言相比C++具有更小代码量(bin文件)、更快的运行速度。 当然,这里是C相对C++而言。其实,汇编相对C而言,具有更小代码量和更快的运行速度。可以参看文章:用 汇编 和 C语言 写流水灯程序有什么不
[单片机]
STM32在IAR中如何使用printf函数
STM32使用printf函数给串口打印信息的执行步骤为: 1.重定向printf函数 给uart.c文件中增加如下函数: int fputc(int ch, FILE *f) { USART_SendData(USART2, (unsigned char) ch);// USART1 可以换成 USART2 等 while (!(USART2- SR & USART_FLAG_TXE)); return (ch); } 2.增加头文件stdio #include stdio.h 3.添加宏 在IAR中使用printf应在Options- C/C++Compler- Preprocess
[单片机]
<font color='red'>STM32</font>在IAR中如何使用printf函数
STM32-DMA学习笔记
DMA,全称为:Direct Memory Access,即直接存储器访问。DMA传输方式无需CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM 与I/O设备开辟一条直接传送数据的通路,能使CPU 的效率大为提高。 STM32中 DMA1有7个通道,DMA2有5个通道(DMA2 仅存在大容量产品中)。DMA挂载的时钟为AHB总线,其时钟为72Mhz,所以可以实现高速数据搬运。 STM32F103RBT6 只有1 个DMA控制器,DMA1 ,下面我们就针对DMA1 进行介绍。 从外设(TIMx、ADC、SPIx 、I2Cx 和USARTx )产生的DMA请求,通过逻辑
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved