STM32F103ZET6+IIC+SGP30气体传感

这篇具有很好参考价值的文章主要介绍了STM32F103ZET6+IIC+SGP30气体传感。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

STM32F103ZET6+IIC+SGP30气体传感

为了加深对IIC协议的理解和应用,接下来,使用STM32驱动SGP30气体传感传感器

准备IIC协议

用的还是之前的那些代码,只是把GPIO引脚口改了一下而已~~~

1、声明GPIO和IIC初始化

void SGP30_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(SGP30_SCL_GPIO_CLK | SGP30_SDA_GPIO_SDA, ENABLE);

  GPIO_InitStructure.GPIO_Pin = SGP30_SCL_GPIO_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(SGP30_SCL_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;
  GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}

2、IIC数据线的输出模式
因为在IIC数据线输出数据前,需要将数据线设置为输出模式才行

void SDA_OUT(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}

3、IIC数据线的输入模式
同样在IIC数据线输入数据前,需要将数据线设置为输入模式才行

void SDA_IN(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}

4、IIC起始信号

void SGP30_IIC_Start(void)
{
  SDA_OUT();
  SGP30_SDA = 1;
  SGP30_SCL = 1;
  delay_us(20);

  SGP30_SDA = 0;
  delay_us(20);
  SGP30_SCL = 0; 
}

5、IIC停止信号

void SGP30_IIC_Stop(void)
{
  SDA_OUT();
  SGP30_SCL = 0;
  SGP30_SDA = 0;
  delay_us(20);
  SGP30_SCL = 1;
  SGP30_SDA = 1;
  delay_us(20);
}

6、IIC等待应答信号
返回值:1,接收应答失败;0,接收应答成功。

u8 SGP30_IIC_Wait_Ack(void)
{
  u8 ucErrTime = 0;
  SDA_IN();
  SGP30_SDA = 1;
  delay_us(10);
  SGP30_SCL = 1;
  delay_us(10);
  while(SGP30_SDA_READ())
  {
    ucErrTime++;
    if(ucErrTime > 250)
    {
      SGP30_IIC_Stop();
      return 1;
    }
  }
  SGP30_SCL = 0; 
  return 0;
}

7、IIC产生应答信号

void SGP30_IIC_Ack(void)
{
  SGP30_SCL = 0;
  SDA_OUT();
  SGP30_SDA = 0;
  delay_us(20);
  SGP30_SCL = 1;
  delay_us(20);
  SGP30_SCL = 0;
}

8、IIC不产生应答信号

void SGP30_IIC_NAck(void)
{
  SGP30_SCL = 0;
  SDA_OUT();
  SGP30_SDA = 1;
  delay_us(20);
  SGP30_SCL = 1;
  delay_us(20);
  SGP30_SCL = 0;
}

9、IIC发送一个字节
返回从机有无应答,1,有应答;0,无应答。

void SGP30_IIC_Send_Byte(u8 txd)
{
  u8 t;
  SDA_OUT();
  SGP30_SCL = 0; 
  for(t = 0; t < 8; t++)
  {
    if((txd & 0x80) >> 7)
      SGP30_SDA = 1;
    else
      SGP30_SDA = 0;
    txd <<= 1;
    delay_us(20);
    SGP30_SCL = 1;
    delay_us(20);
    SGP30_SCL = 0;
    delay_us(20);
  }
  delay_us(20);

}

10、IIC读取一个字节
读取字节时,ask=1,产生应答;ask=0,不产生应答

u16 SGP30_IIC_Read_Byte(u8 ack)
{
  u8 i;
  u16 receive = 0;
  SDA_IN();
  for(i = 0; i < 8; i++ )
  {
    SGP30_SCL = 0;
    delay_us(20);
    SGP30_SCL = 1;
    receive <<= 1;
    if(SGP30_SDA_READ())
      receive++;
    delay_us(20);
  }
  if (!ack)
    SGP30_IIC_NAck();
  else
    SGP30_IIC_Ack();
  return receive;
}

气体传感器的驱动过程

SGP30数据手册下载链接
STM32F103ZET6+IIC+SGP30气体传感
STM32F103ZET6+IIC+SGP30气体传感
STM32F103ZET6+IIC+SGP30气体传感
STM32F103ZET6+IIC+SGP30气体传感
STM32F103ZET6+IIC+SGP30气体传感

驱动代码如下:

void SGP30_Init(void)
{
  SGP30_GPIO_Init();
  SGP30_Write(0x20, 0x03);
//	SGP30_ad_write(0x20,0x61);
//	SGP30_ad_write(0x01,0x00);
}


void SGP30_Write(u8 a, u8 b)
{
  SGP30_IIC_Start();
  SGP30_IIC_Send_Byte(SGP30_write); //发送器件地址+写指令
  SGP30_IIC_Wait_Ack();
  SGP30_IIC_Send_Byte(a);		    //发送控制字节
  SGP30_IIC_Wait_Ack();
  SGP30_IIC_Send_Byte(b);
  SGP30_IIC_Wait_Ack();
  SGP30_IIC_Stop();
  delay_ms(100);
}

u32 SGP30_Read(void)
{
  u32 dat;
  u8 crc;
  SGP30_IIC_Start();
  SGP30_IIC_Send_Byte(SGP30_read); //发送器件地址+读指令
  SGP30_IIC_Wait_Ack();
  dat = SGP30_IIC_Read_Byte(1);
  dat <<= 8;
  dat += SGP30_IIC_Read_Byte(1);
  crc = SGP30_IIC_Read_Byte(1);
  crc = crc;
  dat <<= 8;
  dat += SGP30_IIC_Read_Byte(1);
  dat <<= 8;
  dat += SGP30_IIC_Read_Byte(0);
  SGP30_IIC_Stop();
  return(dat);
}

在之前的USART工程上,新建两个文件,一个是SGP30.h文件,另一个是SGP30.c文件

SGP30.h文件的代码如下:

#ifndef __HX711_H
#define __HX711_H

#include "sys.h"
#include "delay.h"

#define  SGP30_SCL   PEout(7)
#define  SGP30_SDA   PEout(8)


// GPIO 引脚宏定义
#define  SGP30_SCL_GPIO_CLK        RCC_APB2Periph_GPIOE
#define  SGP30_SCL_GPIO_PORT       GPIOE
#define  SGP30_SCL_GPIO_PIN        GPIO_Pin_7

#define  SGP30_SDA_GPIO_SDA        RCC_APB2Periph_GPIOE
#define  SGP30_SDA_GPIO_PORT       GPIOE
#define  SGP30_SDA_GPIO_PIN        GPIO_Pin_8

#define  SGP30_SDA_READ()           GPIO_ReadInputDataBit(SGP30_SDA_GPIO_PORT, SGP30_SDA_GPIO_PIN)

#define SGP30_read  0xb1  //SGP30的读地址
#define SGP30_write 0xb0  //SGP30的写地址


void SGP30_IIC_Start(void);				
void SGP30_IIC_Stop(void);	  		
void SGP30_IIC_Send_Byte(u8 txd);	
u16 SGP30_IIC_Read_Byte(unsigned char ack); 
u8 SGP30_IIC_Wait_Ack(void); 			
void SGP30_IIC_Ack(void);				
void SGP30_IIC_NAck(void);				
void SGP30_IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 SGP30_IIC_Read_One_Byte(u8 daddr,u8 addr);	
void SGP30_Init(void);				  
void SGP30_Write(u8 a, u8 b);
u32 SGP30_Read(void);


#endif


SGP30.c文件的代码如下:

#include "SGP30.h"


void SGP30_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(SGP30_SCL_GPIO_CLK | SGP30_SDA_GPIO_SDA, ENABLE);

  GPIO_InitStructure.GPIO_Pin = SGP30_SCL_GPIO_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(SGP30_SCL_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;
  GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}

void SDA_OUT(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}

void SDA_IN(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}

void SGP30_IIC_Start(void)
{
  SDA_OUT();
  SGP30_SDA = 1;
  SGP30_SCL = 1;
  delay_us(20);

  SGP30_SDA = 0;
  delay_us(20);
  SGP30_SCL = 0;
}

void SGP30_IIC_Stop(void)
{
  SDA_OUT();
  SGP30_SCL = 0;
  SGP30_SDA = 0;	
  delay_us(20);
  SGP30_SCL = 1;
  SGP30_SDA = 1;
  delay_us(20);
}

u8 SGP30_IIC_Wait_Ack(void)
{
  u8 ucErrTime = 0;
  SDA_IN();
  SGP30_SDA = 1;
  delay_us(10);
  SGP30_SCL = 1;
  delay_us(10);
  while(SGP30_SDA_READ())
  {
    ucErrTime++;
    if(ucErrTime > 250)
    {
      SGP30_IIC_Stop();
      return 1;
    }
  }
  SGP30_SCL = 0; 
  return 0;
}

void SGP30_IIC_Ack(void)
{
  SGP30_SCL = 0;
  SDA_OUT();
  SGP30_SDA = 0;
  delay_us(20);
  SGP30_SCL = 1;
  delay_us(20);
  SGP30_SCL = 0;
}

void SGP30_IIC_NAck(void)
{
  SGP30_SCL = 0;
  SDA_OUT();
  SGP30_SDA = 1;
  delay_us(20);
  SGP30_SCL = 1;
  delay_us(20);
  SGP30_SCL = 0;
}

void SGP30_IIC_Send_Byte(u8 txd)
{
  u8 t;
  SDA_OUT();
  SGP30_SCL = 0; 
  for(t = 0; t < 8; t++)
  {
    if((txd & 0x80) >> 7)
      SGP30_SDA = 1;
    else
      SGP30_SDA = 0;
    txd <<= 1;
    delay_us(20);
    SGP30_SCL = 1;
    delay_us(20);
    SGP30_SCL = 0;
    delay_us(20);
  }
  delay_us(20);

}

u16 SGP30_IIC_Read_Byte(u8 ack)
{
  u8 i;
  u16 receive = 0;
  SDA_IN();
  for(i = 0; i < 8; i++ )
  {
    SGP30_SCL = 0;
    delay_us(20);
    SGP30_SCL = 1;
    receive <<= 1;
    if(SGP30_SDA_READ())
      receive++;
    delay_us(20);
  }
  if (!ack)
    SGP30_IIC_NAck();
  else
    SGP30_IIC_Ack();
  return receive;
}

void SGP30_Init(void)
{
  SGP30_GPIO_Init();
  SGP30_Write(0x20, 0x03);
//	SGP30_ad_write(0x20,0x61);
//	SGP30_ad_write(0x01,0x00);
}


void SGP30_Write(u8 a, u8 b)
{
  SGP30_IIC_Start();
  SGP30_IIC_Send_Byte(SGP30_write); 
  SGP30_IIC_Wait_Ack();
  SGP30_IIC_Send_Byte(a);	
  SGP30_IIC_Wait_Ack();
  SGP30_IIC_Send_Byte(b);
  SGP30_IIC_Wait_Ack();
  SGP30_IIC_Stop();
  delay_ms(100);
}

u32 SGP30_Read(void)
{
  u32 dat;
  u8 crc;
  SGP30_IIC_Start();
  SGP30_IIC_Send_Byte(SGP30_read); 
  SGP30_IIC_Wait_Ack();
  dat = SGP30_IIC_Read_Byte(1);
  dat <<= 8;
  dat += SGP30_IIC_Read_Byte(1);
  crc = SGP30_IIC_Read_Byte(1); 
  crc = crc;
  dat <<= 8;
  dat += SGP30_IIC_Read_Byte(1);
  dat <<= 8;
  dat += SGP30_IIC_Read_Byte(0);
  SGP30_IIC_Stop();
  return(dat);
}

main.c文件的代码如下:

#include "stm32f10x.h"
#include <stdio.h>
#include "delay.h"
#include "led.h"
#include "USART_Init_Config.h"
#include "SGP30.h"


int main(void)
{
	u32 CO2Data, TVOCData;  //定义CO2浓度变量与TVOC浓度变量
	u32 sgp30_dat;          //定义SGP30读取到的数据
	
	delay_init();	        //延时函数初始化 
	LED_Init();             //LED初始化
    USART_Init_Config();    //串口初始化
	SGP30_Init();           //SGP30初始化

	delay_ms(100);
	SGP30_Write(0x20,0x08);
	sgp30_dat = SGP30_Read();                  //读取SGP30的值
	CO2Data = (sgp30_dat & 0xffff0000) >> 16;  //获取CO2的值
	TVOCData = sgp30_dat & 0x0000ffff;         //获取TVOC的值
	while(CO2Data == 400 && TVOCData == 0)
	{
		SGP30_Write(0x20,0x08);
		sgp30_dat = SGP30_Read();                 //读取SGP30的值
		CO2Data = (sgp30_dat & 0xffff0000) >> 16; //获取CO2的值
		TVOCData = sgp30_dat & 0x0000ffff;		  //获取TVOC的值
		printf("正在检测中......");
		delay_ms(500);
	}
		
	while(1)
	{
		SGP30_Write(0x20,0x08);
		sgp30_dat = SGP30_Read();                  //读取SGP30的值
		CO2Data = (sgp30_dat & 0xffff0000) >> 16;  //获取CO2的值
		TVOCData = sgp30_dat & 0x0000ffff;         //获取TVOC的值
		printf("CO2浓度为:%0.2d\r\nTVOC浓度为:%0.2d\r\n",CO2Data,TVOCData);
		delay_ms(1000);
	}
		
}

运行效果

打开串口调试助手

STM32F103ZET6+IIC+SGP30气体传感

完整工程下载!!!文章来源地址https://www.toymoban.com/news/detail-401043.html

到了这里,关于STM32F103ZET6+IIC+SGP30气体传感的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 矩阵键盘之门锁小项目(stm32f103zet6)

    今天,给大家分享的是自己弄着玩的一个矩阵键盘控制控制舵机模拟一个智能门锁的功能。 用到的硬件: 开发板我用的是原子哥的精英板(杀鸡用宰牛刀了)。 矩阵键盘(宝上十几块买的): 外加一个舵机和一个0.96的oled显示屏。 矩阵键盘: 有VCC,GND,SCL,SDO四条线,这个矩阵键

    2024年02月10日
    浏览(50)
  • AD7606与STM32F103ZET6的串行通信

      本文是AD7606与STM32的串行通信的学习心得,可帮助你快速入门AD7606。   图一   图二   图三   图四   根据图一,一些引脚在置高或置低时的上升或下降沿会受时间影响,因此在编写代码时,一些对引脚的操作需要放在一起,且延时函数不能随意使用。   图

    2024年02月08日
    浏览(67)
  • STM32---stm32f103c8t6与stm32f103zet6之间的代码移植转换

    目录 一、将c8t6转换为zet6 1、修改启动文件 2、修改芯片 3、将MD修改为HD  4、下载器的修改 5、修改完成,编译成功  二、将zet6转换为c8t6 最终结果如下:   将STM32F103C8改为STM32F103ZE   基本相同,反向即可。    

    2024年02月06日
    浏览(63)
  • MDK Keil5 创建Stm32工程-理论篇(这里以Stm32F103Zet6为例)

    整个工程可以粗略的划分为几个文件夹: BSP 底层驱动比如GPIOTimer等驱动文件 CMSIS 内核相关的文件 Firmware 生成的固件下载文件 Mycode 用户编写的相关文件,主要编写的文件都在这个文件夹里 Project 工程文件 startup 芯片启动文件 STM32F10x_FWLib 标准库文件 USER 主函数等文件 readm

    2023年04月24日
    浏览(93)
  • STM32F103ZET6【标准库函数开发】------04五个串口的详细配置

    正点原子战舰开发板 STM32F103ZET6有5个串口,查看引脚图可以找到对应的IO口分别如下 串口 USART1 USART2 USART3 UART4 UART5 输入/输出方式 USARTx_TX PA9 PA2 PB10 PC10 PC12 复用推挽输出 USARTx_RX PA10 PA3 PB11 PC11 PD2 浮空输入 USART1挂在APB2下 USART2,USART3,USART4,USART5挂在APB1下 串口调试助手设置波特率

    2024年02月03日
    浏览(115)
  • 用正点原子STM32F103ZET6精英板控制舵机转动实验保姆教程

    正点原子精英板一块 Jlink4线SWD下载线一根 精英板usb供电/下载线一根(负责给开发板供电) SG90舵机一个(三线:其中红线接5V电压,棕线接GED,橙黄色为信号线接开发板PB5引脚,舵机所给为3pin杜邦线母头,可用单根杜邦线(一头子一头母)将舵机线飞开接到精英板上)。 以

    2023年04月15日
    浏览(61)
  • STM32F103ZET6 封装 LQFP-144 ST意法 单片机芯片

    STM32F103ZET6 是意法半导体(STMicroelectronics)生产的一款基于 ARM Cortex-M3 内核的 32 位微控制器。它具有高性能、低功耗的特点,广泛应用于各种嵌入式系统和工业应用中。STM32F103ZET6 的主要特点如下: 内核:ARM Cortex-M3,工作频率最高可达 72MHz。 存储器:64KB SRAM,512KB FLASH。 外

    2024年04月22日
    浏览(65)
  • 正点原子stmf103zet6代码移植为stm32f103c8t6(库函数版)

    目录 1、打开正点原子的工程模板template, 点击魔术棒  2、 修改芯片型号 为stm32f103c8

    2024年02月01日
    浏览(56)
  • 【LVGL】STM32F103ZET6——LVGL_GUI_GUIDER移植过程成功

    STM32F103ZET6——LVGL_GUI_GUIDER移植过程 STM32F103ZET6——LVGL_GUI_GUIDER移植过程 使用工具: 1.LVGL库8.02 2.GUI_GUIDER 3.keil5 设计出来的总体是这样 提示:以下是本篇文章正文内容,下面案例可供参考 这部分有很多大佬已经写的很成熟了,我就不赘述了 安装包在这里硬件资源 右上角可将

    2024年02月12日
    浏览(67)
  • 基于STM32F103ZET6使用STM32CubeMX配置FSMC模块驱动LCD屏(基于正点原子历程)

    在学习STM32的过程中,刚好学到了LCD屏,我使用的是STM32F103ZET6,屏幕是正点原子的。但是在我自己新建工程点亮显示LCD屏时遇到了很多问题。解决之后分享在此,希望能帮助到遇到此困惑的朋友。 想要快速驱动LCD屏请直接跳转到CubeMX配置 FSMC全名叫可变静态存储控制器(Fle

    2024年02月15日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包