ZE08-CH2O模块概述
管脚定义:
ZE08-CH2O模块的数据及其使用方法:
这是我经常用的方法:使用串口来接收数据,然后这个模块分为两个模式:1,主动上传模式,2.问答模式。如果没有太大要求的话选择主动上传模式即可,这次我所用的方法是主动上传的方法。
在主动上传的模式下数据接收的模式:
然后下面切换到代码界面,直接上源码:
#include "stm32f10x.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
u8 vUSART_Data[8]; //用来存储八位数据
u8 vUSART_CL; //函数计算位(可以在后续的代码中理解)
unsigned int vUSART_PPM; //PPM的值
void Usart_Init(void)
{
NVIC_InitTypeDef NVIC_InitTypeDefs;
USART_InitTypeDef USART_InitTypeDefs;
GPIO_InitTypeDef GPIO_InitTypeDefs;
USART_TypeDef USART_TypeDefs;
//PA9,10串口时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//GPIOA时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//GPIOA PA10,9管脚配置为复用USART1,串口1
//PA9
GPIO_InitTypeDefs.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitTypeDefs.GPIO_Pin=GPIO_Pin_9;
GPIO_InitTypeDefs.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitTypeDefs);
//PA10
GPIO_InitTypeDefs.GPIO_Mode=GPIO_Mode_IN_FLOATING; //½ÓÊÕÒý½ÅÉèÖÃΪ¸¡¿ÕÊäÈëģʽ
GPIO_InitTypeDefs.GPIO_Pin=GPIO_Pin_10;
GPIO_InitTypeDefs.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitTypeDefs);
//串口参数初始化
USART_InitTypeDefs.USART_BaudRate=9600;
USART_InitTypeDefs.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //硬件流控制,设置为不使用
USART_InitTypeDefs.USART_Mode=USART_Mode_Tx|USART_Mode_Rx; //发送和接收都使能
USART_InitTypeDefs.USART_Parity=USART_Parity_No; // 无奇偶校验
USART_InitTypeDefs.USART_StopBits=USART_StopBits_1; //停止位设置为1
USART_InitTypeDefs.USART_WordLength=USART_WordLength_8b; //数据位为8
USART_Init(USART1,&USART_InitTypeDefs);
//使能串口
USART_Cmd(USART1,ENABLE);
//开启串口中断并初始化
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //设置为接收中断,因为我们要接收模块传来的数据
//设置串口的中断的抢占优先级和响应优先级
NVIC_InitTypeDefs.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitTypeDefs.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitTypeDefs.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitTypeDefs.NVIC_IRQChannelSubPriority=0;
NVIC_Init(&NVIC_InitTypeDefs);
}
//写中断服务函数
void USART1_IRQHandler(void)
{
u8 res;
static int i=0;
static u8 USART_i;
float PPM;
unsigned int PPB;
if(USART_GetITStatus(USART1,USART_IT_RXNE))
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE); //接收完一次,清除中断标志位,等待下次中断到来
res=USART_ReceiveData(USART1);
if(res==0xFF) USART_i=1;
if((USART_i==1)&&(res != 0xFF))
{
vUSART_Data[i]=res;
i++;
if(i==8)
{
i=0;
USART_i=0;
vUSART_CL=1;
}
if(vUSART_CL)
{
PPB=(vUSART_Data[3]*256)+vUSART_Data[4];
PPM=PPB/1000.0;
PPM *= 1.25; //单位体积的甲醛浓度
vUSART_PPM=PPM*1000; //换算单位为mmg/m^3
vUSART_CL=0;
}
}
}
}
上述源码是Usart.c文件,接下来看.h文件:
#ifndef __USART_H
#define __USART_H
#include "stdio.h"
#include "sys.h"
#define USART_REC_LEN 200
#define EN_USART1_RX 1
void Usart_Init();
extern u8 USART_RX_BUF[USART_REC_LEN];
extern u16 USART_RX_STA;
void uart_init(u32 bound);
#endif
最后就是main.c文件:
#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include "delay.h"
#include "beep.h"
#include "key.h"
#include "oled.h"
#include "DHT111.h"
extern int vUSART_PPM;
int main(void)
{
int OLED_PPM;
uint8_t TEMP_I=0;
//设置中断优先级为2:2的分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
OLED_Init();
Usart_Init();
OLED_Clear();
OLED_PPM=0;
delay_ms(2000);
while(1)
{
if(OLED_PPM!=vUSART_PPM)
{
OLED_Clear();
OLED_PPM=vUSART_PPM;
OLED_ShowNum(3,8,vUSART_PPM,6,32);
}
else OLED_ShowNum(3,8,vUSART_PPM,6,32);
}
}
代码就到这里结束了,最后就不再过多的解释了,上述代码中有注释,友友们自己看把,不会的评论区见。
对了,可以看下我实现的界面: