蓝桥杯单片机刷题——采集温度控制指示灯状态

设计要求

从DS18B20温度传感器上获取环境温度,并将其温度值显示到数码管上。

按键“S16”定义为“温度参数”按键,按下按键S16按键可将当前温度设置为温度参数。

当温度超过温度参数时,LED1指示灯亮,否则LED1指示灯熄灭;

数码管显示格式如下图所示:

温度为26.2°C(数码管最低位显示固定字符C)

备注:

单片机IRC振荡器频率设置为12MHz。

按键模式:KBD;扩展方式:IO模式。

显示的温度值保留小数点后一位有效数字。

个人代码

#include <STC15F2K60S2.H>
#include "intrins.h"
sbit DQ=P1^4;
code unsigned char Seg_Table[] = {
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xc6, //C  10
0xff //熄灭  11
};
unsigned char Seg_Buff[]={11,11,11,11,2,6,2,10};
float tempermax=26.2,temper;
unsigned char flag_seg=0,flag_key=0,flag_temper=0,flag_tempermax=0;
unsigned char keyval,keyold,keydown,keyup;
void init74hc138(unsigned char n){
	P2=(P2&0x1f)|(n<<5);
	P2&=0x1f;
}
void init(){
	P0=0xff;
	init74hc138(4);
	P0=00;
	init74hc138(5);
}
void Delay_OneWire(unsigned int t)  
{
	unsigned char i;
	while(t--){
		for(i=0;i<12;i++);
	}
}
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;
}
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;
}
void r_ds18b20_temper(){
	unsigned char th,tl;
	EA=0;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	tl=Read_DS18B20();
	th=Read_DS18B20();
	temper=(th<<8|tl)*0.0625;
	EA=1;
}	

void Key_Loop(){
	P34=0;
	keyval=0;
	if(P33==0)keyval=1;
	keydown=keyval&(keyold^keyval);
	keyup=~keyval&(keyold^keyval);
	if(keyval&&keyold!=keyval)flag_tempermax=1;
	keyold=keyval;
}
void seg(unsigned char addr,num){
	P0=0xff;
	init74hc138(7);
	P0=0x01<<addr;
	init74hc138(6);
	P0=Seg_Table[num];
	if(addr==5)P0&=0x7f;
	init74hc138(7);
}
void Seg_Loop(){
	static unsigned char i=0;
	seg(i,Seg_Buff[i]);
	i++;
	if(i==8)i=0;
}
void seg_temper(){
	Seg_Buff[6]=(int)(temper*10)%10;
	Seg_Buff[5]=(int)temper%10;
	Seg_Buff[4]=(int)temper/10;
}
void Timer0_Init(void)		//100微秒@12.000MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x50;				//设置定时初始值
	TH0 = 0xFB;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA = 1;
}
void main(){
	init();
	Timer0_Init();
	while(1){
		if((int)(temper*10)>(int)(tempermax*10)){
			P0=0xfe;
			init74hc138(4);
		}else{
			P0=0xff;
			init74hc138(4);
		}
		if(flag_tempermax){
			flag_tempermax=0;
			tempermax=temper;
		}
		if(flag_seg){
			flag_seg=0;
			Seg_Loop();
		}
		if(flag_key){
			flag_key=0;
			Key_Loop();
		}
		if(flag_temper){
			flag_temper=0;
			r_ds18b20_temper();
			seg_temper();
		}
	}
}
void Timer0_Isr(void) interrupt 1
{
	static unsigned char count1=0,count2=0;
	static unsigned int count3=0;
	count1++;count2++;count3++;
	if(count1==2){
		count1=0;
		flag_seg=1;
	}
	if(count2==20){
		count2=0;
		flag_key=1;
	}
	if(count3==1000){
		count3=0;
		flag_temper=1;
	}
}

测试结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值