发作品签到
专业版

#第九届立创电赛#温湿度检测仪-5763796A

工程标签

131
0
0
0

简介

主控芯片: STM32G030K6T6 温湿度传感器: 盛思睿 SHT40 显示: 数码管 电源: 两节5号电池(约3V) 功能: 显示当前环境的温度和湿度 节能模式: 睡眠模式,通过按键唤醒

简介:主控芯片: STM32G030K6T6 温湿度传感器: 盛思睿 SHT40 显示: 数码管 电源: 两节5号电池(约3V) 功能: 显示当前环境的温度和湿度 节能模式: 睡眠模式,通过按键唤醒

开源协议

GPL 3.0

(未经作者授权,禁止转载)
创建时间:2024-07-16 13:58:43更新时间:2024-08-05 09:52:08

描述

 

* 1、项目功能介绍


这个项目是一个基于STM32G030K6T6微控制器的桌面温湿度检查仪。该设备小巧轻便,既可以作为桌面装饰美化环境,也可以在闲暇时用来查看当前环境的温度和湿度。为了达到更长的电池续航时间,设备采用了节能设计,平时处于低功耗的睡眠模式,通过按下外部按键即可唤醒进行数据采集,并将结果显示在数码管上。系统使用两节5号电池供电,大约提供3V的电压,这样的设计使得在睡眠唤醒的工作模式下,两节电池可以使用非常长的时间。主控芯片STM32G030K6T6内置丰富的外设接口,如SPII²C等,可以轻松地与盛思睿SHT40温湿度传感器通信,获取准确的温湿度数据。整个系统不仅实用,而且具有一定的趣味性和装饰性,非常适合DIY爱好者制作。

*2、项目属性


该项目非首次公开,也非原创,同时也没有获奖,按照立创开源平台的开源项目进行的复刻。

* 3、开源协议


开源协议:GPL 3.0

*4、硬件部分


1.电源部分

采用了两节5号电池供电,供电电压3V。使用PMOS管来防止电压输入反接烧坏电路。使用两个10kΩ电阻分压来测量电池电压,电阻精度选择1%,使得测量电压尽量精准。

2.主控部分

选用了32.768K的晶振来提升时钟准确性。

注意:在布线时晶振尽量靠近芯片,减少干扰。

3.显示部分

显示部分需要显示温湿度,所以采用了两个3位数码管,即显示精度为0.1。3位数码管为了方便控制数码管显示,我们采用了3个移位寄存器芯片SN74HC595PWR芯片来控制数码管显示。2个移位寄存器芯片各控制一个数码管的段选即控制数码管显示什么;另一个芯片控制两个数码管的位选,即哪个数码管3位中的那一位显示。这样画电路很容易实现软件,我们只需要先控制位选,再控制段选就可以了。

 

4.传感器部分

温湿度传感器采用的是盛思锐的SHT40,可以同时测量温湿度,采用I2C读取温湿度。这里采用了10K上拉电阻,给I2C通信过程中一个确定的信号,保证通信质量和稳定。

5.按键和LED部分

显示结束后,芯片将进入睡眠模式,延长使用时间。这里采用按键用来唤醒芯片进行显示温湿度。LED灯的设计可以用来检测SN74HC595PWR芯片和电灯科技。

*5、软件部分


STM32配置可以使用STM32CubeProgrammer配置,也可以使用STM32CubeProgrammer配置完时钟和下载口后,自己写。
 
1.I2C配置
这里使用硬件I2C,配置完引脚后,直接调用I2C硬件读取函数。按照SHT40的数据手册,I2C地址是0X44,寻址是 7 位 I2C 地址,后跟第八位来指示通信方向: “0” 表示向从设备传输数据,即“写”,而 “1” 表示“读”请求,所以在调用函数时,要注意地址。
根据数据手册,对读取的数据进行如下处理,代码如下:
void SHT40_Read_RHData(float *temperature,float *humidity)
{
    uint8_t writeData[1] = {0xFD};
    uint8_t readData[6] = {0};
    uint32_t tempData = 0;
    HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)SHT40_Write, (uint8_t *)writeData, 1, HAL_MAX_DELAY);
  HAL_Delay(10);
    HAL_I2C_Master_Receive(&hi2c1, (uint16_t)SHT40_Read, (uint8_t *)readData, 6, HAL_MAX_DELAY);
    
    tempData = readData[0]<<8 | readData[1];
    *temperature = (tempData * 175.0f) / 65535.0f - 45;
    
    tempData = readData[3]<<8 | readData[4];
  *humidity      = (tempData * 125.0f) / 65535.0f - 6;
}
这里采用指针获取数据。
 
2.按键配置
唤醒引脚配置中断,使用中断判断按键确实被按下,按键配置是上拉,根据电路,按键按下是接低,则是下降沿。中断配置成下降沿触发回调,按下后调用I2C读取温湿度。

3.数码管显示

数码管引脚配置采用标准配置,依次配置时钟、引脚、模式、上下拉、速度、复用。

 /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
    
     /*Configure GPIO pins : PBPin PBPin */
  GPIO_InitStruct.Pin = LED1_SER_Pin|LED_TEST_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
  /*Configure GPIO pins : PAPin PAPin PAPin PAPin
                           PAPin PAPin PAPin PAPin */
  GPIO_InitStruct.Pin = LED2_SER_Pin|LED2_RCLK_Pin|LED2_SCLK_Pin|DIG_SER_Pin
                          |DIG_RCLK_Pin|DIG_SCLK_Pin|LED1_RCLK_Pin|LED1_SCLK_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

引脚配置完成后,就可以测试数码管显示了。按照SN74HC595PWR的时序图来进行数据传输来显示。

数据输入流程:

  1. 数据输入阶段:在SRCLK的上升沿,SER上的数据被加载到移位寄存器的第一个位置。
  2. 数据移位阶段:随着SRCLK的持续上升沿,数据逐位向右移动,直到到达最后一个位置。
  3. 数据锁定阶段:在RCLK的上升沿,移位寄存器的内容被锁存在输出端口。
  4. 数据输出阶段:此时,输出端口(QA-QH)反映出移位寄存器的内容。
  5. 清零阶段:当SRCLR变为低电平,移位寄存器被清零。所以在硬件电路中SRCLR接了3V。

按照这个流程,控制一个数码管显示需要8位数据,所以使用for循环输入一个8位数据,这里我们先传高位再传低位数据。

      for(i = 0;i < 8;i++)
        {
            if(((sendValue << i)&0x80)!=0)    //如果数据第一位是1
            {
                HAL_GPIO_WritePin(LED1_SER_GPIO_Port,LED1_SER_Pin,GPIO_PIN_SET);        //高电平
            }
            else
            {
                HAL_GPIO_WritePin(LED1_SER_GPIO_Port,LED1_SER_Pin,GPIO_PIN_RESET);    //低电平
            }
            HAL_GPIO_WritePin(LED1_SCLK_GPIO_Port,LED1_SCLK_Pin,GPIO_PIN_RESET);    //产生一个SCLK上升沿
            HAL_GPIO_WritePin(LED1_SCLK_GPIO_Port,LED1_SCLK_Pin,GPIO_PIN_SET);
            }
        HAL_GPIO_WritePin(LED1_RCLK_GPIO_Port,LED1_RCLK_Pin,GPIO_PIN_RESET);    //产生一个RCLK上升沿
        HAL_GPIO_WritePin(LED1_RCLK_GPIO_Port,LED1_RCLK_Pin,GPIO_PIN_SET);

再控制数码管之前我们应该把对应数码管使能,即控制第三个SN74HC595PWR芯片控制数码管的使能。代码参考上面,把控制引脚换成第三个SN74HC595PWR芯片的DIG_RCLK_Pin、DIG_SCLK_Pin、DIG_SER_Pin即可。

具体驱动代码:

void SN74HC595_Send_Data(unsigned char sn_num,unsigned int sendValue)
{
    uint8_t i = 0;
    if(sn_num == SN_LED1)    //第一个数码管
    {
        for(i = 0;i < 8;i++)
        {
            if(((sendValue << i)&0x80)!=0)    //如果数据第一位是1
            {
                HAL_GPIO_WritePin(LED1_SER_GPIO_Port,LED1_SER_Pin,GPIO_PIN_SET);        //高电平
            }
            else
            {
                HAL_GPIO_WritePin(LED1_SER_GPIO_Port,LED1_SER_Pin,GPIO_PIN_RESET);    //低电平
            }
            HAL_GPIO_WritePin(LED1_SCLK_GPIO_Port,LED1_SCLK_Pin,GPIO_PIN_RESET);    //产生一个SCLK上升沿
            HAL_GPIO_WritePin(LED1_SCLK_GPIO_Port,LED1_SCLK_Pin,GPIO_PIN_SET);
            }
        HAL_GPIO_WritePin(LED1_RCLK_GPIO_Port,LED1_RCLK_Pin,GPIO_PIN_RESET);    //产生一个RCLK上升沿
        HAL_GPIO_WritePin(LED1_RCLK_GPIO_Port,LED1_RCLK_Pin,GPIO_PIN_SET);
    }
    else if(sn_num == SN_LED2)
    {
        for(i = 0;i < 8;i++)
        {
            if(((sendValue << i)&0x80)!=0)
            {
                HAL_GPIO_WritePin(LED2_SER_GPIO_Port,LED2_SER_Pin,GPIO_PIN_SET);
            }
            else
            {
                HAL_GPIO_WritePin(LED2_SER_GPIO_Port,LED2_SER_Pin,GPIO_PIN_RESET);
            }
            HAL_GPIO_WritePin(LED2_SCLK_GPIO_Port,LED2_SCLK_Pin,GPIO_PIN_RESET);
            HAL_GPIO_WritePin(LED2_SCLK_GPIO_Port,LED2_SCLK_Pin,GPIO_PIN_SET);
            }
        HAL_GPIO_WritePin(LED2_RCLK_GPIO_Port,LED2_RCLK_Pin,GPIO_PIN_RESET);
        HAL_GPIO_WritePin(LED2_RCLK_GPIO_Port,LED2_RCLK_Pin,GPIO_PIN_SET);    
    }
    else if(sn_num == SN_DIG)
    {
        for(i = 0;i < 8;i++)
        {
            if(((sendValue << i)&0x80)!=0)
            {
                HAL_GPIO_WritePin(DIG_SER_GPIO_Port,DIG_SER_Pin,GPIO_PIN_SET);
            }
            else
            {
                HAL_GPIO_WritePin(DIG_SER_GPIO_Port,DIG_SER_Pin,GPIO_PIN_RESET);
            }
            HAL_GPIO_WritePin(DIG_SCLK_GPIO_Port,DIG_SCLK_Pin,GPIO_PIN_RESET);
            HAL_GPIO_WritePin(DIG_SCLK_GPIO_Port,DIG_SCLK_Pin,GPIO_PIN_SET);
            }
        HAL_GPIO_WritePin(DIG_RCLK_GPIO_Port,DIG_RCLK_Pin,GPIO_PIN_RESET);
        HAL_GPIO_WritePin(DIG_RCLK_GPIO_Port,DIG_RCLK_Pin,GPIO_PIN_SET);    
    }
}

/*

延时函数

单位:us

*/

void Delay_us(uint32_t us)
{
    __IO uint32_t delay;
    uint32_t start, ticks;
    ticks = us * 64;

    start = SysTick->VAL;
    do
    {
        delay = (start - SysTick->VAL) & 0xFFFFFF;  // 防止溢出
    } while(delay < ticks);
}

void ShowNum(uint8_t row, uint8_t column, uint8_t value)
{
    if(row == 1)
    {
        switch(column)
        {
                case 1: //如果是第一排第一个
                        SN74HC595_Send_Data(SN_DIG, 0xFE);
                        break;
                case 2:
                        SN74HC595_Send_Data(SN_DIG, 0xFD);
                        break;
                case 3:
                        SN74HC595_Send_Data(SN_DIG, 0xFB);
                        break;
                default:
                        break;
        }
    
        if(column==2)
        {
            SN74HC595_Send_Data(SN_LED1, sgh_value[value]|0x80); //显示值对应的16进制数
        }
        else
        {
            SN74HC595_Send_Data(SN_LED1, sgh_value[value]); //显示值对应的16进制数
        }
        Delay_us(1000); //大致延时1000us
        SN74HC595_Send_Data(SN_LED1, 0x00); //消除阴影
    
    }
    else
    {
        switch(column)
        {
                case 1: //如果是第一排第一个
                        SN74HC595_Send_Data(SN_DIG, 0xF7);
                        break;
                case 2:
                        SN74HC595_Send_Data(SN_DIG, 0xEF);
                        break;
                case 3:
                        SN74HC595_Send_Data(SN_DIG, 0xDF);
                        break;
                default:
                        break;
        }
                if(column==2)
        {
            SN74HC595_Send_Data(SN_LED2, sgh_value[value]|0x80); //显示值对应的16进制数
        }
        else
        {
            SN74HC595_Send_Data(SN_LED2, sgh_value[value]); //显示值对应的16进制数
        
        }
            Delay_us(1000); //大致延时50us

        SN74HC595_Send_Data(SN_LED2, 0x00); //消除阴影        
    }
}

数码显示的数字是0-9段选是固定的,我们把段选按照0-9填充在数组sgh_value中,使数组内容和数据位置对应,显示数字时我们调用相应的数组即可。显示内容的精度是0.1,所以在显示数码管的第二位时,显示是数与0x80与,高位置1则显示小数点。每次显示完成后快速消影,防止影响下次显示。

4.定时器配置
配置一个定时器,这里使用了定时器4,定时30us触发一次中断,在中断里面,我们把读取的温湿度传入数码管显示。
 
5.其余引脚处理
为达到低功耗,把其余没有用到的引脚初始化为模拟模式,既不上拉也不下拉。

*6、BOM清单

见附件:BOM

*7、大赛LOGO验证


 

* 8、演示您的项目并录制成视频上传


见附件:立创电赛-温湿度检测仪-实物演示

 

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

附件

序号文件名称下载次数
1
立创电赛-温湿度检测仪-实物演示.mp4
0
2
show.7z
1
3
BOM.xlsx
0
克隆工程
添加到专辑
0
0
分享
侵权投诉

评论

全部评论(1
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航