基于STM32F407的一个温度传感器报警系统(用的是DS18B20温度传感器,4针0.96寸OLED显示屏,并且附带日期显示)

基于STM32F407的一个温度传感器报警系统(用的是DS18B20温度传感器,4针0.96寸OLED显示屏,并且附带日期显示)

本次所实现的功能是实时监测环境温度(用的是DS18B20温度传感器,稳定性好,抗干扰能力强,很任性也很人性,使用起来贼方便)。

并且用OLED显示屏显示出来,且会有一个报警的简单逻辑(超出所设定的范围就会有声光报警)。人性化起见,又添加了日期显示(各位仁兄做日期的这里也是可以嫖的,日期我已经校准)。

只要是STM32F4的芯片,都可以用,可移植性好。兄弟们可以在我这个代码的基础上增添功能,都是可以而且非常方便的。测试n次,性能稳定。

经验总结

本人做这个工程前后花了3天左右,以至于我的作业都落下了好多(笑哭),主要是网上的资源还是比较多的,我呢就是将它们整合了一下,然后进行精简(本人有个强迫症,就是没有用的代码部分我是断然不会留它的,所以代码就会显得很精简),再添加一些自己的东西,整个东西也就做出来了。

实测有效,而且功能还挺稳定。还加了一个声光预警(在主函数部分,我把他给注释掉了,因为那个蜂鸣器响的让我心慌,只要温度不在22-24摄氏度(人体在环境中的最适宜温度)范围内,都会报警)。当然主要的作用还是显示温度。各位仁兄在用的时候可以直接复制粘贴相对应的功能部分,这个是很方便的。

(本次上传的代码对于比较懂的仁兄已经够用,如果还有仁兄想要参考完整的源码,可加我微信:wpt666aaa 或QQ:2036795517),这个很方便的。

各位仁兄,废话不多说,直接上代码!!!

主要代码

主函数部分(认真阅读,你一定会有收获的):

#include "sys.h"
#include "OLED_I2C.h"
#include "usart.h"
#include "rtc.h"
#include "led.h"
#include "beep.h"
#include "ds18b20.h"

int main(void)
{
   RTC_TimeTypeDef RTC_TimeStruct;
   RTC_DateTypeDef RTC_DateStruct;
	u8 a[40];
	u8 t=0;
	short temperature;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);      //初始化延时函数
	uart_init(115200);		//初始化串口波特率为115200
	LED_Init();		//初始化LED
	BEEP_Init();
	DS18B20_Init();
	My_RTC_Init();		 		//初始化RTC
	RTC_Set_WakeUp(RTC_WakeUpClock_CK_SPRE_16bits,0);		//配置WAKE UP中断,1秒钟中断一次	
	I2C_Configuration();
	OLED_Init();
	OLED_ShowString(10,45,"Temp:   .  C",16);
	
	while(1)
	{
 	   	if(t%10==0)		//每100ms更新一次显示数据
		{									  
						    
			temperature=DS18B20_Get_Temp();	
					
//			//报警部分
//			if(temperature>240)
//			{
//				LED0=1;
//				BEEP=0;
//				delay_ms(500);
//				LED0=0;
//				BEEP=1;
//				delay_ms(500);
//	
//			}
//			if(temperature<220)
//			{
//				LED1=1;
//				BEEP=0;
//				delay_ms(500);
//				LED1=0;
//				BEEP=1;
//				delay_ms(500);
//				
//			}
			
			
			
			//温度显示部分	
			if(temperature<0)
			{
				OLED_ShowChar(53,45,'-',16);			//显示负号
				temperature=-temperature;					//转为正数
			}else OLED_ShowChar(53,45,' ',16);			//去掉负号
			OLED_ShowNum(56,45,temperature/10,2,16);	//显示正数部分	    
   			OLED_ShowNum(83,45,temperature%10,1,16);	//显示小数部分 		 
			
		
			
			//日期显示部分
			RTC_GetTime(RTC_Format_BIN,&RTC_TimeStruct);
			sprintf((char*)a,"Time:%02d:%02d:%02d",RTC_TimeStruct.RTC_Hours,RTC_TimeStruct.RTC_Minutes,RTC_TimeStruct.RTC_Seconds); 
			OLED_ShowString(1,5,a,16);
			RTC_GetDate(RTC_Format_BIN, &RTC_DateStruct);
			sprintf((char*)a,"Date:20%02d-%02d-%02d",RTC_DateStruct.RTC_Year,RTC_DateStruct.RTC_Month,RTC_DateStruct.RTC_Date); 
			OLED_ShowString(1,20,a,16);		
		}				   
	 	delay_ms(10);
		t++;		
	}  
}

OLED_I2C.C文件比较重要代码


void OLED_ShowChar(u8 x,u8 y,u8 ch,u8 size)
{
	u8 i,j;
	u16 cnt=0;
	if(x>127){x=0;y+=2;}
	for(j=0;j<64/8;j++)								//y最大坐标64  共有8页
	{
		if(size/8.0<=j*1.0)return;
		OLED_SetPos(x,y/8+j);
		for(i=0;i<size/2;i++)
		{
			if(size==12)OLED_Send_Data(ASCII_6_12[ch-' '][cnt++]);
			else if(size==16)OLED_Send_Data(ASCII_8_16[ch-' '][cnt++]);
			else if(size==24)OLED_Send_Data(ASCII_12_24[ch-' '][cnt++]);
			else return;
		}
	}
	
}

//显示字符串
void OLED_ShowString(u8 x,u8 y,u8 *p,u8 size)
{
    while((*p<='~')&&(*p>=' '))//判断是不是非法字符!
    {       
        if(x>(128-(size/2))){x=0;y+=size;}
        if(y>(64-size)){y=x=0;OLED_Clear();}
        OLED_ShowChar(x,y,*p,size);	 
        x+=size/2;
        p++;
    }  
	
}


u32 mypow(u8 m,u8 n)
{
	u32 result=1;	 
	while(n--)result*=m;    
	return result;
}	

//显示温度的用的函数		
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)
{         	
	u8 t,temp;
	u8 enshow=0;						   
	for(t=0;t<len;t++)
	{
		temp=(num/mypow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				OLED_ShowChar(x+(size/2)*t,y,' ',size);
				continue;
			}else enshow=1; 
		 	 
		}
	 	OLED_ShowChar(x+(size/2)*t,y,temp+'0',size); 
	}
} 

ds18b20.c文件全部代码

//复位DS18B20
void DS18B20_Rst(void)	   
{                 
	DS18B20_IO_OUT(); //SET PG11 OUTPUT
  DS18B20_DQ_OUT=0; //拉低DQ
  delay_us(750);    //拉低750us
  DS18B20_DQ_OUT=1; //DQ=1 
	delay_us(15);     //15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void) 	   
{   
	u8 retry=0;
	DS18B20_IO_IN();//SET PG11 INPUT	 
    while (DS18B20_DQ_IN&&retry<200)
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=200)return 1;
	else retry=0;
    while (!DS18B20_DQ_IN&&retry<240)
	{
		retry++;
		delay_us(1);
	};
	if(retry>=240)return 1;	    
	return 0;
}
//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void) 			 // read one bit
{
  u8 data;
	DS18B20_IO_OUT();//SET PG11 OUTPUT
  DS18B20_DQ_OUT=0; 
	delay_us(2);
  DS18B20_DQ_OUT=1; 
	DS18B20_IO_IN();//SET PG11 INPUT
	delay_us(12);
	if(DS18B20_DQ_IN)data=1;
  else data=0;	 
  delay_us(50);           
  return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)    // read one byte
{        
    u8 i,j,dat;
    dat=0;
	for (i=1;i<=8;i++) 
	{
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }						    
    return dat;
}
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)     
 {             
    u8 j;
    u8 testb;
	  DS18B20_IO_OUT();//SET PG11 OUTPUT;
    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;
        dat=dat>>1;
        if (testb) 
        {
            DS18B20_DQ_OUT=0;// Write 1
            delay_us(2);                            
            DS18B20_DQ_OUT=1;
            delay_us(60);             
        }
        else 
        {
            DS18B20_DQ_OUT=0;// Write 0
            delay_us(60);             
            DS18B20_DQ_OUT=1;
            delay_us(2);                          
        }
    }
}
//开始温度转换
void DS18B20_Start(void)// ds1820 start convert
{   						               
    DS18B20_Rst();	   
	  DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0x44);// convert
} 
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
u8 DS18B20_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG时钟

  //GPIOG9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化
 
 	DS18B20_Rst();
	return DS18B20_Check();
}  
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250) 
short DS18B20_Get_Temp(void)
{
    u8 temp;
    u8 TL,TH;
	  short tem;
    DS18B20_Start ();                    // ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0xbe);// convert	    
    TL=DS18B20_Read_Byte(); // LSB   
    TH=DS18B20_Read_Byte(); // MSB   
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
        temp=0;//温度为负  
    }else temp=1;//温度为正	  	  
    tem=TH; //获得高八位
    tem<<=8;    
    tem+=TL;//获得底八位
    tem=(double)tem*0.625;//转换     
	if(temp)return tem; //返回温度值
	else return -tem;    
}

至于 rtc.c文件的源码这里就不多说了,有要的仁兄可以私聊我(文章开头的两个联系方式均可)。想要整个工程源码的仁兄也可以私聊我。

实验结果图片

上部分为日期显示,下部分为温度显示

最后的最后

1.一定要多阅读代码。我是查阅了CSDN上几乎所有的相关代码,各种修改,删减,浓缩成现在这个样子。你们可以在我这个代码的基础上添加各种功能,如果不需要,你就可以直接拿来用了。

2.你只有看懂了,才能拿来用,所以最好不要放过任何一个疑问,说不定这个疑问就是解决问题的关键。

最后的最后,支持还是要支持一下的,请求各路英雄豪杰多多打赏,多多关注,多多点赞,我是只发布高质量文章的李白有点儿黑。

  • 78
    点赞
  • 141
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李白有点儿黑

孩子原创呕心沥血,求打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值