第五届蓝桥杯单片机组 简易温度采集与控制系统(省赛)

   日期:2021-03-07     浏览:105    评论:0    
核心提示:(萌新一枚。连肝4个小时,在这里分享给大家。)这一届的题目总体来说,难度不大。但第一次也是唯一一次考到了矩阵键盘,足以引起我们的注意。我在写代码的过程,主要遇到的障碍就是矩阵键盘的使用过于粗糙。希望矩阵键盘没有怎么练习过的,只会运用最基础的操作的小伙伴能进一步加强这一块的学习,防止比赛暴雷。。。。如果你发现了程序需要优化的地方,请一定要告诉我!#题目:#onewire.c/* 程序设计:单总线驱动程序 软件环境:Keil uVision 4.10 硬件环境:CT107单片机综

(萌新一枚。连肝4个小时,在这里分享给大家。)
这一届的题目总体来说,难度不大。但第一次也是唯一一次考到了矩阵键盘,足以引起我们的注意。我在写代码的过程,主要遇到的障碍就是矩阵键盘的使用过于粗糙。希望矩阵键盘没有怎么练习过的,只会运用最基础的操作的小伙伴能进一步加强这一块的学习,防止比赛暴雷。。。。
如果你发现了程序需要优化的地方,请一定要告诉我!

onewire.c


#include "reg52.h"
#include "onewire.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{ 
	t *= 10;//时间扩大十倍
	while(t--);
}

//通过单总线xiangDS18B20写一个字节
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);
}

//从DS18B20读取一个字节
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;
}

uchar read_temperatuer(void)
{ 
	uchar LSB, MSB;
	uchar temp;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	Delay_OneWire(100);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	init_ds18b20();
	
	temp = (MSB << 8)|LSB;
	temp >>= 4;//右移4位,只取整数部分
	
	return temp;
}

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H
#define uchar unsigned char
#define uint unsigned int
	
extern uchar read_temperatuer(void);
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);

#endif

main.c

#include <REGX52.H>
#include <onewire.h>

sfr P4 = 0xc0;

sbit P42 = P4^2;
sbit P44 = P4^4;

sbit L1 = P0^0;
sbit L2 = P0^1;

void Delay(uint t);
void Init_hc573(uint s);
void key_scan(void);
void inputdat(uint key);//输入数据
void save_t(void);//保存输入的数据
void Init_Timer0(void);
void DisplaySMG_Dat(uint pos, uint dat);
void DisplaySMG_all(void);//清空所有数码管
void DisplaySMG(void);

uint code Shu[] = 
{ 0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,0x80,0x90,//0-9 
0xbf, 0xff};//-和灭

uint yi=11,er=11,san=11,si=11, wu=11, liu=11, qi=11, ba=11;
uint temperature;//温度
uint set;//控制显示界面标志位
uint set_t1, set_t2, set_t3, set_t4;//设置温度的临时数据
uint Tmax = 30, Tmin = 20;
uint level;//温度等级
uint sel;//选择要修改的数据
uint flag;//计算设置按键按下的次数
uint clear;//清空数据标志位
uint count_0;//定时器时间控制
uint count_1;
uint count_2;

void main(){ 
	Init_hc573(4);
	P0 = 0xff;
	Init_hc573(5);
	P0 = 0x00;
	Init_Timer0();
	while(1){ 
		key_scan();
		if(temperature < Tmin){ 
			level = 0;
			Init_hc573(5);
			P0 = 0x00;
		}
		else if((temperature >= Tmin)&&(temperature <= Tmax)){ 
			level = 1;
			Init_hc573(5);
			P0 = 0x00;
		}
		else
		{ 
			level = 2;
			Init_hc573(5);
			P0 = 0x10;
		}
		
		if(set== 0){ 
			EA = 1;
			ET0 = 1;
			temperature =  read_temperatuer();
			
			yi = 10;er = level;san = 10;
			si = 11;wu = 11;liu = 11;
			qi = temperature/10;ba = temperature%10;
		}
		else{ 
			//关闭定时器并清空数据
			EA = 0;
			ET0 = 0;
			count_0 = 0;
			count_1 = 0;
			count_2 = 0;
			yi = 10;er = set_t1;san = set_t2;
			si = 11;wu = 11;liu = 10;
			qi = set_t3;ba = set_t4;
		}
		
		DisplaySMG();
	}
}

void Delay(uint t){ 
	while(t --);
}

void Init_hc573(uint s){ 
	switch(s){ 
		case 4:P2 = (P2 &0x1f)|0x80;break;//LED
		case 5:P2 = (P2 &0x1f)|0xa0;break;//蜂鸣器和继电器
		case 6:P2 = (P2 &0x1f)|0xc0;break;//数码管com端口
		case 7:P2 = (P2 &0x1f)|0xe0;break;//段码
	}
}
static uint key;
void key_scan(void){ 
	
	uint temp;
	P3 = 0x7f;P42 = 1;P44 = 0;//扫描第一列
	temp = P3;
	temp &= 0x0f;//判断第四位是否发生变化 0111 1111&0000 1111 = 0000 1111
	if(temp != 0x0f){ 
		Delay(200);
		if(temp != 0x0f){ 
			temp = P3;
			switch(temp)//便于直接控制到每个按键
			{ 
				case 0x7e:if(set == 1){ sel ++;key = 0;inputdat();}break;
				case 0x7d:if(set == 1){ sel ++;key = 3;inputdat();}break;
				case 0x7b:if(set == 1){ sel ++;key = 6;inputdat();}break;
				case 0x77:if(set == 1){ sel ++;key = 9;inputdat();}break;
			}
			while(temp != 0x0f){ //重新判断,否则temp永远不能等于0x0f
				temp = P3;
				temp &= 0x0f;//若松开,则temp = 0x0f;
			}
		}
	}
	
	P3 = 0xbf;P42 = 0;P44 = 1;//判断第二列
	temp = P3;
	temp &= 0x0f;//判断第四位是否发生变化
	if(temp != 0x0f){ 
		Delay(200);
		if(temp != 0x0f){ 
			temp = P3;
			switch(temp)
			{ 
				case 0xbe:if(set == 1){ sel ++;key = 1;inputdat();}break;
				case 0xbd:if(set == 1){ sel ++;key = 4;inputdat();}break;
				case 0xbb:if(set == 1){ sel ++;key = 7;inputdat();}break;
				case 0xb7:set = 1;flag ++;if(flag == 2){ save_t();}break;
			}
			while(temp != 0x0f){ 
				temp = P3;
				temp &= 0x0f;
			}
		}
	}
	
	P3 = 0xdf;P42 = 1;P44 = 1;//扫描第三列
	temp = P3;
	temp &= 0x0f;
	if(temp != 0x0f){ 
		Delay(200);
		if(temp != 0x0f){ 
			temp = P3;
			switch(temp)
			{ 
				case 0xde:if(set == 1){ sel ++;key = 2;inputdat();}break;
				case 0xdd:if(set == 1){ sel ++;key = 5;inputdat();}break;
				case 0xdb:if(set == 1){ sel ++;key = 8;inputdat();}break;
				case 0xd7:if(set == 1){ sel ++;clear = 1;inputdat();}break;
			}
			while(temp != 0x0f){ 
				temp = P3;
				temp &= 0x0f;
			}
		}
	}
}

void inputdat(void){ 
	if(clear == 0){ 
		switch(sel){ 
			case 1:set_t1 = key;break;
			case 2:set_t2 = key;break;
			case 3:set_t3 = key;break;
			case 4:set_t4 = key;break;
		}
	}
	else{ //清空数据
		set_t1 = 0;
		set_t2 = 0;
		set_t3 = 0;
		set_t4 = 0;
		sel = 0;//重新输入
		clear = 0;
	}
}
void save_t(void){ 
	if((set_t1*10+ set_t2) > (set_t3*10+ set_t4)){ 
		Tmin = set_t3*10+ set_t4;
		Tmax = set_t1*10+ set_t2;
		sel = 0;
		set = 0;
		
		Init_hc573(4);
		L2 = 1;
	}
	else{ //输入错误,重新输入
		set_t1 = 0;
		set_t2 = 0;
		set_t3 = 0;
		set_t4 = 0;
		sel = 0;
		set = 1;
		
		Init_hc573(4);
		L2 = 0;
	}
	flag = 0;//清空设置按键标志位
}


void Init_Timer0(void){ //@12MHz
	TMOD = 0x01;
	TH0 = (65535 -20000)/256;
	TL0 = (65535- 20000)%256;
	
// EA = 1;
// ET0 = 1;
	TR0 = 1;
}

void service_Timer0(void) interrupt 1{ 
	TH0 = (65535 -20000)/256;
	TL0 = (65535- 20000)%256;
	
	count_0 ++;
	count_1 ++;
	count_2 ++;
	if(count_0 == 4){ 
		count_0 = 0;
		if(level == 0){ 
			if(L1 == 0){ 
				Init_hc573(4);
				P0 = 0xff;//避免其他LED闪烁
				L1 = 1;
			}
			else
			{ 
				Init_hc573(4);
				P0 = 0xff;
				L1 = 0;
			}
		}
	}
	if(count_1 == 2){ 
		count_1 = 0;
		if(level == 1){ 
			if(L1 == 0){ 
				Init_hc573(4);
				P0 = 0xff;
				L1 = 1;
			}
			else{ 
				Init_hc573(4);
				P0 = 0xff;
				L1 = 0;
			}
		}
	}
	if(count_2 == 1){ 
		count_2 = 0;
		if(level == 2){ 
			if(L1 == 0){ 
				Init_hc573(4);
				P0 = 0xff;
				L1 = 1;
			}
			else{ 
				Init_hc573(4);
				P0 = 0xff;
				L1 = 0;
			}
		}
	}
}

void DisplaySMG_Dat(uint pos, uint dat){ 
	Init_hc573(6);
	P0 = 0x01 << pos;
	Init_hc573(7);
	P0 = dat;
	
	Delay(50);
	P0 = 0xff;
}

void DisplaySMG_all(void){ 
	Init_hc573(6);
	P0 = 0xff;
	Init_hc573(7);
	P0 = 0xff;
}

void DisplaySMG(void){ 
	DisplaySMG_Dat(0, Shu[yi]);
	Delay(100);
	DisplaySMG_Dat(1, Shu[er]);
	Delay(100);
	DisplaySMG_Dat(2, Shu[san]);
	Delay(100);
	DisplaySMG_Dat(3, Shu[si]);
	Delay(100);
	DisplaySMG_Dat(4, Shu[wu]);
	Delay(100);
	DisplaySMG_Dat(5, Shu[liu]);
	Delay(100);
	DisplaySMG_Dat(6, Shu[qi]);
	Delay(100);
	DisplaySMG_Dat(7, Shu[ba]);
	Delay(100);
	
	DisplaySMG_all();
}

end

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服