
#第九届立创电赛#温湿度检测仪-5763796A
简介
主控芯片: STM32G030K6T6 温湿度传感器: 盛思睿 SHT40 显示: 数码管 电源: 两节5号电池(约3V) 功能: 显示当前环境的温度和湿度 节能模式: 睡眠模式,通过按键唤醒
简介:主控芯片: STM32G030K6T6 温湿度传感器: 盛思睿 SHT40 显示: 数码管 电源: 两节5号电池(约3V) 功能: 显示当前环境的温度和湿度 节能模式: 睡眠模式,通过按键唤醒开源协议
:GPL 3.0
(未经作者授权,禁止转载)描述
* 1、项目功能介绍
这个项目是一个基于STM32G030K6T6微控制器的桌面温湿度检查仪。该设备小巧轻便,既可以作为桌面装饰美化环境,也可以在闲暇时用来查看当前环境的温度和湿度。为了达到更长的电池续航时间,设备采用了节能设计,平时处于低功耗的睡眠模式,通过按下外部按键即可唤醒进行数据采集,并将结果显示在数码管上。系统使用两节5号电池供电,大约提供3V的电压,这样的设计使得在睡眠唤醒的工作模式下,两节电池可以使用非常长的时间。主控芯片STM32G030K6T6内置丰富的外设接口,如SPI、I²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、软件部分
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;
}
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的时序图来进行数据传输来显示。
数据输入流程:
- 数据输入阶段:在SRCLK的上升沿,SER上的数据被加载到移位寄存器的第一个位置。
- 数据移位阶段:随着SRCLK的持续上升沿,数据逐位向右移动,直到到达最后一个位置。
- 数据锁定阶段:在RCLK的上升沿,移位寄存器的内容被锁存在输出端口。
- 数据输出阶段:此时,输出端口(QA-QH)反映出移位寄存器的内容。
- 清零阶段:当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则显示小数点。每次显示完成后快速消影,防止影响下次显示。
*6、BOM清单
见附件:BOM
*7、大赛LOGO验证

* 8、演示您的项目并录制成视频上传
见附件:立创电赛-温湿度检测仪-实物演示
设计图

BOM


评论