Stm32_标准库_期末设计_温度测量&光照测量&手机与芯片通信实现信息的更新

这篇具有很好参考价值的文章主要介绍了Stm32_标准库_期末设计_温度测量&光照测量&手机与芯片通信实现信息的更新。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:

期末设计预期的效果是整个系统能对环境温度、环境的光照情况进行测量及显示,并且能对时间及日期进行显示。时间与日期的控制不再打算用按键进行修改,取而代之用蓝牙模块实现手机与蓝牙模块之间单向通信,即手机向蓝牙模块发送当前的时间或日期,蓝牙模块接受数据,通过内部代码对数据进行筛选与解析,最后更新芯片自身数据为手机发送的数据。


1.接线&效果&功能:

1、接线:

1、光敏传感器AO端口接GPIO_PA_0

2、热敏传感器AO端口接GPIO_PA_1

3、蓝牙模块端口RXD接GPIO_PA_9

4、蓝牙模块端口TXD接GPIO_PA_10

2、效果:

Stm32_标准库_期末设计_温度测量&光照测量&手机与芯片通信实现信息的更新,stm32,智能手机,嵌入式硬件
3、功能:

1、实时监控当前环境的温度范围为[- 20 ℃,+ 99 ℃]

2、实时监控当前环境的光照强度,光照强度由低到高为[0 , 100]

3、显示时间与日期

4、能接收手机传输的信息并整合更新自己的日期与时间


2. 实现:

1、手机与芯片单向通信:

主要利用了Stm32自带的串口通信功能,这个跟着网上大佬学就可以了

除此之外手机与芯片之间的单向通信还要解决以下几个问题:

1、如何确保接收数据的完整性?

2、如何判断传输数据的合法性?

3、如何对数据合理的分割整合?

解答如下:


—— 2023/10/16

(1) 确保接收数据的完整性:

首先需要注意的就是数据之所以会出现丢失,主要原因在于手机向接受端发送信息时,接收端不能及时接受信息,以至于前一个数据还未来的及接受就被后来的数据覆盖

数据不能被及时接收的原因:

网上常用数据接收代码:

void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
	Serial_RxData = USART_ReceiveData(USART1); //一个一个接收
	Serial_RxFlag = 1;
	USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}

由上述串口接收数据中断函数可以看出,触发中断后数据总是一个字节逐个被Serial_RxData变量接收

接着标记标志位Serial_RxFlag,主函数发现标志位变化,才会接受并储存Serial_RxData上的数据

这个逻辑看似没有问题,但漏洞在于,我们的主函数不可能时刻判断标志位的值是否变化吧?朴素的说主函数不可能就执行判断标志位是否变化这一个语句吧?正是由于主函数在执行其他语句的时候导致没能时刻观察标志位的变化,而导致数据不能被立即接收,最终导致了数据丢失

那么解决方向就显而易见了,即如何做到数据能在中断发生的时候就立即接收呢?
答案就是数组

优化代码:

void USART1_IRQHandler(void)//中断函数
{
	
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		news[I] = USART_ReceiveData(USART1);//读数据
		Serial_RxFlag = 1;//至标志位为有数据
		I ++;
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
		 
	}
}

在中断产生的时候就立即用数组进行接收,同时标记标志位

主函数发现标志位变化了,等待一会就可以获取数组,取出传输方发送的全部信息了


(2) 判断传输数据的合法性:

传输方发送的信息不可能都是符合标准的,那么如何对数据进行筛选就显得及其重要

首先对我们需要的正确信息进行分析其特点:

例如需要获取的正确信息如下:
    日期:2023/10/17
    时间:21:57:55

分析上述两个典型数据,可以发现日期的特点是数据里存在/,数据时间特点是有:,那么第一次筛选条件就是判断接收数据是否存在上述任意一种符号。

这个在数据传输阶段就可以用两个标志位判断:

if(news[i] == '/') flagDate = 1;
if(news[i] == ':') flagTime = 1;

接下来摆在面前的就是假若筛选后的数据里出现超过两个/:符号的时候

再进一步讲上若传入的数据符号为两个,但是传入的时间为25:15:80阁下又应该如何应对?

要解决上述问题还是要对传入数据的特点进行细节分析:

拿日期 2023/10/17 进行分析,其中/符号出现了两次我们完全可以用一个cnt在拆解数据的过程中进行计数,若最后cnt的大小不等于2的时候那么这个数据就会被判断为不合法这样符号问题就解决了


—— 2023/10/17

(3) 对数据合理的分割整合:

那么又如何对年份,月份,天数、进行判别呢?

这就需要将数据进行切割了拿2023/10/17 示范,分析数据,巧妙的是在2023出现的时候cnt = 0,也就是在2023之前没有出现/而到10出现的时候cnt = 1,最后17出现的时候自然cnt = 2恍然大悟用一个updateDate[cnt]分别对数据进行储存即可updateDate[0] = 2023、updateDate[1] = 10、updateDate[2] = 17再对这三个数据分别分析就可以最终判断传入的数据是否合法了!

实现代码:

uint8_t Function_DateState(unsigned int *updateDate, char *News){
	      uint8_t cnt = 0;
	      uint8_t i = 0;
	      uint8_t end = Serial_GetI();
	      char month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	      while(i < end){
					if(News[i] == '/') {
						 cnt ++;
						 i ++;
						 if(cnt >= 3) {
							 
							 return 0;
						 }
						 continue;
					}
					updateDate[cnt] = updateDate[cnt]* 10 + (News[i] - '0');
					i ++;
        }
				 
				if(cnt != 2) return 0;
				  
				if(Function_Numlength(updateDate[0]) >= 5 || updateDate[0] > 9999 || updateDate[0] == 0) return 0;
				
				if((updateDate[0] % 4 == 0 && updateDate[0] % 100 != 0 )|| updateDate[0] % 400 == 0) month[2] = 29;
	            else month[2] = 28;
				 
				if(Function_Numlength(updateDate[1]) >= 3 || updateDate[1] > 12 || updateDate[1] == 0) return 0;
				if(Function_Numlength(updateDate[2]) >= 3 || updateDate[2] > month[updateDate[1]]|| updateDate[2] == 0) return 0;
				
                Time_GetArrayMonth()[2] = month[2];//这里年份也会发生变化,要修改原有数据
				
				return 1;
				
}

(4) 实现过程产生的重大BUG及解决方法:

上述理论成立,接下来就是动手实践了。以下是在对功能以及细节实现过程中产生重大BUG原因的解答以及解决方法的揭秘:

为了让主函数main函数更加简洁,我将数据传输的侦测,处理以及更新都封装在主函数以外的文件中,主函数引用其头文件即可调用我提前封装好的函数,也就是因为封装这些函数,所以产生一些小问题以下列函数为例:

返回数据函数:

char * Serial_returnNews(void){//返还一个数组
	     char * array;
	     uint8_t i = 0;
	     array = (char *) malloc(sizeof(char) * 100);
	     Delay_ms(300);//等待数据传输完
	     while(i < I){//复制
				    if(news[i] == '/') flagDate = 1;
				    if(news[i] == ':') flagTime = 1;
				    array[i] = news[i];
				    i ++;
			 }
			 return array;
}

1、多次传输数据芯片出现卡机现象:

这个函数目的是将接收端存放在数组内的数据,传送至数据处理端,这里使用malloc创建了一个char数组将news数值的数据copy过来并作为返地址,由于此函数是个返还类型的函数,所以没办法及时清理掉这个新创建的array数组,但这不代表不需要清理

若不采取情理,运行程序,手机端在向芯片连续发送几次信息后,显示屏上的就会卡住,任凭怎么输入都没有反应。

究其原因就是因为大量因创建数组产生的地址泄露,导致最后芯片地址耗尽,停止工作

解决方法:

free(News);//释放空间必须释放否者发生地址紊乱,直接卡机

2、返回数据函数被离奇执行两次:

解决上述问题后,数据传输会卡机的现象就没有了,但是再多测试几次的时候,却惊奇的发现传输的数据和接收的数据还是会有误差,查看news数组的时候发现数据并没有丢失?!但传递到数据处理端就有问题?然而我的返还数组函数并没有问题啊,这个bug就很玄学了。

经过不懈排查体调试最终发现传输数据的时候,char * Serial_returnNews(void)被执行了两次?!这是我用cnt变量计数得来的,这个函数又没和别的中断函数重名,为啥调用一次执行两次?再说偏偏还执行两次,真是邪门…

重新更改调试方向,我将目标放在了主函数:

if(Serial_GetRxFlag() == 1)    //时刻监控标志位

这条语句是监控数据是否传输完成的,若传输完成则Serial_GetRxFlag()会返回1值并自动清0,主函数进入if语句内并处理数据

uint8_t Serial_GetRxFlag(void)//读取标志位后自动青除
{
	if (Serial_RxFlag == 1)
	{
		Serial_RxFlag = 0;
		return 1;
	}
	return 0;
}

再结合着中断传输数据函数判断:

void USART1_IRQHandler(void)//中断函数
{
	
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		news[I] = USART_ReceiveData(USART1);//读数据
		Serial_RxFlag = 1;//至标志位为有数据
		I ++;
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
		 
	}
}

看似没有问题,但要知道中断函数在接受数据的时候是一字节一字节的接受,当传输一串数据的时候Serial_RxFlag = 1语句就是一个持续的过程,也就是当传输一串数据的时候主函数if虽然获取了标志位,并将其制0,但后续数据继续传输的时候中断函数内的Serial_RxFlag = 1,仍会继续将标志位制1,这就是为什么if语句还会执行一次

解决方法在if语句结束的时候再次调用制0函数:

Serial_GetRxFlag();//制零否则if循环将会被执行两次

3、数据显示乱码:

这个问题单纯是因为使用中间变量接收数据完毕后没有将其恢复初始化,内部存有上次传输的数值,导致数据叠加乱码

解决方法:

 unsigned int updateTime[] = {0, 0, 0};
 unsigned int updateDate[] = {0, 0, 0};

2、时间&日期的实现:

时间、日期主要分别存入对应数组中,需要更改的话直接更改对应数组即可

unsigned int time[] = {22, 59, 30};
unsigned int date[] = {2023, 12, 31};
char month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

主函数需要提取对应数组的话,直接调用提取数组函数即可:

unsigned int * Time_GetArrayTime(void){
	       return time;
}

unsigned int * Time_GetArrayDate(void){
	       return date;
}
char * Time_GetArrayMonth(void){
	       return month;
}

时间计数,采用的是芯片计数器功能,在记满相应数值,达到1s触发中断函数,对时间日期进行更新

中断函数:

void TIM2_IRQHandler(void){//定时器2
	   //主要运用时间更新
	   if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){
			 TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清除标志位
			 Time_Control(time, month, date);
		 }
}

注意:时间显示中断抢占优先级要设置的比,串口输入中断等级低一点,否者串口传入数据会由于时间中断函数与其抢占CPU导致接受数据丢失,中断函数的名字及类型最好不要更改避免产生相应不必要的BUG

时间中断等级设置:

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

—— 2023/10/19

3、温度&光照的测量:

主要用到了Stm32的数据转换功器(ADC)
通俗来说,正常的GPIO口只能读取0或1即低电平和高电平,而在低电平与高电平这一区间内的电平却无法描述,Stm32的ADC正可以解决这个问题,朴素的来讲ADC能让GPIO口成为一个电压表
而温度传感器,光敏传感器就是因为温度或光照的变化导致内部电阻阻值发生变化,最后导致其输出电压发生变化,GPIO口通过读取这些电压的具体量,再由人为对这些数据量做一些数据处理就能转换成我们想要的摄氏度、光照强度,以下是数据转换公式:

1.光照模拟量转实际光照强度:

uint16_t Function_RealityADLight(uint16_t ADCnum){//获取光照强度
	  return 100 - ADCnum / 40;
}

2.温度模拟量转实际摄氏度:

这个网上找的公式不能用,问了人家说只知道成线性关系,所以带入两组数据自己测了一个函数关系用起来还不错凑活着用:

int32_t Function_RealityTmperature(uint16_t Vout){//获取实际温度
	   double T = 0;//获取的实际温度
	   T = -0.0423 * Vout + 105 + 0.5;//模拟电压转实际温度公式
	   return (int32_t) T; 
}

这个温度可以测出负温度,为了严谨,用了double变量转换温度


4、OLED显示优化:

OLED:

我对OLED的理解就是它一行有128个点,显示一个字母需要消耗这一行其中8个点,且字符是分两部分打印,上一半和下一半,一行最多打印16个字符,最多能打印四列

OLED程序源中提供了输出字符、清屏、以及输出符号类数字等功能,还是相当丰富的

但是为了让显示屏显示光照、温度的效果达到最佳,还是迫切需要对OLED库中扩充一些功能

1.解决输出无符号数字不足规定长度自动补零的缺陷:

OLED提供的源显示数据函数:

void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)

这个函数需要提前写入你要显示的数字长度,后续数字长度不足会在前面补零
Stm32_标准库_期末设计_温度测量&光照测量&手机与芯片通信实现信息的更新,stm32,智能手机,嵌入式硬件
如上述显示及其影响美观,所以添加一个能实时监控输入数字长度的函数:

uint8_t Function_Length(uint16_t num){
	  uint8_t length = 0;
	  if(num == 0) return (uint8_t) 1;
	  while(num > 0){
		   num = num / 10;
		   length = length + 1;
	  }
	  return length;
}

这不学的算法就用上了,注意0的长度是1

由于温度有正有负,所以需要一个检测有符号数字长度的函数:

uint8_t Function_SignedNum_Length(int32_t num){
	      uint8_t length = 1;//符号位占1位
	      if(num == 0) return (uint8_t) 1;
	      if(num < 0) num = - num;
	      while(num > 0){
					   num = num / 10;
					   length = length + 1;
				}
	      return length;
}

由于OLED库函数的输出有符号数字事先未考虑计算符号长度,而是提前添加正负号,所以其也得修改

void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length)
{
	uint8_t i;
	uint32_t Number1;
	Length = Length - 1;
	if (Number >= 0)
	{
		OLED_ShowChar(Line, Column, '+');
		Number1 = Number;
	}
	else
	{
		OLED_ShowChar(Line, Column, '-');
		Number1 = -Number;
	}
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + '0');
	}
}

2.解决数据刷新造成的数据显示不连贯效果:

OLED数据刷新是采用覆盖式的例如上一次数据显示19这一次要写入9的时候不足位会补0也就是显示09,但由于上述操作让其位数不足不会补0,也就是说显示的将不会是09而是显示99即1被这次要写入的9覆盖掉了而后面的数据却没有被覆盖了,这涉及的就不是美不美观的问题了,直接就显示错了数据

所以必须要将后面的数清理掉,OLED库函数提供的只有清屏函数,简单粗暴全部清理掉,再全部写入

这样做有很多不便之处,原因在于整体清除刷新需要大量时间OLED显示起来整体就不连贯影响美观,还有就例如日期数据就没必要一直刷新,只有天数变了才需要刷新,没必要放在while循环内。所以迫切需要一个能清除某片区域的函数,以便能为美化OLED显示以及后续代码的优化提供功能支持

清除特定区域函数:

void OLED_ClearLocation(uint8_t row, uint8_t begin, uint8_t end)
{  
	uint8_t i, j;
	for (j = row * 2 - 2; j < row * 2; j++)
	{
		OLED_SetCursor(j, begin * 8);
		for(i = begin * 8; i < end * 8; i ++)
		{
			OLED_WriteData(0x00);
		}
	}
}

根据清屏函数重写一个清除某区域的函数,参数分别表示要删除的行,以及从哪里清除,到哪里结束。

3.添加OLED显示汉字功能:

利用取模软件对想要输出汉字进行取模,根据已有输出字符函数原理创建输出汉字函数

Stm32_标准库_期末设计_温度测量&光照测量&手机与芯片通信实现信息的更新,stm32,智能手机,嵌入式硬件
封装汉字数组:

const uint8_t OLED_F10x16[][32] ={

0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,/*"温",0*/
	
0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,/*"度",1*/

0x40,0x40,0x42,0x44,0x58,0xC0,0x40,0x7F,0x40,0xC0,0x50,0x48,0x46,0x40,0x40,0x00,
0x80,0x80,0x40,0x20,0x18,0x07,0x00,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x78,0x00,/*光,2*/

0x00,0xFE,0x42,0x42,0x42,0xFE,0x00,0x42,0xA2,0x9E,0x82,0xA2,0xC2,0xBE,0x00,0x00,
0x80,0x6F,0x08,0x08,0x28,0xCF,0x00,0x00,0x2F,0xC8,0x08,0x08,0x28,0xCF,0x00,0x00,/*"照",3*/

0x00,0x08,0x30,0x00,0xFF,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x22,0x2C,0x20,0x00,
0x04,0x04,0x02,0x01,0xFF,0x80,0x40,0x30,0x0E,0x01,0x06,0x18,0x20,0x40,0x80,0x00,/*"状",4*/

0x00,0x04,0x84,0x84,0x44,0x24,0x54,0x8F,0x14,0x24,0x44,0x84,0x84,0x04,0x00,0x00,
0x41,0x39,0x00,0x00,0x3C,0x40,0x40,0x42,0x4C,0x40,0x40,0x70,0x04,0x09,0x31,0x00,/*"态",5*/
};

显示汉字函数:

void OLED_ShowCHINESE(uint8_t Line, uint8_t Column, uint8_t Num)
{
	
	uint8_t i;
	uint8_t wide = 16;//字宽
	
	OLED_SetCursor(( Line - 1 ) * 2, ( Column - 1 )* wide);		//参数1:把光标设置在第几页. 参数2:把光标设置在第几列
	for (i = 0; i < wide; i++)
	{
		OLED_WriteData(OLED_F10x16[Num][i]);			//显示上半部分内容
	}
	
	OLED_SetCursor(( Line - 1 ) * 2 + 1,( Column - 1) * wide);		
	for (i = 0; i < wide ; i++)
	{ 
		OLED_WriteData(OLED_F10x16[Num][i+wide]);		//显示下半部分内容
	}

}

参考来源:OLED显示汉字及屏幕滚动


5、主函数的设计与布局:

为了使主函数布局清晰,所以对主函数的代码进行了最大可能的优化,采用函数嵌套函数的方式,反正Stm32函数已经够多了我再添加一点也很核理,这样做的优点就是思路清晰,后续添加新功能的时候也很方便明了,缺点就是查bug的时候得来回跳转,不过我是确认没有大bug的情况下才开始优化的

主函数:

#include "ADC.h" 
#include "OLED.h"
#include "Time.h" 
#include <stdio.h>
#include "Delay.h"
#include <stdlib.h>
#include "Serial.h"
#include "Function.h"
#include "stm32f10x.h"   

char *News = NULL; //存数据
 
int main(void){
	
AD_Init();                               //开启ADC
OLED_Init();                            //开启显示器
Time_Init();                           //开启计时器
Serial_Init();                        //开启串口允许接收数据
Function_ShowTransmit();	           //显示接收数据的状态
Time_ShowDate(Time_GetArrayDate()); //显示日期
	
while(1){
		
		Time_Show(Time_GetArrayTime());            //时刻显示温度
		ADC_printf(ADC_Channel_0, ADC_Channel_1); //时刻获取温度&光照强度并显示
		 
		if(Serial_GetRxFlag() == 1){     //时刻监控标志位
			 News = Serial_returnNews();  //获取传输的数据
			 Function_DP(Serial_GetFlagTime(), Serial_GetFlagDate(), Time_GetArrayTime(), Time_GetArrayDate(), News); //对获取的数据进行筛选处理并自我更新
			 Serial_StateRecovery(News); //数据恢复初始化
		}
 
	  }
}

与主函数搭配的库函数:

Stm32_标准库_期末设计_温度测量&光照测量&手机与芯片通信实现信息的更新,stm32,智能手机,嵌入式硬件


3. 总结:

明白了学习嵌入的过程就是理解并能灵活使用其提供的库函数的过程

要有自己的创新与解决问题的能力

将功能尽可能封装,能使代码思路更加清晰


4.程序源码:

链接:https://pan.baidu.com/s/1WsZ7dTRUMHRa8jaXDtmrpA?pwd=ws6f

提取码:ws6f


—— 2023/10/18文章来源地址https://www.toymoban.com/news/detail-723635.html

到了这里,关于Stm32_标准库_期末设计_温度测量&光照测量&手机与芯片通信实现信息的更新的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 毕业设计——基于STM32的智能家具控制系统(ESP-01S(8266)、手机app远程控制、远程显示温度)

    智能家具系统分为两个不同版本系列: ①系列一:手机app远程控制、远程检测温湿度显示在app,(云平台)    ---------本文章 ②系列二:语音识别控制                https://blog.csdn.net/m0_59113542/article/details/123742383 步进电机及相关驱动 步进电机28BYJ48 uln2003驱动板器4相5线

    2023年04月09日
    浏览(44)
  • 97、基于stm32单片机智能药箱药盒温湿度体温光照时钟wifi手机APP监控(程序+原理图+PCB源文件+手机APP源码+硬件设计资料+元器件清单等)

    单片机类型选择 方案一:可以使用现在比较主流的单片机STC89C5单片机进行数据处理。这款单片机具有的特点是内存和51的单片机相比多了4KB内存,但是价格和51单片机一样。并且支持数据串行下载和调试助手。此款单片机是有ATMEL公司生产,可用5V电压编程,而且擦写时间仅需

    2024年02月13日
    浏览(40)
  • 基于STM32的电阻、电容测量(NE555芯片RC振荡法)

    做的一个关于电阻和电容的测量电路,都是比较通用的。经过实际测试,电容测量电路还是可以的,电阻测量电路有一个缺点就是,随着测量时长的推移,在小电阻的测量时,比如0-100欧姆测量时,检测到的RC震荡频率会增加, 所以小电阻需要校正一下,否则小电阻容易出现

    2024年02月04日
    浏览(267)
  • 基于STM32设计的炉温温度检测仪

    炉温检测在现代工业生产中十分重要,因为炉温过高或过低都会对产品质量产生影响,甚至影响工厂的正常运作。因此,设计一款能够精准测量炉温并显示结果的检测仪器具有很大的实用价值。 本项目采用了STM32F103C8T6作为主控芯片,该芯片拥有丰富的外设和性能较好的计算

    2024年02月07日
    浏览(36)
  • 基于STM32(HAL库)的水质检测(浑浊度、PH值、温度、手机APP显示、wifi上云)

    本系统由通过wifi将浑浊度、PH值、温度采集的数据发送到手机APP,超过设定的阈值报警。 一、硬件材料清单: 1、STM32C8T6:控制器 2、OLED显示屏:显示传感器采集的数据 3、PH传感器:检测PH值 4、TDS传感器:检测浑浊度 5、DS18B02水温传感器:检测温度 6、ESP8266:将数据发送到

    2023年04月08日
    浏览(27)
  • STM32 Proteus UCOSII系统锅炉报警系统设计压力温度水位-0059

    STM32 Proteus UCOSII系统锅炉报警系统设计压力温度水位-0059 Proteus 仿真小实验: STM32 Proteus UCOSII系统锅炉报警系统设计压力温度水位-0059 功能: 硬件组成:51单片机 +8位数码管+MAX7219数码管驱动模块++多个按键+LED灯+蜂鸣器 1.准确测量信号发生器输出的方波频率信号(速度)(

    2024年02月13日
    浏览(38)
  • 基于STM32单片机的智能家居烟雾温度火灾防盗报警的设计与实现

        功能介绍 以STM32单片机作为主控系统; LCD1602液晶显示屏来显示显示测得的值; SR501人体红外感应是否有人进行防盗; 通过烟雾传感器MQ-2获取前的烟雾值; 通过DHT11温湿度传感器来获取当前的温湿度; 所有的信息通过通过esp8266 wifi把数据传输到手机端进行显示;    

    2024年02月15日
    浏览(38)
  • 用STM32单片机ADC+NTC热敏电阻采集温度的设计思路 | 附参考电路

    目录 前言 一、热敏电阻NTC 二、参考电路  三、激励电压选择 记录一些我在工作和学习过程中遇到的问题 NTC:在淘宝随便买的 单片机型号:STM32G030C8T6 目的:用单片机采集NTC温度 本文主要是介绍关于NTC激励电压的选择        热敏电阻 NTC(Negative Temperature Coefficient) , 直

    2024年02月02日
    浏览(39)
  • 毕业设计常用温度测量模块之DS18B20温度传感器介绍

    DS18B20是一种单总线数字温度传感器,测试温度范围-55℃-125℃,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。 单总线通信 ,意味着没有时钟线,只有一根通信线。单总线读写数据是靠控制起始时间和采样时间来完成,所以时序要求很严格,这也是DS18B20驱动编程

    2024年02月08日
    浏览(35)
  • 70、基于STM32单片机的蓝牙智能热水器控制系统设计温度温控水温水位检测

    毕设帮助、开题指导、技术解答(有偿)见文末。 目录 摘要 一、硬件方案 二、设计功能 三、实物图 四、原理图 五、PCB图 六、硬件框图 七、程序源码 八、资料包括 随着社会的发展,人类科技的进步,各行各业都在使自己的产品智能化、数字化,因老式的热水器使用煤气

    2024年02月05日
    浏览(94)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包