dwwzl 发表于 2024-10-27 11:12

【2024 DigiKey创意大赛】基于STM32F411+BME680 家居气象台(完结)

本帖最后由 dwwzl 于 2024-10-28 21:08 编辑

<p align="center"><b>基于STM32F411+BME680 家居气象台</b></p>

<p align="right">作者:dwwzl</p>

<p align="right">&nbsp;</p>

<p><b>一、作品简介</b><br />
图1.1</p>

<div style="text-align: center;">
<div style="text-align: center;"></div>

<p>&nbsp;</p>
</div>

<p>本作品能实时测量室内外空气的温度、湿度,大气压和空气质量指数,旨在服务于家居与外出,在室内外空气发生变化,能够及时提醒家人适时增减衣物,开关加湿器和空气清洁器。</p>

<p>&nbsp;</p>

<p>本作品采用的物料如下表1.1:</p>

<p>表1.1</p>

<table style="border-collapse:collapse; border:none;Times New Roman&quot;">
        <tbody>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p align="center">序号</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p align="center">名称</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p align="center">厂商</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p align="center">得捷零件编号</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p align="center">简介</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p align="center">1</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>NUCLEO-F411RE开发板</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>ST</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>497-14711-ND</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>NUCLEO-F411RE 是ST公司推出的一款针对STM32F4系列设计的Cortex-M4开发板,具有 mbed 功能,支持Arduino。同时还提供 ST Morpho 扩展排针,可连接微控制器的所有周边外设。开发板基于STM32F411RET6设计,开发板还集成了ST-LINK/V2-1仿真下载器(但仅对外提供SWD接口),免除您另外采购仿真器或下载器的麻烦。并且具备Arduino接口,可接入 Arduino 巨大生态系统的各种 Shield 扩展板,让您能够轻松快速增加特殊功能。</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p align="center">2</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>BME680</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>Adafruit Industries LLC</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>1528-2444-ND</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>BME680是Qwiic,STEMMA QT平台评估扩展板,可进行大气压力、环境温度、相对湿度、VOC 气体变化检测 (结合博世的软件包,可计算 IAQ 空气质量系数)。</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p align="center">3</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>D6T-1A-02</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>Omron Electronics Inc-EMC Div</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>Z10316-ND</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>欧姆龙红外热成像温度传感器D6T-1A-02可对静止人物也能检测的高灵敏度人体感应传感器。通过使用自制的MEMS、ASIC,达到了高水平的SNR。(D6T-32L-01A除外) 数字输出,抗干扰性优异。 通过低串扰的视野特性,实现更高精度的区域温度检测。</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p align="center">4</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>0.96寸OLED显示屏</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>中景园电子</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>另购</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="center">
                        <p>0.96寸的OLED液晶显示屏模块,显示区域是128X64的点阵(分辨率128*64),每个点都可以自己独立发光,所以不需要背光,可以显示汉字、ASIIC码、图案等。</p>
                        </td>
                </tr>
        </tbody>
</table>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><b>二、系统框图</b><br />
本作品的设计思路如下:</p>

<p>图2.1</p>

<p align="center"> &nbsp;</p>

<ol>
        <li>首先从系统开发平台入手,熟悉本作品所要用到的NUCLEO-F411RE开发板,下载相关的编译软件和代码库文件,新建项目,编写并调试基础资源配置代码,点亮运行指示灯;</li>
        <li>以BME680为例编写并调试IIC底层读写代码,同样的,移植到D6T-1A-02和0.96寸OLED显示屏的IIC读写驱动文件中,并调试通过;</li>
        <li>根据要显示的数据内容,编写0.96寸OLED显示屏界面代码,并显示相关数据。</li>
</ol>

<p>&nbsp;</p>

<p>系统硬件展示如下:</p>

<ol>
        <li>NUCLEO-F411RE开发板,图2.2</li>
</ol>

<p align="center"> &nbsp;</p>

<p>NUCLEO-F411RE 是ST公司推出的一款针对STM32F4系列设计的Cortex-M4开发板,具有 mbed 功能,支持Arduino。同时还提供 ST Morpho 扩展排针,可连接微控制器的所有周边外设。开发板基于STM32F411RET6设计,开发板还集成了ST-LINK/V2-1仿真下载器(但仅对外提供SWD接口),免除您另外采购仿真器或下载器的麻烦。并且具备Arduino接口,可接入 Arduino 巨大生态系统的各种 Shield 扩展板,让您能够轻松快速增加特殊功能。</p>

<p>&nbsp;</p>

<ol start="2">
        <li>BME680模块,图2.3</li>
</ol>

<p align="center"> &nbsp;</p>

<p>BME680是Qwiic,STEMMA QT平台评估扩展板,可进行大气压力、环境温度、相对湿度、VOC 气体变化检测 (结合博世的软件包,可计算 IAQ 空气质量系数)。</p>

<p>&nbsp;</p>

<ol start="3">
        <li>D6T-1A-02模块,图2.4</li>
</ol>

<p align="center"> &nbsp;</p>

<p>欧姆龙红外热成像温度传感器D6T-1A-02可对静止人物也能检测的高灵敏度人体感应传感器。通过使用自制的MEMS、ASIC,达到了高水平的SNR。(D6T-32L-01A除外) 数字输出,抗干扰性优异。 通过低串扰的视野特性,实现更高精度的区域温度检测。</p>

<p>&nbsp;</p>

<ol start="4">
        <li>0.96寸OLED显示屏,图2.5</li>
</ol>

<p align="center"> &nbsp;</p>

<p align="justify">0.96寸的OLED液晶显示屏模块,显示区域是128X64的点阵(分辨率128*64),每个点都可以自己独立发光,所以不需要背光,可以显示汉字、ASIIC码、图案等。</p>

<p align="justify">&nbsp;</p>

<p align="justify">系统框图如下:图2.6</p>

<p align="center"> &nbsp;</p>

<p align="justify">&nbsp;</p>

<p><b>三、各部分功能说明</b></p>

<ol>
        <li align="justify">室内外温湿度大气压和空气质量数据采集</li>
</ol>

<p align="justify">利用BME680模块分别采集室内外的温湿度值,大气压力和空气参数。</p>

<p align="justify">如图3.1所示,</p>

<p style="text-align: left;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;</p>

<div style="text-align: center;">&nbsp;</div>

<p align="justify">BME680模块采用4针IIC接口,3.3V~5V供电,功耗低至0.1mA,因此可以采用IO端口供电。</p>

<p align="justify">关键代码如下:</p>

<pre>
<code class="language-cpp">void BME680_Init(void)

{

  GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);



  GPIO_InitStructure.GPIO_Pin = BME680_SCL1_Pin; // SCL

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_Init(BME680_SCL1_GPIO_Port, &amp;GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_Init(GPIOC, &amp;GPIO_InitStructure);



  GPIO_ResetBits(GPIOC, GPIO_Pin_0); // 开通电源-

  GPIO_SetBits(GPIOC, GPIO_Pin_1); // 开通电源+

}



int8_t  bme680_iic_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len)

{

    u8 i=0;

  BME_IIC_Start();

  BME_IIC_Send_Byte(BME_IIC_ADDR);

  BME_IIC_Wait_Ack();

  BME_IIC_Send_Byte(reg_addr);

  BME_IIC_Wait_Ack();

  BME_IIC_Stop();

  BME_IIC_Start();

  BME_IIC_Send_Byte(BME_IIC_ADDR|0x01);

  BME_IIC_Wait_Ack();

  len--;

  for(i= 0 ; i&lt; len;i++)

  {

      data = BME_IIC_Read_Byte(1);

  }

  data = BME_IIC_Read_Byte(0);

  BME_IIC_Stop();



  return 0;

}

int8_t  bme680_iic_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len)

{

    u8 cnt=0;

  BME_IIC_Start();

  BME_IIC_Send_Byte(BME_IIC_ADDR);

  BME_IIC_Wait_Ack();

  BME_IIC_Send_Byte(reg_addr);

  BME_IIC_Wait_Ack();



 while(len--)

  {

    BME_IIC_Send_Byte(data);

    BME_IIC_Wait_Ack();

    cnt ++;

  }

  BME_IIC_Stop();

  return 0;

}



void my_bme_init(void)

{

  uint8_t set_required_settings;

  u8 rslt;



  BME680_Init();    // IO初始化

  bme680_soft_reset(&amp;gas_sensor);



  gas_sensor.chip_id  = BME680_CHIP_ID; // 芯片ID

  gas_sensor.dev_id   = BME680_I2C_ADDR_SECONDARY;

  gas_sensor.amb_temp = 25;

  gas_sensor.read     = bme680_iic_read; //  数据读取函数的指针

  gas_sensor.write    = bme680_iic_write; // 写数据的指针

  gas_sensor.intf     = BME680_I2C_INTF; // 通讯方式的选择

  gas_sensor.delay_ms = bme_delay_ms; //  延时函数的函数指针



  gas_sensor.power_mode    = BME680_FORCED_MODE;  // 读取方式



  gas_sensor.calib              = calib_struct;

  gas_sensor.tph_sett           = tph_sett_struct;

  gas_sensor.gas_sett           = gas_sett_struct;



  /* Set the temperature, pressure and humidity &amp; filter settings */

  gas_sensor.tph_sett.filter   = BME680_FILTER_SIZE_1;

  gas_sensor.tph_sett.os_hum   = BME680_OS_1X;  // 这里是  数据结构体下的 过采样率

  gas_sensor.tph_sett.os_temp  = BME680_OS_1X;

  gas_sensor.tph_sett.os_pres  = BME680_OS_1X;



  /* Set the remaining gas sensor settings and link the heating profile */

  gas_sensor.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;

  /* Create a ramp heat waveform in 3 steps */

  gas_sensor.gas_sett.heatr_temp = 350; // degree Celsius

  gas_sensor.gas_sett.heatr_dur = 2000; // 150  milliseconds



  /* Set the required sensor settings needed */

  set_required_settings = (BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL| BME680_GAS_SENSOR_SEL);



   rslt =  bme680_init(&amp;gas_sensor);                           // 调用初始化函数

   if(rslt)printf("result of bme680_init() is %d",rslt);    // 有问题的话输出调试信息



   /* Set the desired sensor configuration */

   rslt =  bme680_set_sensor_settings(set_required_settings,&amp;gas_sensor);

   if(rslt)printf("result of bme680_set_sensor_settings() is %d",rslt);



  /* Set the power mode */

  rslt =  bme680_set_sensor_mode(&amp;gas_sensor);

  if(rslt)printf("result of bme680_set_sensor_mode() is %d",rslt);

}

数据输出如下:
</code></pre>

<p>&nbsp;</p>

<div style="text-align: center;"></div>

<div style="text-align: center;">&nbsp;</div>

<div style="text-align: center;">
<div style="text-align: center;"></div>

<p>&nbsp;</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>
</div>

<ol start="2">
        <li align="justify">人体体温采集</li>
</ol>

<p align="justify">利用D6T-1A-02模块感应并采集人体温度值。</p>

<p align="justify">如图3.2</p>

<div style="text-align: center;"></div>

<p align="justify">D6T-1A-02模块采用4线IIC接口,供电电压为5V,工作电流3.5mA。</p>

<p align="justify">关键代码实现如下:</p>

<pre>
<code class="language-cpp">void D6T_Init(void)

{

    GPIO_InitTypeDef  GPIO_InitStructure;



    // RCC

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB,

                            ENABLE );

    // SCL

    GPIO_InitStructure.GPIO_Pin     = D6T_SCL_Pin;

    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_OUT;

    GPIO_InitStructure.GPIO_OType   = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_NOPULL;

    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;

GPIO_Init(D6T_SCL_GPIO_Port, &amp;GPIO_InitStructure);



    D6T_SDA_OUT();

    D6T_IIC_SDA=1;

    D6T_IIC_SCL=1;

}



/*

 *******************************************************************************************

 ** =0 正常,=-1 传感器缺失,=1 时序异常

 *******************************************************************************************

*/

int D6T_ReadData()

{

    unsigned char D6Tbuff;

    unsigned char D6T_Data;

    unsigned char i;

    unsigned int tPTAT_l;

unsigned int tP_l;



    D6T_IIC_Start();

    D6T_IIC_Send_Byte(D6T_Addr + 0);

    D6T_IIC_Wait_Ack();

    D6T_IIC_Send_Byte(D6T_CMD);

D6T_IIC_Wait_Ack();



    D6T_IIC_Start();

    D6T_IIC_Send_Byte(D6T_Addr + 1);

D6T_IIC_Wait_Ack();



    // READ Data of Temperature

    D6T_Data = 0;

    for(i=0;i&lt;(5-1);i++)

    {

        D6Tbuff = D6T_IIC_Read_Byte(1);

    }

    D6Tbuff = D6T_IIC_Read_Byte(0);

D6T_IIC_Stop();



    tPTAT_l = D6Tbuff * 256 + D6Tbuff;

tP_l = D6Tbuff * 256 + D6Tbuff;



    D6T_Temp_f = (float)tPTAT_l / 10; // 单位 ℃

D6T_Temp_f = (float)tP_l / 10; // 单位 ℃



    return 0;

}</code></pre>

<p>数据输出如下:</p>

<div style="text-align: center;"></div>

<p align="justify">&nbsp;</p>

<p align="justify">&nbsp;</p>

<ol start="3">
        <li align="justify">数据显示</li>
</ol>

<p align="justify">利用0.96寸OLED显示屏显示室内外的温湿度值,大气压力和空气参数和人体温度值。</p>

<p align="justify">如图3.3</p>

<div style="text-align: center;"></div>

<p align="justify">0.96寸OLED显示屏采用7针IIC接口,供电电压3.3V,供电电流在全亮时约为25mA,全灭时约为1.5mA。</p>

<p align="justify">按照下表调整电阻配置。</p>

<div style="text-align: center;"></div>

<p align="justify">关键代码实现如下:</p>

<pre>
<code>
//OLED的初始化

void OLED_Init(void)

{

    // 端口配置

GPIO_InitTypeDef  GPIO_InitStructure;



    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟



    //初始化设置

    GPIO_InitStructure.GPIO_Pin = OLED_G_Pin | OLED_V_Pin | OLED_D0_Pin;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_Init(GPIOA, &amp;GPIO_InitStructure);//初始化

    GPIO_ResetBits(GPIOA,OLED_G_Pin);//电源-

    GPIO_SetBits(GPIOA,OLED_V_Pin);//电源+

GPIO_ResetBits(GPIOA,OLED_D0_Pin);//D0



    GPIO_InitStructure.GPIO_Pin = OLED_D1_Pin | OLED_DC_Pin | OLED_RES_Pin | OLED_CS_Pin;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_Init(GPIOB, &amp;GPIO_InitStructure);//初始化

    GPIO_ResetBits(GPIOB,OLED_D1_Pin);//D1

    GPIO_ResetBits(GPIOB,OLED_DC_Pin);//DC

    GPIO_SetBits(GPIOB,OLED_RES_Pin);//RES

GPIO_ResetBits(GPIOB,OLED_CS_Pin);//CS



delay_ms(200);



    //初始化命令

    OLED_WR_Byte(0xAE,OLED_CMD);//关闭显示--turn off oled panel

    OLED_WR_Byte(0x00,OLED_CMD);//第1点列地址---set low column address

    OLED_WR_Byte(0x10,OLED_CMD);//高1点列地址---set high column address

    OLED_WR_Byte(0x40,OLED_CMD);//显示开始线--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)

    OLED_WR_Byte(0x81,OLED_CMD);//设置对比度--set contrast control register

    OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness

    OLED_WR_Byte(0xA1,OLED_CMD);//设置段复用--Set SEG/Column Mapping     0xa0左右反置 0xa1正常

    OLED_WR_Byte(0xC8,OLED_CMD);//设置扫描方向--Set COM/Row Scan Direction   0xc0上下反置 0xc8正常

OLED_WR_Byte(0xA6,OLED_CMD);//设置正常显示或反显--set normal display



    OLED_WR_Byte(0xA8,OLED_CMD);//设置复用比--set multiplex ratio(1 to 64)

OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty



    OLED_WR_Byte(0xD3,OLED_CMD);//设置显示偏移量--set display offset   Shift Mapping RAM Counter (0x00~0x3F)

    OLED_WR_Byte(0x00,OLED_CMD);//-not offset



    OLED_WR_Byte(0xd5,OLED_CMD);//设置时钟分频因子--set display clock divide ratio/oscillator frequency

OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec



    OLED_WR_Byte(0xD9,OLED_CMD);//设置充电周期--set pre-charge period

OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks &amp; Discharge as 1 Clock



    OLED_WR_Byte(0xDA,OLED_CMD);//设置引脚配置--set com pins hardware configuration

OLED_WR_Byte(0x12,OLED_CMD);



    OLED_WR_Byte(0xDB,OLED_CMD);//设置取消等级--set vcomh

OLED_WR_Byte(0x30,OLED_CMD);// 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;



OLED_WR_Byte(0x40,OLED_CMD);//显示开始线--Set VCOM Deselect Level



    OLED_WR_Byte(0x20,OLED_CMD);//内存水平地址模式--Set Page Addressing Mode (0x00/0x01/0x02)

OLED_WR_Byte(0x02,OLED_CMD);//



    OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable

OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable



    OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)

OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)



    OLED_WR_Byte(0xAF,OLED_CMD);

    OLED_Clear();

}



//清屏函数

void OLED_Clear(void)

{

    unsigned char i,n;

    for(i=0;i&lt;8;i++)

    {

       for(n=0;n&lt;128;n++)

        {

            OLED_GRAM=0;//清除所有数据

        }

    }

    OLED_Refresh();//更新显示

}



//显示字符串

//x,y:起点坐标  

//size1:字体大小

//*chr:字符串起始地址

void OLED_ShowString(unsigned char x,unsigned char y,unsigned char *chr,unsigned char size1)

{

    while((*chr&gt;=' ')&amp;&amp;(*chr&lt;='~'))//判断是不是非法字符!

    {

        OLED_ShowChar(x,y,*chr,size1);

        x+=size1/2;

        if(x&gt;128-size1)  //换行

        {

            x=0;

            y+=2;

        }

        chr++;

    }

}



//显示汉字

//x,y:起点坐标

//num:汉字对应的序号

//取模方式 列行式

void OLED_ShowChinese(unsigned char x,unsigned char y,unsigned char num,unsigned char size1)

{

    unsigned char i,m,n=0,temp,chr1;

    unsigned char x0=x,y0=y;

    unsigned char size3=size1/8;

    while(size3--)

    {

        chr1=num*size1/8+n;

        n++;

        for(i=0;i&lt;size1;i++)

        {

            if(size1==16)

                    {temp=Hzk1;}//调用16*16字体

            else if(size1==24)

                    {temp=Hzk2;}//调用24*24字体

            else if(size1==32)      

                    {temp=Hzk3;}//调用32*32字体

            else if(size1==64)

                    {temp=Hzk4;}//调用64*64字体

            else return;

                       

            for(m=0;m&lt;8;m++)

            {

                if(temp&amp;0x01)OLED_DrawPoint(x,y);

                else OLED_ClearPoint(x,y);

                temp&gt;&gt;=1;

                y++;

            }

            x++;

            if((x-x0)==size1)

            {x=x0;y0=y0+8;}

            y=y0;

        }

    }

}</code></pre>

<p>最终,显示界面如下:</p>

<p align="center"> &nbsp;</p>

<p><b>四、作品源码</b></p>

<p align="justify">本作品源码链接如下:</p>

<p align="justify"><a href="https://download.eeworld.com.cn/detail/dwwzl/634616" target="_blank">https://download.eeworld.com.cn/detail/dwwzl/634616</a></p>

<p align="justify">&nbsp;</p>

<p><b>五、</b><b>作品功能演示视频</b></p>

<p align="justify">视频如下:</p>

<p align="justify">fa1ece3d07f922de004b32e6da02b8b8<br />
&nbsp;</p>

<p><b>六、项目总结</b></p>

<p align="justify">在实现本作品的过程中,接触到了像BME680和D6T-1A-02一类的MEMS传感器,读写操作不难做到,难点在于将传感器的输出数据进行算法计算和实际应用起来,做到让先进的传感技术真正服务于生活和工作场景中去。</p>

<p align="justify">本作品后续可以考虑加入无线通信模块,采用锂电池供电,实现传感器分布式采集数据并上传到数据计算中心,经过综合计算判断后,得出合理的结论下发到人机接口终端,让输出结果一目了然。</p>

<p align="justify">分享帖链接如下:</p>

<p align="justify">【2024 DigiKey创意大赛】家居气象台-物料开箱 - DigiKey得捷技术专区 - 电子工程世界-论坛 <a href="https://bbs.eeworld.com.cn/thread-1291454-1-1.html"><u>https://bbs.eeworld.com.cn/thread-1291454-1-1.html</u></a></p>

<p align="justify">【2024 DigiKey创意大赛】家居气象台-备料 - DigiKey得捷技术专区 - 电子工程世界-论坛 <a href="https://bbs.eeworld.com.cn/thread-1293100-1-1.html"><u>https://bbs.eeworld.com.cn/thread-1293100-1-1.html</u></a></p>

<p align="justify">【2024 DigiKey创意大赛】家居气象台-调试iic接口通信 - DigiKey得捷技术专区 - 电子工程世界-论坛 <a href="https://bbs.eeworld.com.cn/thread-1296584-1-1.html"><u>https://bbs.eeworld.com.cn/thread-1296584-1-1.html</u></a></p>

<p align="justify">&nbsp;</p>

<p align="justify"><b>七、附件</b></p>

<p align="justify"><br />
<br />
&nbsp;</p>
页: [1]
查看完整版本: 【2024 DigiKey创意大赛】基于STM32F411+BME680 家居气象台(完结)