当前位置:网站首页>基于STM32F407的一个温度传感器报警系统(用的是DS18B20温度传感器,4针0.96寸OLED显示屏,并且附带日期显示)
基于STM32F407的一个温度传感器报警系统(用的是DS18B20温度传感器,4针0.96寸OLED显示屏,并且附带日期显示)
2022-08-05 05:15:00 【李白有点儿黑】
基于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.你只有看懂了,才能拿来用,所以最好不要放过任何一个疑问,说不定这个疑问就是解决问题的关键。
最后的最后,支持还是要支持一下的,请求各路英雄豪杰多多打赏,多多关注,多多点赞,我是只发布高质量文章的李白有点儿黑。
边栏推荐
- Flink HA安装配置实战
- 《基于机器视觉的输电线路交叉点在线测量方法及技术方案》论文笔记
- The University of Göttingen proposed CLIPSeg, a model that can perform three segmentation tasks at the same time
- el-table,el-table-column,selection,获取多选选中的数据
- 【NFT开发】设计师无技术基础保姆级开发NFT教程在Opensea上全套开发一个NFT项目+构建Web3网站
- 通过Flink-Sql将Kafka数据写入HDFS
- 【数据库和SQL学习笔记】4.SELECT查询2:排序(ORDER BY)、聚合函数、分组查询(GROUP BY)
- [Go through 8] Fully Connected Neural Network Video Notes
- RecycleView和ViewPager2
- [Skill] Long-term update
猜你喜欢
原来何恺明提出的MAE还是一种数据增强
ECCV2022 | RU&谷歌提出用CLIP进行zero-shot目标检测!
【Pytorch学习笔记】8.训练类别不均衡数据时,如何使用WeightedRandomSampler(权重采样器)
【MySQL】数据库多表链接的查询方式
【论文阅读-表情捕捉】High-quality Real Time Facial Capture Based on Single Camera
flink实例开发-batch批处理实例
读论文 - Unpaired Portrait Drawing Generation via Asymmetric Cycle Mapping
怎么更改el-table-column的边框线
MSRA proposes extreme masking model ExtreMA for learning instances and distributed visual representations
【数据库和SQL学习笔记】9.(T-SQL语言)定义变量、高级查询、流程控制(条件、循环等)
随机推荐
[Skill] Long-term update
【Multisim仿真】直流稳压电源设计报告
单变量线性回归
【论文阅读-表情捕捉】ExpNet: Landmark-Free, Deep, 3D Facial Expressions
【Kaggle项目实战记录】一个图片分类项目的步骤和思路分享——以树叶分类为例(用Pytorch)
[Over 17] Pytorch rewrites keras
对数据排序
大型Web网站高并发架构方案
ECCV2022 | RU & Google propose zero-shot object detection with CLIP!
【数据库和SQL学习笔记】5.SELECT查询3:多表查询、连接查询
MSRA proposes extreme masking model ExtreMA for learning instances and distributed visual representations
Comparison and summary of Tensorflow2 and Pytorch in terms of basic operations of tensor Tensor
如何编写一个优雅的Shell脚本(二)
初识机器学习
6k+ star,面向小白的深度学习代码库!一行代码实现所有Attention机制!
Oracle压缩表修改字段的处理方法
学习总结week3_3迭代器_模块
[Go through 11] Random Forest and Feature Engineering
华科提出首个用于伪装实例分割的一阶段框架OSFormer
SSL 证书签发详细攻略