草庐IT

用蓝桥杯单片机实现温度界面与时钟界面转换

安知甜与乐 2024-02-09 原文

1基本功能描述

1)通过DS18B20温度传感器,采集环境温度数据,保留小数点后2位有效数字。

2)读取DS1302时钟芯片的时、分、秒数据。

3)通过数码管显示时间和温度数据,显示界面可以通过按键来回切换。

初始化状态说明

1)关闭蜂鸣器、继电器。

2)数码管处于时间界面。

3)实时时钟的初始化时间是00:00:00

显示界面状态

1)时间界面指示灯L2点亮,其余指示灯熄灭。

2)温度界面指示灯L3点亮,其余指示灯熄灭。

按键功能

1)按键S4定义为“切换”按键,用于切换显示时间和温度界面。

2)按键S5定义为“时”按键,每次按下,时加1。

3)按键S6定义为“分”按键,每次按下,分加1。

4)按键S7定义为“秒”按键,每次按下,秒值清零。

报警条件

  1. 当时间22:00:00,继电器吸合,指示灯L1点亮,   3秒后,继电器自动断开,指示灯L1熄灭。
  2. 当温度高于24度时,开启蜂鸣器发出响声,继电器吸合;温度低于24度时自动关闭蜂鸣器继电器。

代码如下

onewire.c

#include "onewire.h"
#include <STC15F2K60S2.H>

sbit DQ = P1^4; 

//单总线内部延时函数
void Delay_OneWire(unsigned int t)  
{
	t=t*12;
	while(t--);
}

//单总线写操作
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//单总线读操作
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//DS18B20初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}


//
float temperature()
{
int low,hight;
float wundu;
init_ds18b20();
Write_DS18B20(0xcc);//跳过ROM
Write_DS18B20(0x44);//开始温度转换
init_ds18b20();
Write_DS18B20(0xcc);//跳过ROM
Write_DS18B20(0xbe);//读取温度	
low=Read_DS18B20();//接收低8位
hight=Read_DS18B20();//接收高8位
wundu=(hight<<8|low)*0.0625;//转换成10进制
	return wundu ;
}

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H



 

float temperature(); 

#endif

ds1302函数c

#include "ds1302.h"  									
#include <STC15F2K60S2.H>

sbit SCK = P1^7;		
sbit SDA = P2^3;		
sbit RST = P1^3; 

void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK = 0;
		SDA = temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

//向DS1302寄存器写入数据
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	RST=0; 
}

//从DS1302寄存器读出数据
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();
	return (temp);			
}
unsigned char DecToBCD(unsigned char j)//将10进制转换成BCD
{

j=(j/10*16)+(j%10);
return j;

}

void ds1302_sy(unsigned char h,unsigned char min ,unsigned char s)
{
Write_Ds1302_Byte( 0x8e,0x00 );//打开写保护
Write_Ds1302_Byte( 0x80,DecToBCD(s) );
Write_Ds1302_Byte( 0x82,DecToBCD(min));
Write_Ds1302_Byte( 0x84,DecToBCD(h));
Write_Ds1302_Byte( 0x8e, 0x80 );//关闭写保护	
}

h

#ifndef __DS1302_H
#define __DS1302_H


#include <intrins.h>



unsigned char Read_Ds1302_Byte( unsigned char address );
void ds1302_sy(unsigned char h,unsigned char min ,unsigned char s);

#endif

主体函数

#include <STC15F2K60S2.H>
#include "ds1302.h"
#include "onewire.h"

unsigned char BCDToDec(unsigned char i)//BCD转换成10进程值
{

	i=(i/16*10)+(i%16);
	return i;

}

void Device(unsigned char p2,unsigned char p0)//配置锁存器
{
P0=p0;
P2=p2;
P2=0;
}

void system()//初始化
{
Device(0x80,0xff);
Device(0xa0,0);
}
int ms;
void Timer2Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xFB;		//定时器时钟12T模式
	T2L = 0x18;		//设置定时初始值
	T2H = 0xFC;		//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
	EA =1;
	IE2  |= 0x04;
}

//这个为阴极数码管显示表0~9  10 为.  11为—— 12为C
unsigned char smg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x80,0x40,0x39};

void smg_csh(unsigned n,unsigned m)//配置数码管显示
{
	int a;
	a= 0x01<<n;
	Device(0xc0,0);
	Device(0xe0,~smg[m]);//显示内容
	Device(0xc0,a);//显示的位置为n+1
}

char h,min,s;
void ds1302_dq()//读取时间
{
s = BCDToDec(Read_Ds1302_Byte(0x81));
min = BCDToDec(Read_Ds1302_Byte( 0x83 ));
h = BCDToDec(Read_Ds1302_Byte( 0x85));
}

void ds1302_show()//显示时间
{
	smg_csh(0,h/10);
	smg_csh(1,h%10);
	smg_csh(2,11);
	smg_csh(3,min/10);
	smg_csh(4,min%10);
	smg_csh(5,11);
	smg_csh(6,s/10);
	smg_csh(7,s%10);
}
unsigned long du;
void ds18b20()//读取温度
{
 if(ms>=10)
 {
 ms=0;
 du=(unsigned long)(temperature()*10000); //()强制类型转换
 }
		
}
void ds18b20_show()//显示温度
{
	smg_csh(0,12);
	smg_csh(4,du/100000);	
	smg_csh(5,du/10000%10);
	smg_csh(5,10);
	smg_csh(6,du/1000%10);
	smg_csh(7,du/100%10);
}
void Delay()		//@12.000MHz
{
	unsigned char i, j;

	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}

int i=0;

void key()
{//按键按下s=0
if(P30==0){Delay();if(P30==0){s=0;ds1302_sy(h,min,s);while(P32==0){}}}
if(P32==0)//按下S5
{//消抖  判断下一个  按下一次加一  限制范围       存入该数据           让数码管闪说明在调整
Delay();if(P32==0){h++;if(h>23){h=0;}ds1302_sy(h,min,s);while(P32==0){}}//控制小时加
}

if(P31==0)//按下s6
{//消抖  判断下一个  按下一次加一  限制范围       存入该数据           让数码管闪说明在调整
Delay();if(P31==0){min++;if(min>59){min=0;}ds1302_sy(h,min,s);while(P31==0){}}//控制分钟加
	
}
if(P33==0)//变量值改变
{Delay();if(P33==0){i++;i=i%2;while(P33==0){}}}
}

void main()
{
	Timer2Init();
	system();
	ds1302_sy(00,00,00);
while(1)
{
	key();
	ds1302_dq();
	
	if(i==0)//该条件为时间显示条件
	{ 
	ds1302_show();Device(0x80,~0x02);Device(0xa0,0);
//报警的功能
	if((h==22)&&(s==0)&&(min==0))
	{Device(0xa0,0x10);Device(0x80,~0x01);}
	if((h==22)&&(s==3)&&(min==0))
	{Device(0xa0,0);Device(0x80,0xff);}
	}
}
}

void t2() interrupt 12  //中断入口
{
	ms++;
	ds18b20();
	if(i==1)//温度显示的条件
	{
	ds18b20_show();
	Device(0x80,~0x04);
	Device(0xa0,0);
//报警功能
	if(du>240000)
	{Device(0xa0,0x50);}
	if(du<240000)
	{Device(0xa0,0);}
	}
	

}

有什么不足的地方请指教

有关用蓝桥杯单片机实现温度界面与时钟界面转换的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  3. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  4. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  5. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  6. ruby-on-rails - Ruby url 到 html 链接转换 - 2

    我正在使用Rails构建一个简单的聊天应用程序。当用户输入url时,我希望将其输出为html链接(即“url”)。我想知道在Ruby中是否有任何库或众所周知的方法可以做到这一点。如果没有,我有一些不错的正则表达式示例代码可以使用... 最佳答案 查看auto_linkRails提供的辅助方法。这会将所有URL和电子邮件地址变成可点击的链接(htmlanchor标记)。这是文档中的代码示例。auto_link("Gotohttp://www.rubyonrails.organdsayhellotodavid@loudthinking.

  7. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

  8. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  9. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  10. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

随机推荐