专业版
#第九届立创电赛#温湿度检测仪

创建时间:4个月前

132 0

描述

<h2>视频链接:</h2> <p><a href="https://www.bilibili.com/video/BV17uYTedETb/?pop_share=1&amp;vd_source=4948554f342901cce6a4269d440c97d3" target="_blank">B站视频--功能演示及介绍</a></p> <h2>项目简介</h2> <p>该项目使用“盛思锐传感器”,高精度、小体积,非常适用于温湿度项目制作。</p> <h2>项目功能</h2> <p>温湿度检测<br> 桌面温湿度检测仪通过SHT40检测室内温湿度,通过两个3位共阴极数码管显示数据,整体使用两节5号电池进行供电,非触发时处于休眠状态,预计使用时长6个月。</p> <p>温湿度检测仪项目使用STM32G030K6T6芯片作为主控芯片,该芯片使用ARM-Cortex-M0+内核;最大主频64Mhz;具有32KB的FLash和8K的SRAM,供电电压在2.0V~3.6V之间。</p> <h2>软件代码</h2> <p>使用STM32CubeMx软件生成代码为共阳极,并把显示效果改成温湿度同显示。</p> <p>电池进行供电,考虑到功耗问题,默认不开机,进入睡眠模式。当有按键按下时,触发中断,此时结束睡眠模式,执行按键判断,获取温湿度并启动数码管进行显示;同时启动定时器中断,循环显示两次数据后再次进入睡眠,等待下次唤醒。</p> <p>重点是中断,STM32G0系列使用Arm Cortex M0+内核,是两级流水线的冯诺依曼结构,具有4位中断优先级。这些与STM32F103是不一致的。</p> <p>重点介绍一下如何进入休眠模式以及定时器中断。</p> <p>STM32G0系列有四种休眠模式;</p> <p>低功耗运行模式(降低CPU频率,系统仍在运行) 睡眠模式(系统进入睡眠,任意中断/事件唤醒) 停止模式(系统进入停止,支持任意外部中断和RTC闹钟唤醒) 待机模式(系统进入待机,支持RTC闹钟唤醒,WKUP、NRST引脚唤醒以及IWDG复位唤醒,打开了LSI和LSE)</p> <p>注意以上模式均不可进行Debuge调试,系统时钟已经关闭;且设置为低功耗模式后,无法下载代码,需要唤醒后才能进行下载;详细说明可以查看具体数据手册。</p> <p>大家根据实际情况进行设置,综合代码设置为睡眠模式。</p> <p>睡眠模式代码</p> <pre><code>//进入睡眠模式 HAL_SuspendTick(); //暂停滴答定时器,防止通过滴答定时器中断唤醒 HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); /* 执行WFI指令, 进入睡眠模式 */ //退出睡眠模式,任意中断/事件退出 HAL_ResumeTick(); //恢复滴答定时器</code></pre> <p>在Cubemx中设置了定时器14中断,代码中默认是不开启的,启动后自动开始计时。计时时间到来后进入溢出中断。 定时器溢出中断回调函数,由于计时时间较短,在回调函数中加入累加变量,表示数据显示时间,假设一1s为周期,前半秒显示温度数据,后半s显示湿度数据,显示完两次后进入休眠。 </p> <p>定时器相关代码</p> <pre><code>HAL_TIM_Base_Start_IT(&amp;htim14); //开始定时器 HAL_TIM_Base_Stop_IT(&amp;htim14); //停止定时器 /* 函数内容:定时器溢出中断回调函数 函数参数:TIM_HandleTypeDef *htim--定时器句柄 返回值: 无 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim->Instance == TIM14) { HAL_TIM_Base_Stop_IT(&amp;htim14); updata_flag++; if(updata_flag &lt;= 5000) { ShowNum(1,1,(device_paramter.Temp/100)); ShowNum(1,2,(device_paramter.Temp / 10 % 10)); ShowNum(1,3,device_paramter.Temp%10); } else if(updata_flag &lt;= 10000) { ShowNum(2,1,(device_paramter.Humi/100)); ShowNum(2,2,(device_paramter.Humi / 10 % 10)); ShowNum(2,3,device_paramter.Humi%10); } else { updata_flag = 0; sleep_flag++; } __HAL_TIM_SetCounter(&amp;htim14,0); if(sleep_flag >= 2) { sleep_flag = 0; device_paramter.sleepStatus = 1; SN74HC595_Send_Data(SN_DIG,0xFF); SN74HC595_Send_Data(SN_LED1,0x00); SN74HC595_Send_Data(SN_LED2,0x00); } else{ HAL_TIM_Base_Start_IT(&amp;htim14); } } }</code></pre> <p>数码管优化,在前面的案例中,会看到数码管亮度不尽人意,这是因为此时主频太快导致显示过短;在原来的代码中,显示数据后立刻进行消影操作。此时CPU主频为64Mhz,执行速度较快,导致数据显示过暗。 在原有的基础上,加入一个us延时,数据显示出来后,延时一点点时间再消影,这样显示效果就好很多了。</p> <p>优化数码管显示</p> <pre><code>/* 64Mhz时钟时,当ulCount为1,函数耗时3个时钟,延时=3*1/64us */ __asm void SysCtlDelay(unsigned long ulCount) { SUBS r0,#1; BNE SysCtlDelay; BX lr; } /* 函数内容:数码管显示数据函数 函数参数:uint8_t row----行号 uint8_t column-列号 uint8_t value--显示数据 返回值:无 */ void ShowNum(uint8_t row, uint8_t column, uint8_t value) { if(row == 1) { switch(column) { case 1: //如果是第一排第一个 SN74HC595_Send_Data(SN_DIG,0xFE); SN74HC595_Send_Data(SN_LED1,sgh_value[value]);//显示值对应16进制数 break; case 2: SN74HC595_Send_Data(SN_DIG,0xFD); SN74HC595_Send_Data(SN_LED1,(sgh_value[value]|0x80)); break; case 3: SN74HC595_Send_Data(SN_DIG,0xFB); SN74HC595_Send_Data(SN_LED1,sgh_value[value]); break; default: break; } SysCtlDelay(1000); //大致延时50us SN74HC595_Send_Data(SN_LED1,0x00); //消影,防止错位 } else { switch(column) { case 1: SN74HC595_Send_Data(SN_DIG,0xF7); SN74HC595_Send_Data(SN_LED2,sgh_value[value]); break; case 2: SN74HC595_Send_Data(SN_DIG,0xEF); SN74HC595_Send_Data(SN_LED2,(sgh_value[value]|0x80)); break; case 3: SN74HC595_Send_Data(SN_DIG,0xDF); SN74HC595_Send_Data(SN_LED2,sgh_value[value]); break; default: break; } SysCtlDelay(1000); //大致延时50us SN74HC595_Send_Data(SN_LED2,0x00); } }</code></pre> <h3>ADC电压采集</h3> <p>桌面温湿度仪使用两节5号电池用于整个系统供电,这里加入一个分压电阻用于检测电池电压 <img src="//image.lceda.cn/oshwhub/1c8a8eca248d4835b6fe7de3d6ed62f9.png" alt="image.png"></p> <p>使用两个10K对电压值进行分压,然后通过单片机ADC进行电压读取,对于3V电池,其实可以直接输入到单片机的IO口进行读取,但是大多数情况都是使用分压电阻来进行,这里我也不做改动。</p> <p>在工程中,会增加一个adc文件,存放ADC相关初始化代码,重要的是ADC句柄,后续启动读取操作通过句柄来进行指定。 注意在gpio.c文件中添加数码管相关驱动代码,这些在之前的课程中都有介绍,我就不重复讲解了。 直接在main.c中添加ADC转换代码,这里配置的是软件触发,若像获得更高的精度,可以在初始化后进行ADC校准;</p> <p>注意此处我们使用DAPLink进行测试,DAPLink是3.3V,所以转换的AD值是✖3.3V,后续使用电池供电是3V,需要进行修改。 且随着电池电压的降低,此处的测量精度也会逐渐下降,准确的测量应该是使用内部基准源做参考。</p> <pre><code> /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ uint32_t ADC_Value = 0; float Data = 0; uint16_t Vol_Value = 0; /* USER CODE END 1 */</code></pre> <p>/<em> MCU Configuration--------------------------------------------------------</em>/</p> <p>/<em> Reset of all peripherals, Initializes the Flash interface and the Systick. </em>/ HAL_Init();</p> <p>/<em> USER CODE BEGIN Init </em>/</p> <p>/<em> USER CODE END Init </em>/</p> <p>/<em> Configure the system clock </em>/ SystemClock_Config();</p> <p>/<em> USER CODE BEGIN SysInit </em>/</p> <p>/<em> USER CODE END SysInit </em>/</p> <p>/<em> Initialize all configured peripherals </em>/ MX_GPIO_Init(); MX_ADC1_Init(); /<em> USER CODE BEGIN 2 </em>/ HAL_Delay(100); SN74HC595_Send_Data(SN_DIG,0x00); SN74HC595_Send_Data(SN_LED1,0x00); SN74HC595_Send_Data(SN_LED2,0x00);</p> <pre><code>HAL_ADCEx_Calibration_Start(&amp;hadc1); //ADC校准 HAL_ADC_Start(&amp;hadc1); //启动ADC转换 HAL_ADC_PollForConversion(&amp;hadc1, 50); //等待转换完成,50为最大等待时间,单位为ms if(HAL_IS_BIT_SET(HAL_ADC_GetState(&amp;hadc1), HAL_ADC_STATE_REG_EOC)) { ADC_Value = HAL_ADC_GetValue(&amp;hadc1); //获取AD值 Data = (ADC_Value*3.3f)/4095.0f; }</code></pre> <p>/<em> USER CODE END 2 </em>/ Vol_Value = (uint16_t)(Data <em> 100)</em>2; /<em> Infinite loop </em>/ /<em> USER CODE BEGIN WHILE </em>/ while (1) { /<em> USER CODE END WHILE </em>/ ShowNum(1,1,Vol_Value / 100); ShowNum(1,2,Vol_Value /10 %10); ShowNum(1,3,Vol_Value % 10); /<em> USER CODE BEGIN 3 </em>/ } /<em> USER CODE END 3 </em>/ }</p> <pre><code> ## 注意事项 注意不要用洗板水刷到数码管以及电池盒这类橡胶材料的 我干脆直接刷白了,刷不干净也不要再刷了。不然整个腐蚀了。焊接完贴片的就可以洗下板子 ## 实物图 ![image.png](//image.lceda.cn/oshwhub/6ae2484a15014ab6b102f2be19c704d3.png)</code></pre>

文档

BOM

暂无

附件

附件名 下载
阳极同显.zip

评论(0)

  • 表情
    emoji
    小嘉工作篇
    小嘉日常篇
  • 图片
成功
工程所有者当前已关闭评论
goToTop
svg-battery svg-battery-wifi svg-books svg-more svg-paste svg-pencil svg-plant svg-ruler svg-share svg-user svg-logo-cn svg-double-arrow