发作品签到
专业版

#第九届立创电赛#桌面温湿度检测仪(扩展时钟/秒表等功能)

工程标签

221
0
0
0

简介

一款采用2节5号电池供电的桌面温湿度检测仪,并且扩展了时钟/秒表/电池电压检测/休眠的功能。共有五个工作模式.

简介:一款采用2节5号电池供电的桌面温湿度检测仪,并且扩展了时钟/秒表/电池电压检测/休眠的功能。共有五个工作模式.

开源协议

GPL 3.0

创建时间:2024-07-11 04:23:40更新时间:2024-08-05 01:06:02

描述

项目要求

这是第九届立创电赛的项目;
设计一款桌面温湿度检测仪,采用的主控芯片为STM32G030K6T6,温湿度传感器型号是盛思锐的SHT40/AD1B。

项目分析

1. STM32G030K6T6芯片,使用Arm Cortex-M0+内核;最大主频64Mhz; 具有32KB的Flash以及8K的SRAM,供电电压在2.0V~3.6V之间;
2. 采用2节5号电池供电,可以省去电源转换电路,初学者也比较容易调试;
3. 盛思锐的SHT40是一款灵敏度、精度都较高的温湿度传感器,采用IIC进行通信,可以方便的与单片机进行通信;
4. 显示采用LED数码管具有美观、清淅,价格便宜的优点;

5.在硬件不变的情况下增加时钟、秒表、电池电压检测、自动休眠等实用功能;
6.因为是电池供电,尽量节能。

总体设计方案框图
1111.png

原理图设计说明

设计原理图

原理图与第九届立创电赛官方提供的一样,具体原理这里不缀述,可参考第九届立创电赛#桌面温湿度检测仪#官方讲座:
【手把手教你做温湿度仪:原理图设计-上】https://www.bilibili.com/video/BV1ui421Y7L6?vd_source=c8ee4f10435a9f625620c244f4dfb939

我的硬件全部是按照官方提供的原理图做的,只是软件部分增加了实用功能。如果你也是按官方提供的原理图做的,想测试一下我的程序的效果,可直接下载的我的开源的软件程序。
不同之处是SHT40温湿度 传感器模块的那个插座,官方是间距:1.27mm 1x4P 弯插,因为比赛时商城一时被买光了,所有这边用1.27mm 2x4P 弯插,把两排并联成一排,与1x4P 弯插一模一样管脚排列。

原理图中SHT40温湿度传感器是一个插座,所以如果自动形成BOM表时,要另外加购传感器模块,型号是:SHT40/AD1B。

sh40_原理图.png
原理图分以下几个部分:(可参考第九届立创电赛#桌面温湿度检测仪#官方讲座)
主控电路,晶振电路,SHT40温湿度传感器模块,三态输出8位移位寄存器,
共阴极三位数码管,唤醒按键,测试LED,两节5号电池盒+防反接保护,SWD下载调试接口。
唤醒按键:同时具有模式转换功能。

PCB设计说明

PCB的布局、布线与第九届立创电赛官方提供的基本一样,具体可参考第九届立创电赛#桌面温湿度检测仪#官方讲座:【手把手教你做温湿度仪:PCB布局技巧】https://www.bilibili.com/video/BV15y411i73T?vd_source=c8ee4f10435a9f625620c244f4dfb939

因为是第一次参加这种训练赛,并且是第一次使用STM32,所以我这边全部和比赛官方保持一致,如果你,对STM32G030K6T6芯片有一定的了解,有很多地方可以改进,包括原理图、PCB也可以改进,空闭的引脚都可以引出,可以做很多实验和功能验证。这些只能等我的第二版了。

软件说明

软件部分:
我这个桌面温湿度检测仪与官方最大的不同在于软件部分:
其中:
1、LED数码管显示程序函数;
2、温湿度传感器数据采集和换算函数;
请参考第九届立创电赛官方讲座的讲解,这里再不缀述了。
扩展功能部分说明有:
1、为了实现秒表功能,启用了定时器1,并且设定成1ms中断一次;
在STM32CubeMX中设定定时器1使能,并且定时设成1ms;在主main以中断的形式启动定时器1;
2、为了实现时钟功能在低功耗模式下能工作,启用了外部时钟源;
在STM32CubeMX中RTC项目中激活LSE时钟源和日历功能。
3、五种模式之间转换;
Modelcharg()为模式转换函数,按键每按住0.5秒钟以上切换一次模式,顺序如下:温湿度->时钟->秒表->电池电压->休眠->温湿度;在时钟模式,进一步判断按键按下情况,分别进行计时设置、分设置操作;在秒表模式,进一步判断按键按下的次数,分别进行计时开始、暂停或复位的操作;具体参考程序mian.c中的函数;
4、时钟读取和时钟设置功能;
采用如下两个HAL库函数分别读取时间和日期,
void TaskRTC(void)
{
HAL_RTC_GetTime(&hrtc,&sTime,RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc,&sDate,RTC_FORMAT_BIN);
}
时钟设置功能:因为只有一个按键,所以只能通过巧妙设计,快速按压按键 二次,如同我们操作鼠标的双击,来切换到时钟和分钟的设定模式。 具体参照我的程序中的时钟设定函数void clockset(void);

时钟显示功能:与温湿度显示原理一样,通过LED数码管显示函数把时和分的高低位显示在第一排和第二排上。因为才两个三位显示器,所以这里只对时间的时、分进行显示。如果要年月日显示原理一模一样的。
这里有所不同的是,增加了闪烁功能,通过设计一个PWM 0.5秒通0.5秒断的信号outpwm来切换显示与不显示,从而达到闪烁的效果。

if (!outpwm )
{
ShowNum(1,2, hour /10 %10,0);
ShowNum(1,3, hour %10,0);
ShowNum(2,2, 18,0);//18是空 字模第18位是空的字模,具有看《增加部分英文字母和特殊字符字模》的说明;
ShowNum(2,3, 18 ,0);//18是空
}
else
{
ShowNum(1,2, 18 ,0);
ShowNum(1,3, 18 ,0);
}
5、秒表计时函数;
秒表计时函数是CountTime()函数,先定义一个计时变量CountMinutes,当计时启动时,在定时器1的中断回调函数中,进行CountMinutes++,计时暂停时,停止CountMinutes累加,计时复位时,CountMinutes清0,从而实现计时功能,精度达ms级别,因为显示器只有3位,所以取0.1s为单位显示。
6、电池电压测量与显示;
电池电压测量在STM32CubeMX的ADC项选定基准电压和VIN9与Vbat,(此处Vbat的作用是什么,还不明白,有测出来过,但总是固定值,不知其义,有高手知道可以知会一声,) 我们只讨论基准电压Vref和VIN9.
ADC1.png
以下程序就是把基准电压Vref和VIN9读入数组adc1_val中:

HAL_ADC_Start (&hadc1);
HAL_ADC_PollForConversion(&hadc1,10);
adc1_val[i]=HAL_ADC_GetValue (&hadc1);
adc1_val[0]读出基本准电压读数,adc1_val[1]读出VIN9电压读数,就可以算出VIN9的电压=120 * VIN9电压读数 / 基准电压读数; 然后按显示温湿度的方法显示出来,
最后显示出来的值,再与万用表测量的值进行比较,修正 一下系数120为122,即:VIN9的电压=122*VIN9电压读数/基准电压读数,小数点显得在第1位,可能我这MCU内核电压是1.22v;在显示电池电压时,我在显示器上行显示了英文字母bAt.,是因为我增加了数码管的字模。
7、数码管的字模;
因为数码管不仅可以显示数字,通过增加字模数组的值,可以显示其他字符。
数码管的字模数组的程序 gpio.c的最前面,增加后的字模数组:
uint16_t sgh_value[19]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x80,0x40,0x77,0x7c,0x79,0x38,0x78,0x73,0};
//0,1,2,3,4,5,6,7,8,9,.,-,A,b,E,L,t,P,空,
这里举例,如果要显示bAt.,只要取位置13、12、16。
我在进入电池电压显示时显示了bAt,进入低功耗模式的倒计时时,显示了SLEEP.
如图:
bAt.png

SLEEP.png
7、进入深度休眠模式函数;
EnterSTOPMode()函数,可自动进入休眠模式,通过计算空闲时间是否达到设定的时间(温湿度模式、时钟、电压模下设定为1分钟自动进入休眠模式,EnterSTOPTime =60000、秒表模式设定为1小时自动进入休眠模式,EnterSTOPTime =60000 * 60),条件满足,就进入STOPMode,此时主控芯片时钟会关闲,以便达到最大程度的节能。
手动进入休眠模式:把模式调到手动进入休眠模式,此时LED显示器显示SLEEP.09 倒计时计数10秒后,进入休眠模式,
休眠模式的意义:这个小仪器设计的初衷是显示温湿度,采用了5号电池供电, 可是经过实际测试,LED显示器显示电流在21-22mA左右。

22ma.png
5号电池按某孚碱性电池的容量为1600mAh,可用时间=1600 / 22=72小时,天数=72/24=3天,也就是说2节5号电池,24小时开机,只够用3天,有点少了,所以这个小仪器,如果想24小时开机,就要设计成充电器或充电电池供电。
官方提供下载的程序,经过实际测试是进行SlepMode睡眠模式,睡眠时电流在2.8mA左右。我们再来算一算,待机使用天数,天数=1600 / 2.8/24=23.8天,还是有点少,毕竟就放在那儿没显示,一天偶尔把玩一下,20几天就没电了,
我这个程序,是进行STOPMode休眠模式(停止模式,停止了MCU的时钟),经过测试,待机电流仅0.32ma,经过计算,两节5号电池待机最大时间可到7个月,STOPMode休眠模式此时停止了内部时钟,外部时钟没停止,时钟功能仍然有有效。

326ua.png
还的一个情况,如果低功耗模式是进入STANDBYMode待机模式,经过测试,整机电流为0.62ma,反尔比STOPMode高,有兴趣的同学可以自行测试一下;
以上都在我有程序mian.c中,请参照我上传的程序附件。


这里贴出主代码块int main(void):请参照我上传的程序附件。
//倒计时进入休眠模式 倒计时初值ms ,dowmtime=9000; 可以在下面程序中修改,
// 自动进入休眠模式的时间设定 EnterSTOPTime =60000;//等待进入休眠时间60000=1min ,可以在下面程序中修改
... ...

int main(void)
{
/* USER CODE BEGIN 1 /
float Temperature=0,Humidity=0;
uint16_t Temp=0,Humi=0;
//计分钟 计0.1 定义变量
uint32_t CountMinutes=0;
uint32_t CountCseconds=0;
uint16_t UP_Disply=0,DOWN_Disply=0;
;
/
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_TIM1_Init();
MX_RTC_Init();
MX_ADC1_Init();
/
USER CODE BEGIN 2 */
//SN74HC595_Send_Data(SN_DIG,0x00);
//SN74HC595_Send_Data(SN_LED2,0xFF);

/* USER CODE END 2 */

/* Infinite loop /
/
USER CODE BEGIN WHILE /
//以中断的形式启动定时器1
HAL_TIM_Base_Start_IT(&htim1 );
Close_Led();
sTime.Hours=12;
sTime.Minutes =12;
HAL_RTC_SetTime(&hrtc,&sTime,RTC_FORMAT_BIN);
HAL_ADCEx_Calibration_Start(&hadc1);
uint8_t display_h=0;
uint8_t display_m=0;
uint8_t display_sec=0;
while (1)
{
/
USER CODE END WHILE /

/
USER CODE BEGIN 3 /
//Toggle_Led();
//HAL_Delay(500);
//Scanf_key();
for(i=0;i<3;i++)
{
HAL_ADC_Start (&hadc1);
HAL_ADC_PollForConversion(&hadc1,10);
adc1_val[i]=HAL_ADC_GetValue (&hadc1);
}
Vref=adc1_val[0];
VIN9=adc1_val[1];
Vbat=adc1_val[2];
for(i=0;i<3;i++)
{
adc1_h[i]=adc1_val[i]/256;
adc1_l[i]=adc1_val[i] % 256;
}
GetTemperatureHumidity(&Temperature,&Humidity );
Temp=(uint16_t)(Temperature * 10);
Humi=(uint16_t)(Humidity * 10);
CountCseconds=(countMiliSeconds/100)%600;
CountMinutes=countMiliSeconds/1000/60;
EnterSTOPMode();//进入深度睡眠模式
Modelcharg();//模式转换
TaskRTC();//读时钟
pwm();//闪烁用脉冲
if (Display_sel==2)//计时器模式
{
CountTime();
}
else
{
Countflag=0;
PB5pushNum=0;
CountTimeStart=0;
countMiliSeconds=0;
}
if (Display_sel!=4)//倒计时进入休眠模式
{
dowmtime=9000;//倒计时初值ms
}
//显示模式选择
switch (Display_sel)
{
case 0://温湿度模式
UP_Disply=Temp;
DOWN_Disply=Humi;
ShowNum(1,1,UP_Disply/100,0);
ShowNum(1,2,UP_Disply/10 %10,1);
ShowNum(1,3,UP_Disply %10,0);
ShowNum(2,1, DOWN_Disply /100,0);
ShowNum(2,2, DOWN_Disply /10 %10,1);
ShowNum(2,3, DOWN_Disply %10,0);
EnterSTOPTime =60000;//等待进入休眠时间60000=1min
break;
case 1://时钟模式
display_h=sTime.Hours;
display_m=sTime.Minutes;
display_sec=sTime.Seconds;
clockset();//时间设定函数
//正常显示时间
if (!clocksetflag)//非时间设定模式--->正常显示时间
{
EnterSTOPTime =60000;//等待进入休眠时间60000=1min
ShowNum(1,2,display_h /10 %10,0);
//ShowNum(1,3,display_h %10,0);
ShowNum(2,2, display_m /10 %10,0);
//ShowNum(2,3, display_m %10,0);
//让点闪烁
if (!outpwm )
{
ShowNum(1,3,display_h %10,0);
ShowNum(2,3, display_m %10,1);
}
else
{
ShowNum(1,3,display_h %10,1);
ShowNum(2,3, display_m %10,0);
}
}
else
{
//clockset();//时间设定函数
}
break;
case 2://秒表模式
UP_Disply=CountMinutes;
DOWN_Disply=CountCseconds;
ShowNum(1,1,UP_Disply/100,0);
ShowNum(1,2,UP_Disply/10 %10,0);
ShowNum(1,3,UP_Disply %10,0);
ShowNum(2,1, DOWN_Disply /100,0);
ShowNum(2,2, DOWN_Disply /10 %10,1);
ShowNum(2,3, DOWN_Disply %10,0);
EnterSTOPTime =60000
60;//等待进入休眠时间60000=1min 1h
break;
case 3://电池电压
V_BAT=VIN9122/Vref ;
DOWN_Disply=V_BAT
2;
ShowNum(1,1,13,0);//b
ShowNum(1,2,12,0);//A
ShowNum(1,3,16,1);//t.
// ShowNum(1,1,UP_Disply/100,0);
// ShowNum(1,2,UP_Disply/10 %10,0);
// ShowNum(1,3,UP_Disply %10,0);
ShowNum(2,1, DOWN_Disply /100,1);
ShowNum(2,2, DOWN_Disply /10 %10,0);
ShowNum(2,3, DOWN_Disply %10,0);
EnterSTOPTime =60000;//等待进入休眠时间6000=1min
break;
case 4://睡眠模式
ShowNum(1,1,5,0);//S
ShowNum(1,2,15,0);//L
ShowNum(1,3,14,0);//E
ShowNum(2,1, 14,0);//E
ShowNum(2,2,17,1);//P
sleepdstart=1;
ShowNum(2,3,dowmtime/1000,0);//显示倒计时
if (dowmtime==0)
{
//进入睡眠模式
Close_Led();
HAL_SuspendTick(); //暂停滴答定时器,防止通过滴答定时器中断唤醒
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); /* 执行WFI指令, 进入深度睡眠模式 */
SystemClock_Config(); //恢复时钟
HAL_ResumeTick(); //恢复滴答定时器
Display_sel=0;
}
break;
default :
break;
}
}
}

实物展示说明

1.温湿度显示的样子如下:

上面数码管显示温度,下面数码管显示湿度。

微信图片_20240725200302.jpg
2.时钟显示的样子如下:

上面数码管显示时,下面数码管显示分,快速点两下按键,可进入时间设定模式。

setclock.png
3.秒表显示的样子如下:

上面数码管显示分钟,下面数码管显示秒,精确到0.1秒。

计时显示.png
4.电池电压显示的样子如下:

上面数码管显示字母BAT,下面数码管电压值。

显示bat.png
5.倒计时进入休眠的样子如下:

数码管SLEEP.秒。

显示sleep.png

注意事项

1.PCB元件焊接芯片元件放置方向必须放对,有个点标志要与PCB板上的点对应。
2.PCB元件焊接时,要注意管脚不可虚焊,或连锡短路现象。
3.小元件贴片电阻、贴片电容先焊,再焊芯片元件,直插件后焊,不耐热的元件比如LED灯,按键,后焊,并且不作过多停留。
4.如果PCB布局跟我一样,没改过的,温湿度传感器模块是采用4p 1.27mm插件模块,元件朝下, 插反了会烧温湿度传感器模块。 我就第一次插反了烧温湿度传感器模块。最好是电池焊点贴个胶布或其他绝缘的东西。

注意22.png

sh40_22.png

5.全部焊接完成后,一定要检查无误后才能接下载器,或接上电池。
6.下载器的3V3与电池最好不要同时接,接了下载器3V3管脚就可以不放电池,放了电池就可以不接下载器的3V3,只接CLK,DIO,GND。下载器的3V3与电池同时接时,质量不好的下载器容易烧坏。
7.下载官方程序时,进入休眠模式时间放长一点,不然一旦进入休眠,很不方便下载程序,下载我这程序没有这方面的问题,我这个进入休眠模式时间1分钟,休眠时,点一下按键,有一分钟的时间,足够时间让你下载程序。

使用说明

1.唤醒键每按住0.5秒一次就切换模式一下,模式顺序为:温湿度->时钟->秒表->电池电压->休眠->温湿度;
2.自动休眠,温湿度、时钟、电池电压模式下自动进入休眠时间为1分钟,秒表模式下自动进入休眠时间为1小时;
3.时钟模式下,双击唤醒键,进入“时”设置,时数字会闪,唤醒键每点一下,时+1,按住0.5秒确定,进入“分”设置,同样分数字会闪,唤醒键每点一下,分+1,按住0.5秒确定,保存住设置时间;
4.秒表模式下,点一下,开始计时,再点一下暂停计时,双击唤醒键秒表复位;
5.休眠模式下,倒计数9秒后,进入休眠.

演示视频

设计图

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

BOM

暂无BOM

附件

序号文件名称下载次数
1
实物展示.mp4
0
2
TEST_RTC_ADC_Project.rar
3
3
3e567618c9c19d98fbc5191db08c521f.mp4
1
克隆工程
添加到专辑
0
0
分享
侵权投诉

工程成员

评论

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

底部导航