STM32温湿度传感器读取温湿度数据并显示到PC端串口助手

您所在的位置:网站首页 湿度传感器用在哪里 STM32温湿度传感器读取温湿度数据并显示到PC端串口助手

STM32温湿度传感器读取温湿度数据并显示到PC端串口助手

2024-01-17 18:39| 来源: 网络整理| 查看: 265

STM32F407ZE使用温湿度传感器 (广州奥松) ,读取温湿度数据并显示到PC端串口助手实例

完整工程代码请点击! 输出结果: 在这里插入图片描述

具体代码及解析如下:

main.c部分:

#include #include "dht11.h" #include "ustart.h" #include DHT11_Data_TypeDef DHT11_Data; int main() { Systick_Init(); USART1_Init(); DHT11_Init(GPIO_Mode_OUT); USART_SendString(USART1, "Hello world!\r\n"); while(1) { //调用Read_DHT11读取温湿度,若成功则输出该信息*/ if( Read_DHT11 ( & DHT11_Data ) == SUCCESS) { printf("\r\n 湿度:%d RH ,温度:%d.%d C\r\n",DHT11_Data.humi_int, //湿度精度为整数 DHT11_Data.temp_int,DHT11_Data.temp_deci); //温度精度为小数 delay_s(1); //延时1us } } }

ustart.h部分

#ifndef USTART_H #define USTART_H #include #include #include #include "sys.h" #include "delay.h" extern char USART1_ReceiveData[50]; //接收PC端发送过来的字符 extern int Receive_Flag; void USART1_Init(); void USART_SendString(USART_TypeDef* USARTx, char *DataString); #endif

ustart.c部分

#include "ustart.h" #include int fputc(int ch, FILE *f) { /* 发送一个字节数据到串口 */ USART_SendData(USART1, (uint8_t) ch); //程序开始时,会发送一次数据,ch是系统分配的(可能是0),串口会显示大概两个空格的内容 /* 等待发送完毕 */ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); return (ch); } void USART1_Init() { GPIO_InitTypeDef GPIOInit_Struct; USART_InitTypeDef USARTInit_Struct; NVIC_InitTypeDef USARTNVIC_Struct; //1、使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //2、初始化对应的IO引脚复用为USART1功能 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); GPIOInit_Struct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIOInit_Struct.GPIO_Mode = GPIO_Mode_AF; GPIOInit_Struct.GPIO_OType = GPIO_OType_PP; GPIOInit_Struct.GPIO_Speed = GPIO_Fast_Speed; GPIOInit_Struct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA,&GPIOInit_Struct); //将PA9 PA10复用为USART1功能 GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //3、USART1初始化 USARTInit_Struct.USART_BaudRate = 115200; //波特率 USARTInit_Struct.USART_Parity = USART_Parity_No; //无校验位 USARTInit_Struct.USART_StopBits = USART_StopBits_1; //1位停止位 USARTInit_Struct.USART_WordLength = USART_WordLength_8b; //8位数据位 USARTInit_Struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 USARTInit_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件控制流 USART_Init(USART1,&USARTInit_Struct); //开启串口终端 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); USARTNVIC_Struct.NVIC_IRQChannel = USART1_IRQn;//stm32f4xx.h USARTNVIC_Struct.NVIC_IRQChannelPreemptionPriority = 0; USARTNVIC_Struct.NVIC_IRQChannelSubPriority = 0; USARTNVIC_Struct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&USARTNVIC_Struct); //4、开启串口 USART_Cmd(USART1,ENABLE); } void USART_SendString(USART_TypeDef* USARTx, char *DataString) { int i = 0; USART_ClearFlag(USARTx,USART_FLAG_TC); //发送字符前清空标志位(否则缺失字符串的第一个字符) while(DataString[i] != '\0') //字符串结束符 { USART_SendData(USARTx,DataString[i]); //每次发送字符串的一个字符 while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == 0); //等待数据发送成功 USART_ClearFlag(USARTx,USART_FLAG_TC); //发送字符后清空标志位 i++; } } char USART_ReceiveString[50]; //接收PC端发送过来的字符 int Receive_Flag = 0; //接收消息标志位 int Receive_sum = 0; //数组下标 void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1,USART_IT_RXNE) == 1) //USART_FLAG_RXNE判断数据,== 1则有数据 { if(Receive_sum > 49) //数组能存放50个字节的数据 { USART_ReceiveString[49] = '\0'; //数据字节超过50位时,将最后一位设置为\0 Receive_Flag = 1; //接收标志位置1,停止接收数据 Receive_sum = 0; //数组下标置0 } if(Receive_Flag == 0) //接收标志位等于0,开始接收数据 { USART_ReceiveString[Receive_sum] = USART_ReceiveData(USART1); //通过USART1串口接收字符 Receive_sum++; //数组下标++ } if(Receive_sum >= 2) //数组下标大于2 { if(USART_ReceiveString[Receive_sum-2] == '\r' && USART_ReceiveString[Receive_sum-1] == '\n' ) { USART_ReceiveString[Receive_sum-1] = '\0'; USART_ReceiveString[Receive_sum-2] = '\0'; Receive_Flag = 1; //接收标志位置1,停止接收数据 Receive_sum = 0; //数组下标置0 printf("%s\r\n",USART_ReceiveString); if(strcmp(USART_ReceiveString,"hello") == 0) { PFout(9) = !PFout(9); } if(strcmp(USART_ReceiveString,"world") == 0) { PFout(10) = !PFout(10); } if(strcmp(USART_ReceiveString,"jiajia") == 0) { PEout(13) = !PEout(13); } if(strcmp(USART_ReceiveString,"haha") == 0) { PEout(14) = !PEout(14); } } } USART_ClearITPendingBit(USART1,USART_IT_RXNE); //接收后先清空标志位 } }

delay.h部分:

#ifndef _DELAY_H_ #define _DELAY_H_ //头文件 #include "stm32f4xx.h" //宏定义 //函数声明 void Systick_Init(void); void delay_us(u32 nus); void delay_ms(u32 nms); void delay_s(u32 ns); #endif

delay.c部分:

#include "delay.h" u8 my_us = 0; u16 my_ms = 0; //初始化滴答定时器 void Systick_Init(void) { //得到的Systick时钟 21MHZ SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); my_us = 168/8; //21 my_ms = 21000; } //微秒延时,nms最大值:798.915 void delay_us(u32 nus) { u32 temp = 0; //往自动重装载除值寄存器写入延时nus SysTick->LOAD最大值0xFFFFFF SysTick->LOAD = nus*my_us; SysTick->VAL = 0x00; SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //开启计数 do { //读控制寄存器 temp = SysTick->CTRL; }while(!(temp & (1VAL = 0x00; } //毫秒延时,nus最大值,nus最大值798915 void delay_ms(u32 nms) { u32 temp = 0; //往自动重装载除值寄存器写入延时nus SysTick->LOAD最大值0xFFFFFF SysTick->LOAD = nms*my_ms; SysTick->VAL = 0x00; SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //开启计数 do { //读控制寄存器 temp = SysTick->CTRL; }while(!(temp & (1VAL = 0x00; } //秒延时 void delay_s(u32 ns) { for(; ns>0; ns--) { delay_ms(500); delay_ms(500); } }

dht11.h部分:

#ifndef _DHT11_H_ #define _DHT11_H_ //头文件 #include "stm32f4xx.h" #include "delay.h" #include "ustart.h" //宏定义 #define DHT11_HIGH 1 #define DHT11_LOW 0 #define DHT11_DATA_OUT(a) if (a) GPIO_SetBits(GPIOG,GPIO_Pin_9); else GPIO_ResetBits(GPIOG,GPIO_Pin_9) #define DHT11_DATA_IN() GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_9) //外部变量声明 typedef struct { uint8_t humi_int; //湿度的整数部分 uint8_t humi_deci; //湿度的小数部分 uint8_t temp_int; //温度的整数部分 uint8_t temp_deci; //温度的小数部分 uint8_t check_sum; //校验和 }DHT11_Data_TypeDef; //函数声明 void DHT11_Init(GPIOMode_TypeDef mode); unsigned char Read_Byte(void); unsigned char Read_DHT11(DHT11_Data_TypeDef *DHT11_Data); #endif //__DHT11_H_

dht11.c部分:

#include "dht11.h" //DHT11初始化,并将模式以参数形式传入 void DHT11_Init(GPIOMode_TypeDef mode) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); //使能 GPIOG 时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ; GPIO_InitStructure.GPIO_Mode = mode; //自定义模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //浮空输入 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOG, &GPIO_InitStructure); //初始化 } //读取DHT11的数据 unsigned char Read_Byte(void) { int i, data=0; for(i=0;i while(DHT11_DATA_IN()==1); //等待高电平结束,进入下一bit开始 data|=(unsigned char)(0x01 int count; DHT11_Init(GPIO_Mode_OUT); //输出模式 DHT11_DATA_OUT(0); //主机拉低电平 delay_ms(18); //延时18ms DHT11_DATA_OUT(1); //总线拉高 delay_us(21); //延时20~40us DHT11_Init(GPIO_Mode_IN); //主机设为输入,判断从机响应信号 count=0; //超时计数初始化 while(DHT11_DATA_IN()==0) //等待电平被拉低 { count++; //超时计数 if(count>160) return -1; //超时 delay_us(1); //延时1us } count=0; //超时计数初始化 while(DHT11_DATA_IN()==1) //等待电平被拉高 { count++; //超时计数 if(count>160) return -1; //超时 delay_us(1); //延时1us } count=0; //超时计数初始化 while(DHT11_DATA_IN()==0) //等待电平被拉低,开始传送数据 { count++; //超时计数 if(count>160) return -1; //超时 delay_us(1); //延时1us } //开始接收数据 DHT11_Data->humi_int= Read_Byte(); //读取湿度整数位 DHT11_Data->humi_deci= Read_Byte(); //读取湿度小数位 DHT11_Data->temp_int= Read_Byte(); //读取温度整数位 DHT11_Data->temp_deci= Read_Byte(); //读取温度小数位 DHT11_Data->check_sum= Read_Byte(); //读取数据校验和 DHT11_Init(GPIO_Mode_OUT); //读取结束,引脚改为输出模式 DHT11_DATA_OUT(1); //主机拉高 //检查读取的数据是否正确 if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci) return 1; else return 0; }

使用温湿度传感器需要读懂下面的信号图

unsigned char Read_DHT11(DHT11_Data_TypeDef *DHT11_Data); 此函数对应图2编写延时 在这里插入图片描述

unsigned char Read_Byte(void) 此函数则通过对应图4、5编写延时 在这里插入图片描述 在这里插入图片描述

如果这篇文章能帮到你,能否请我喝杯奶茶?(下方打赏)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3