基于STM32L051和HDC2080的低功耗温湿度计

目录

一、前言

二、cubeMX配置

I2C

SPI

时钟

RTC

独立看门狗

GPIO

三、总体设计

四、代码编写


一、前言

结合之前所撰文章,一个低功耗温湿度计的轮廓隐约显现出来:采用STM32L051单片机为主控,低功耗温湿度芯片HDC2080作为温湿度采集,系统使用纽扣电池供电,墨水屏显示当前温湿度值,断电仍然显示。原理图如下所示

二、cubeMX配置

使用的外设如下

|------|---------------------|--------------|
| 外设 | 相关引脚 | 功能 |
| GPIO | PB0 | 控制墨水屏供电 |
| GPIO | PA3 | 读取墨水屏状态 |
| IWDG | / | 防止程序跑飞 |
| NVIC | / | 中断 |
| SYS | / | 烧录和调试 |
| RTC | / | 定时唤醒 |
| I2C | PB6,PB7 | 与HDC2080芯片通信 |
| SPI | PA4,PA5,PA6,PA7,PA8 | 墨水屏显示控制 |

I2C

标准模式,速率100kHz

SPI

波特率4MBits/s,无DMA

时钟

使用HSI,如果换成外部晶振,功耗会增加还是进一步降低?

RTC

设置自动唤醒为5s

独立看门狗

GPIO

用于墨水屏的控制和显示

三、总体设计

MCU默认状态为休眠,当RTC的5s时间到达,MCU唤醒,先喂狗,再读取当前温湿度。

将当前温湿度与EEPROM中存储的当前屏幕显示的温湿度比较,如果超过一定范围就刷新屏幕,并把新的显示值存入EEPROM,刷新完毕后先让墨水屏下电,再MCU进休眠,等待下一次唤醒到来。流程图如下:

四、代码编写

cpp 复制代码
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "iwdg.h"
#include "rtc.h"
#include "spi.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "epd.h"
#include "hdc2080.h"
#include "GUI.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define TEMP_INTERVAL 0.2f
#define HUMID_INTERVAL 3.0f
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
float temp;
float humidity;
char str[20];
float Showtemp;
float Showhumidity;

uint32_t refreshCnt;

extern GUI_CONST_STORAGE GUI_CHARINFO_EXT GUI_FontMicrosoftYaHeiUI72_CharInfo[13];
#define FONT GUI_FontMicrosoftYaHeiUI72_CharInfo
/* 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 */
float abs(float a, float b)
{
   if (a > b)
   {
      return a - b;
   }
   else
   {
      return b - a;
   }
}
/* 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_I2C1_Init();
  MX_SPI1_Init();
  MX_RTC_Init();
  MX_IWDG_Init();
  /* USER CODE BEGIN 2 */

   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
   HAL_GPIO_WritePin(EPD_EN_GPIO_Port, EPD_EN_Pin, GPIO_PIN_SET);
   HDC2080_Reset();
   HDC2080_WR_Reg(0xE, 0x0);
   HDC2080_Trigger();
   HAL_IWDG_Refresh(&hiwdg);
   HAL_Delay(1);

   HDC2080_RD_Temperature(&temp);
   HDC2080_RD_Humidity(&humidity);

   Showtemp = *(float*)(0x8080000);
   Showhumidity = *(float*)(0x8080004);

#ifdef EPD_REFRESH_CNT
   refreshCnt = *(uint32_t*)(0x8080008);
#endif

   if (abs(Showtemp, temp) > TEMP_INTERVAL || abs(Showhumidity, humidity) > HUMID_INTERVAL)
   {
      Showhumidity = humidity;
      Showtemp = temp;

      __disable_irq();

      HAL_FLASHEx_DATAEEPROM_Unlock();
      HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, 0x8080000, *(uint32_t*)(&Showtemp));
      HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, 0x8080004, *(uint32_t*)(&Showhumidity));
      HAL_FLASHEx_DATAEEPROM_Lock();

      __enable_irq();
   }
   else
   {
      HAL_PWR_EnterSTANDBYMode();
   }

   EPD_Init();
   EPD_BufReset();

   sprintf(str, "%.2f", Showtemp);
   EPD_DrawStr(0, 40, str, FONT, '-');

   sprintf(str, "%.0f", Showhumidity);
   EPD_DrawStr(230, 40, str, FONT, '-');

   EPD_Refresh();
   HAL_PWR_EnterSTANDBYMode();

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

用逻辑分析仪监测I2C引脚,发现每隔5s读取当前温湿度值,符合预期

测得休眠电流约2.8uA

相关推荐
FreakStudio3 天前
W55MH32L-EVB 上手测评:硬件 TCP/IP 加持的以太网单片机,MicroPython 零门槛开发
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
✎ ﹏梦醒͜ღ҉繁华落℘8 天前
单片机基础知识---stm32单片机的优先级
stm32·单片机·mongodb
u152109648498 天前
S.S.Audio PRO A2音频隔离器
嵌入式硬件·音视频·实时音视频·视频编解码·视频
zd8451015008 天前
RS485 总线详解
单片机·嵌入式硬件
半条-咸鱼8 天前
【STM32】I2C协议原理、HAL读写与OLED显示操作
嵌入式硬件·c·信息与通信
wohoo_wangzi8 天前
苏州晟雅泰电子:关于W25Q128JVSIQ这个芯片物料的参数,规格及应用领域
嵌入式硬件
✎ ﹏梦醒͜ღ҉繁华落℘8 天前
编程基础 --高内聚,低耦合
c语言·单片机
科芯创展8 天前
1A,1MHz,30VIN,XZ4115,降压恒流LED驱动芯片
单片机·嵌入式硬件
集芯微电科技有限公司8 天前
四通道2A输出集成功率电感降压模块专为紧凑型方案设计
人工智能·单片机·嵌入式硬件·生成对抗网络·计算机外设
踏着七彩祥云的小丑8 天前
嵌入式测试学习第 37 天:异常场景测试:断电、拔插、干扰、非法指令
单片机·嵌入式硬件·学习