文章目录

  • 硬件配置
  • 软件配置
  • DHT11代码编写
  • BH1750代码编写
  • 虚拟串口输出和OLED显示

硬件配置

  • stm32f103c8t6
  • DHT11(温湿度传感器)
  • BH1750(光照度传感器)
  • OLED
  • micro USB数据传输线

软件配置

  • sys->Debug->Serial Wrie
  • RCC->HSE->Crystal/Cerarnic Resonator
  • PC13->GPIO_Out
  • TIM1->Clock Source->Internal Clock

Parameter Settings

为后面DHT11的延时us起作用

  • TIM2->Clock Source->Internal Clock

Parameter Settings

NVIC Settings->TIM2 global interrupt

  • Enabled

  • 打开I2C1

  • USB->Device(FS) USB_DEVICE->Class For FS IP->Communication Device Class (Virtual Port Com)
  • Clock Configuration :48 To USB(MHz)

DHT11代码编写

DHT11是一款温湿度一体化的数字传感器,该传感器包括一个电阻式测湿元件和一个NTC测温元件,并与一个高性能8位单片机连接。通过单片机微处理器简单的电路连接就能够实时的采集湿度和温度。DHT11与STM32之间能采用简单的单总线进行通讯,仅需一个IO口。

本次IO口使用的是PA8

dht11.h

#ifndef __DHT11_H
#define __DHT11_H
#include "stm32f1xx_hal.h"//IO方向设置
#define DHT11_IO_IN()  {GPIOA->CRH&=0XFFFFFFF0;GPIOA->CRH|=8;}
#define DHT11_IO_OUT() {GPIOA->CRH&=0XFFFFFFF0;GPIOA->CRH|=3;}
IO操作函数
#define    DHT11_DQ_IN   HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8) //数据端口    PA0入方向uint8_t DHT11_Init(void);//初始化DHT11
uint8_t DHT11_Read_Data(uint8_t *humiH,uint8_t *humiL,uint8_t *tempH,uint8_t *tempL);//读取温湿度
uint8_t DHT11_Read_Byte(void);//读出一个字节
uint8_t DHT11_Read_Bit(void);//读出一个位
uint8_t DHT11_Check(void);//检测是否存在DHT11
void DHT11_Rst(void);//复位DHT11  #endif

dht11.c

#include "dht11.h"
#include "tim.h"//延时函数
//利用TIM1,延时1us
//预分频因子设为72-1,向上计数,自动重载值为65535;因此计数器CNT_CLK = 1MHz,计数器周期为1us
void delay_us(uint16_t us){uint16_t differ = 0xffff-us-5;__HAL_TIM_SET_COUNTER(&htim1,differ);  //设定TIM7计数器起始值HAL_TIM_Base_Start(&htim1);       //启动定时器while(differ < 0xffff-5){  //判断differ = __HAL_TIM_GET_COUNTER(&htim1);       //查询计数器的计数值}HAL_TIM_Base_Stop(&htim1);
}//复位DHT11
void DHT11_Rst(void)
{                 DHT11_IO_OUT();    //SET OUTPUTHAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET);    //拉低DQHAL_Delay(20);     //拉低至少18msHAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET);      //DQ=1 delay_us(30);      //主机拉高20~40us
}//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
uint8_t DHT11_Check(void)
{   uint8_t retry=0;DHT11_IO_IN();//SET INPUT   while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us{retry++;delay_us(1);};  if(retry>=100)return 1;else retry=0;while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us{retry++;delay_us(1);};if(retry>=100)return 1;        return 0;
}//从DHT11读取一个位
//返回值:1/0
uint8_t DHT11_Read_Bit(void)
{uint8_t retry=0;while(DHT11_DQ_IN&&retry<100)//等待变为低电平{retry++;delay_us(1);}retry=0;while(!DHT11_DQ_IN&&retry<100)//等待变高电平{retry++;delay_us(1);}delay_us(40);//等待40usif(DHT11_DQ_IN)return 1;else return 0;
}//从DHT11读取一个字节
//返回值:读到的数据
uint8_t DHT11_Read_Byte(void)
{        uint8_t i,dat;dat=0;for (i=0;i<8;i++) {dat<<=1; dat|=DHT11_Read_Bit();}                     return dat;
}//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败uint8_t DHT11_Read_Data(uint8_t *humiH,uint8_t *humiL,uint8_t *tempH,uint8_t *tempL)
{        uint8_t buf[5];uint8_t i;DHT11_Rst();if(DHT11_Check()==0){for(i=0;i<5;i++)//读取40位数据{buf[i]=DHT11_Read_Byte();}if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){*humiH=buf[0];       *humiL=buf[1];       *tempH=buf[2];*tempL=buf[3];}}else return 1;return 0;
}//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在
uint8_t DHT11_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_8;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET);                  //PA8 输出高DHT11_Rst();  //复位DHT11return DHT11_Check();//等待DHT11的回应
}

main.c中的使用

/* USER CODE BEGIN Includes */
#include "dht11.h"
/* USER CODE END Includes *//* USER CODE BEGIN PV */
uint8_t humidityH;    //湿度整数部分
uint8_t humidityL;    //湿度小数部分
uint8_t temperatureH;   //温度整数部分
uint8_t temperatureL;   //温度小数部分
/* USER CODE END PV */int main(void)
{/* USER CODE BEGIN 2 */DHT11_Init();/* USER CODE END 2 */while (1){/* USER CODE BEGIN 3 *///将温湿度的整数小数部分分别赋值给4个变量DHT11_Read_Data(&humidityH,&humidityL,&temperatureH,&temperatureL)}/* USER CODE END 3 */
}

BH1750代码编写

BH1750是一种用于两线式串行总线接口的数字型光强度传感器集成电路。这种集成电路可以根据收集的光线强度数据来调整液晶或者键盘背景灯的亮度。

BH1750引出了时钟线和数据线,单片机通过I2C协议可以与BH1750模块通讯。

前面我们配置了I2C1,PB6接SCL,PB7接SDA

bh1750.h

#ifndef __BH1750_H
#define __BH1750_H
#include "main.h"uint16_t Get_BH1750_Value(void);/*bh1750地址*/
#define    BH1750_ADDR_WRITE  0x46   //01000110
#define    BH1750_ADDR_READ   0x47   //01000111typedef enum
{POWER_OFF_CMD  =  0x00,  //断电:无激活状态POWER_ON_CMD   =  0x01,  //通电:等待测量指令RESET_REGISTER =  0x07,  //重置数字寄存器(在断电状态下不起作用)CONT_H_MODE       =  0x10,  //连续H分辨率模式:在11x分辨率下开始测量,测量时间120msCONT_H_MODE2   =  0x11,  //连续H分辨率模式2:在0.51x分辨率下开始测量,测量时间120msCONT_L_MODE       =  0x13,  //连续L分辨率模式:在411分辨率下开始测量,测量时间16msONCE_H_MODE       =  0x20,  //一次高分辨率模式:在11x分辨率下开始测量,测量时间120ms,测量后自动设置为断电模式ONCE_H_MODE2   =  0x21,  //一次高分辨率模式2:在0.51x分辨率下开始测量,测量时间120ms,测量后自动设置为断电模式ONCE_L_MODE       =  0x23   //一次低分辨率模式:在411x分辨率下开始测量,测量时间16ms,测量后自动设置为断电模式
} BH1750_MODE;#endif

bh1750.c

#include "bh1750.h"
#include "i2c.h"/*i2c句柄*/
#define bh1750_i2c hi2c1/*内部函数声明区*/
static uint8_t BH1750_Send_Cmd(BH1750_MODE cmd);
static uint8_t BH1750_Read_Dat(uint8_t* dat);
static uint16_t BH1750_Dat_To_Lux(uint8_t* dat);/*** @brief  向BH1750发送一条指令* @param  cmd —— BH1750工作模式指令(在BH1750_MODE中枚举定义)* @retval 成功返回HAL_OK
*/
static uint8_t BH1750_Send_Cmd(BH1750_MODE cmd)
{return HAL_I2C_Master_Transmit(&bh1750_i2c, BH1750_ADDR_WRITE, (uint8_t*)&cmd, 1, 0xFFFF);
}/*** @brief  从BH1750接收一次光强数据* @param  dat —— 存储光照强度的地址(两个字节数组)* @retval 成功 —— 返回HAL_OK
*/
static uint8_t BH1750_Read_Dat(uint8_t* dat)
{return HAL_I2C_Master_Receive(&bh1750_i2c, BH1750_ADDR_READ, dat, 2, 0xFFFF);
}/*** @brief  将BH1750的两个字节数据转换为光照强度值(0-65535)* @param  dat  —— 存储光照强度的地址(两个字节数组)* @retval 成功 —— 返回光照强度值
*/
static uint16_t BH1750_Dat_To_Lux(uint8_t* dat)
{uint16_t lux = 0;lux = dat[0];lux <<= 8;lux |= dat[1];lux = (int)(lux / 1.2);return lux;
}/*** @brief  返回光照强度值* @param  无* @retval 成功 —— 返回光照强度值
*/
uint16_t Get_BH1750_Value(void)
{uint8_t dat[2] = {0};     //dat[0]是高字节,dat[1]是低字节uint16_t lux;if(HAL_OK != BH1750_Send_Cmd(ONCE_H_MODE)){return 0;}HAL_Delay(120);if(HAL_OK != BH1750_Read_Dat(dat)){return 0;}lux = BH1750_Dat_To_Lux(dat);return lux;
}

main.c中使用

/* USER CODE BEGIN Includes */
#include "bh1750.h"
/* USER CODE END Includes *//* USER CODE BEGIN PV */
uint16_t Light; //光照度
/* USER CODE END PV */int main(void)
{while (1){/* USER CODE BEGIN 3 */Light=Get_BH1750_Value(); //获取关照度}/* USER CODE END 3 */
}

虚拟串口输出和OLED显示

在主函数中我们使用VCP虚拟串口输出

#include "main.h"
#include "i2c.h"
#include "tim.h"
#include "usb_device.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "oled.h"
#include "dht11.h"
#include "bh1750.h"
#include "usbd_cdc_if.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
char oledBuf[20];
uint8_t humidityH;   //湿度整数部分
uint8_t humidityL;   //湿度小数部分
uint8_t temperatureH;   //温度整数部分
uint8_t temperatureL;   //温度小数部分
uint16_t Light;
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USB_DEVICE_Init();MX_TIM2_Init();MX_TIM1_Init();MX_I2C1_Init();/* USER CODE BEGIN 2 */OLED_Init();OLED_ColorTurn(0);//0姝e父鏄剧ず锛?1 鍙嶈壊鏄剧ずOLED_DisplayTurn(0);//0姝e父鏄剧ず 1 灞忓箷缈昏浆鏄剧ずOLED_Clear();DHT11_Init();HAL_TIM_Base_Start_IT(&htim2);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */Light=Get_BH1750_Value();DHT11_Read_Data(&humidityH,&humidityL,&temperatureH,&temperatureL);usb_printf("Light:%d Lx\r\n",Light);usb_printf("Hum:%d.%d %%  Temp:%d.%d C\r\n",humidityH,humidityL,temperatureH,temperatureL);HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);HAL_Delay(1000);}/* USER CODE END 3 */
}

编写TIM2中断回调函数实现oled的显示

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim==&htim2){sprintf(oledBuf,"Light:%dLx",Light);OLED_ShowString(0,0,(uint8_t*)oledBuf,16);//8*16 “ABC”sprintf(oledBuf,"Hum:%d.%d %%",humidityH,humidityL);OLED_ShowString(0,16,(uint8_t*)oledBuf,16);//8*16 “ABC”sprintf(oledBuf,"Temp:%d.%d C",temperatureH,temperatureL);OLED_ShowString(0,32,(uint8_t *)oledBuf,16);//8*16 “ABC”OLED_Refresh();}
}
/* USER CODE END 4 */

程序资源

[程序下载](https://download.csdn.net/download/weixin_51002159/86250257?spm=1001.2014.3001.5503)

STM32HAL库驱动DHT11和BH1750相关推荐

  1. STM32HAL库驱动DS18B20温度传感器

    说明:控制器STM32L431RCT6  晶振12MHZ  配置时钟80MHZ 一.配置定时器(TIM6) 主要是用来做微秒级延时 相关微秒级延时函数 void DelayUs (uint16_t n ...

  2. STM32HAL库电子广告牌显示广告+温湿度+时间设置

    STM32HAL库电子广告牌显示广告+温湿度+时间 概述 第一天进度 材料采购 1.新建KEIL工程 2.软件编写 第二天进度 1.开始接线 2.开始调试 总结 概述 电子广告牌多用于显示一些简短的信 ...

  3. 淘宝二手优必选舵机保姆级驱动教程,看不懂来打我(自行修改ID,有HAL库驱动函数)

    1.首先,先检查舵机的好坏. 本身优必选舵机的连接线属于稀缺物品,所以经本人实验,使用PH2.0 3P端子口也可以供电,但要剪掉端口背面的一小段塑料凸起. 另:24齿的舵机也已经测试过可以兼容淘宝有售 ...

  4. STM32HAL库RS485-ModBus协议控制伺服电机

    STM32HAL库RS485-ModBus协议控制伺服电机 一个月前,接手了一个学长的毕设小车,小车采用rs485通信的modbus协议驱动轮毂电机,与往常我学习的pwm控制电机方法大相径庭,在这里以 ...

  5. GD32移植STM32HAL库接口

    GD32移植STM32HAL库接口 串口接口 串口需要的延时 GPIO接口及中断设置接口 中断设置 配置端口输出例子 FLASH接口 Flash测试代码 看门狗非HAL接口 定时器部分接口 原工程使用 ...

  6. STM32HAL库实现ADXL355加速度传感器简单记步功能(SPI)

    STM32HAL库实现ADXL355加速度传感器简单记步器功能(SPI) 文章目录 STM32HAL库实现ADXL355加速度传感器简单记步器功能(SPI) 一.硬件连接 二.STM32CubeMx配 ...

  7. STM32HAL库-实现USB虚拟串口打印(printf功能)

    目录 概述 一.使用方法 二.STM32CubeMx配置 三.Examples 四.运行结果 五.总结 概述 本篇文章介绍如何使用STM32HAL库,来实现USB虚拟串口打印功能,代替传统中的串口打印 ...

  8. STM32HAL库调用内部API却显示未定义解决方法

    STM32HAL库调用内部API却显示未定义解决方法 问题描述 在使用hal库进行开发时,碰到明明已经在项目管理里添加了STM32 hal库的驱动文件,并且头文件也已经添加了正确的路径,但是编译时仍然 ...

  9. Mind+上传模式的第三方Arduino用户库实现 -DHT11温湿度模块

    Mind+上传模式的第三方Arduino用户库实现--DHT11模块读取温湿度 前言 Mind+是一款拥有自主知识产权的国产青少年编程软件,支持Arduino.micro:bit.掌控板等各种开源硬件 ...

最新文章

  1. 转 微博 linux中ctime,mtime,atime的区别
  2. CSS:响应式下的折叠菜单(条纹式)
  3. java代码审查规范
  4. PHP XML和数组互相转换
  5. arduino读取水位传感器的数据显示在基于i2c的1602a上_XSB-IC-S2智能水位监测仪-老友网...
  6. 如何使用BOOTSTRAP 栅格系统?
  7. 2017 Multi-University Training Contest - Team 4:1002. Classic Quotation(KMP+DP)
  8. 如何插入电子签名_如何在电子文档上签名?可靠电子签名的特征有哪些?
  9. 2018云+未来峰会圆桌面对面:以网络安全之能,造国之重器
  10. VUE项目中引入135编辑器
  11. 关于ABA问题(隔壁老王问题)
  12. cv1378 选课(树)
  13. 【TPAMI 2022】A Survey on Vision Transformer
  14. 间隔十年重新更新微博
  15. 全国计算机等级考试四级数据库易错知识点
  16. Ubuntu 屏幕颜色校准
  17. 安装Tomcat步骤
  18. 免打扰时间设置_我的视频设置是什么样的,为什么要打扰我
  19. Compose Multiplatform 实战:联机五子棋
  20. python - dict.__reversed__() 无效吗?

热门文章

  1. 计算机管理用房设置要求,综合医院建筑规范(放射科用房)
  2. 评论区抽奖程序2.0
  3. Journal of Electronic Imaging 投稿分享
  4. 计算机键盘上的基准键是哪两个键,键盘上的基准键分别是什么?
  5. 小白如何学3D建模?从零开始变大神
  6. 后台管理系统项目搭建
  7. 【视频】海康威视摄像头RTSP协议格式
  8. 鼠标参数以及选购DPI和报告率
  9. 首尾相连数组的最大子数组和
  10. Hadoop基本命令(记一次Hadoop课后实验)