第十一届省赛程序设计题--温度测试【蓝桥杯真题—06】

该代码实现了一个基于STM32的温度监测系统,使用DS18B20传感器读取温度,并通过数码管显示。系统还包括参数设置功能,允许用户设置温度上下限,并通过PCA8591进行模拟电压输出控制LED灯状态。同时,系统具备定时器和按键扫描功能,支持数码管闪烁和温度更新。
摘要由CSDN通过智能技术生成

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现代码

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

sbit s7=P3^0;
sbit s6=P3^1;
sbit s5=P3^2;
sbit s4=P3^3;
				   

//unsigned char SMGNoDot_CA[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //无小数点
//unsigned char SMGDot_CA[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

unsigned int count=0; //定时器计数

unsigned char temp_k=1; //温度读取开关
unsigned int temp=0;
unsigned int temp_max=30;
unsigned int temp_min=20;
unsigned char temp_flag=0; //0表示设置temp_max   1表示设置temp_min

unsigned char smg_f=1;  //数码管闪烁标志位	选中了1S闪烁

unsigned char smg_stat=0;  //0为数据显示页面  1为参数设置页面


void delay(int t)
{
	while(t--);
}
void delay_ms(int n)
{
	int i,j;
	for(i=n;i>0;i--)
		for(j=110;j>0;j--);
}

/**=====================================================================
温度读取函数
======================================================================*/
void read_temp()
{
	unsigned char LSB;
	unsigned char MSB;
	init_ds18b20();	
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);

	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);

	LSB=Read_DS18B20();
	MSB=Read_DS18B20();

	temp=(MSB<<8)|LSB;
	if((temp&0xf800)==0x0000)
	{
		temp = temp>>4;
	}
}

void read_temp_k()
{
	if(temp_k==1)
	{
		read_temp();
	}
}
/**=====================================================================
DAC模拟电压	  输出电压=dac/255.0*0.4
======================================================================*/
void PCF8591_DAC(unsigned char dat)
{
	IIC_Start(); 
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck(); 
	IIC_SendByte(dat);
	IIC_WaitAck(); 
	IIC_Stop();	  
}

/**=====================================================================
数码管显示函数
======================================================================*/
void selecthc(unsigned char choose)
{
	switch(choose)
	{
		case 4 : P2=(P2&0x1f)|0x8f; break;
		case 5 : P2=(P2&0x1f)|0xaf; break;
		case 6 : P2=(P2&0x1f)|0xcf; break;
		case 7 : P2=(P2&0x1f)|0xef; break;
		case 0 : P2=(P2&0x1f)|0x00; break;
	}
}
void show_bit(unsigned char w,unsigned char n)
{
	selecthc(7);
	P0=0x00;
	selecthc(6);
	P0=0x01<<w-1;
	selecthc(7);
	P0=n;
}
void show_all(unsigned char n)
{

	selecthc(6);
	P0=0xff;
	selecthc(7);
	P0=n;	
}
//数码管显示温度
void show_temp()
{
	show_bit(1,0xc6);
	delay(500);
	show_bit(7,table[temp/10]);
	delay(500);
	show_bit(8,table[temp%10]);
	delay(500);
	show_all(0xff);
}
//数码管显示参数设置
void show_num()
{
	show_bit(1,0x8c);
	delay(500);
	if(((temp_flag==0&smg_f==1))|(temp_flag==1))
	{
		show_bit(4,table[temp_max/10]);
		delay(500);
		show_bit(5,table[temp_max%10]);
		delay(500);		
	}
	delay_ms(1);
	if(((temp_flag==1&smg_f==1))|(temp_flag==0))
	{
		show_bit(7,table[temp_min/10]);
		delay(500);
		show_bit(8,table[temp_min%10]);
		delay(500);			
	}
	show_all(0xff);
}

void showsmg()
{
	if(smg_stat==0)
	{
		show_temp();	
	}else if(smg_stat==1)
	{
		show_num();
	}
}

/**=====================================================================
LED灯显示函数	温度控制DAC输出函数
======================================================================*/
void led_runing_DAC()
{
	selecthc(4);
	if(temp>temp_max)
	{
		PCF8591_DAC(204);	//输出4V=DAC/255*5
		P0=0xfe; //L1点亮
	}
	else if(temp<=temp_max&&temp>=temp_min)
	{
		PCF8591_DAC(153); 	//输出3V=DAC/255*5
		P0=0xfd; //L2点亮
	}
	else if(temp<temp_min)
	{
		PCF8591_DAC(153);	//输出2V=DAC/255*5
		P0=0xfb;
	}
	else P0=0xf7;
	selecthc(0);	
}

/**=====================================================================
定时器相关函数	 定时器0 16位定时器	  定时1000us=1ms
======================================================================*/
void init()
{
	TMOD=0x01; 	
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;

	TR0=1;
	ET0=1;
	EA=1;
}
void service() interrupt 1
{
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	
	count++;
	//if(count>=500) //0.5秒刷新一次温度读取
	//{
	//	temp_k=~temp_k;
	//}
	if(count>=1000)
	{
		smg_f=~smg_f;
		count=0;
	}		
}

/**=====================================================================
开关扫描函数
======================================================================*/
void keys()
{
	if(s4==0)
	{
		delay_ms(1);
		if(s4==0)
		{
			while(s4==0)
			{
				showsmg();
				led_runing_DAC();
			}
			if(smg_stat==0)
			{  
				temp_flag=1;
				showsmg();
				smg_stat=1;
			}else if(smg_stat==1)
			{  
				showsmg();
				smg_stat=0;
			}
		}
	}
	if(smg_stat==1)
	{
		if(s5==0)
		{
			delay_ms(1);
			if(s5==0)
			{
				while(s5==0)
				{
					showsmg();
					led_runing_DAC();
				}
				temp_flag++; //flag_s7默认0,0为正常显示时钟
				if (temp_flag >=2)
				{
					temp_flag = 0;
				}
			}
		}
	}
	if(s6==0) //加
	{
		delay_ms(1);
		if(s6==0)
		{
			while(s6==0)
			{
				showsmg();
				led_runing_DAC();
			}
			if(temp_flag==0)
			{
				temp_max++;
				if(temp_max>=99)
				{
					temp_max=0;
				}
			}
			else if(temp_flag==1)
			{
			
				if(temp_min<temp_max-1)
				{
					temp_min++;
				}
			}
		}

	}
	if(s7==0)  //减
	{
		delay_ms(1);
		if(s7==0)
		{
			while(s7==0)
			{
				showsmg();
				led_runing_DAC();
			}
			if(temp_flag==0)
			{
				if(temp_max>temp_min+1)
				{
					temp_max--;
				}
			}
			else if(temp_flag==1)
			{
				if(temp_min>=0)
				{
					temp_min--;
				}
			}
		}
	}
}

																			 
void main()
{
	selecthc(5);
	P0=0x00;
	selecthc(0);
	init();
	while(1)
	{
		keys();
		read_temp();
		led_runing_DAC();
		showsmg();	
	}
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

root@z~

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值