蓝桥杯之单片机设计与开发(27)——2014_第五届_蓝桥杯_省赛——“简易温度采集与控制装置”

版权声明:让结局不留遗憾,让过程更加完美。 https://blog.csdn.net/Xiaomo_haa/article/details/88368992

今天在图书馆待一天,昨天写好的程序,今天才发博客。=,=

1、题目

2、代码

下载链接:https://download.csdn.net/download/xiaomo_haa/11010289

main.c

#include <stc15.h>
#include "sys.h"

u8 temper_low = 20, temper_high = 30, mode = 0;
u8 temper_range[] = {3, 0, 2, 0}, temp_backup[] = {16, 16, 16, 16};
int Realtemper = 0;
bit flag_option = 0;
bit flag_right = 1;
bit flag_200ms = 0;

void main(void)
{
	int tem = 0;
	
	AllInit();
	Start18B20();
	Timer0Init();
	EA = 1;
	while(1)
	{
		if(flag_200ms == 1)
		{
			flag_200ms = 0;
			Get18B20Temp(&tem);
			tem >>= 4;
			if((tem >= 0) && (tem <= 75))
				Realtemper = tem;
			Start18B20();
		}
		
		if(flag_option == 0)
		{
			if(Realtemper < temper_low)
				mode = 0;
			else if((Realtemper >= temper_low) && (Realtemper <= temper_high))
				mode = 1;
			else
				mode = 2;
		}
		
		KeyPress();
		TubeShow();
	}
}

sys.c

#include "sys.h"

void AllInit(void)
{
	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 0x00;
	P2 = (P2 & 0x1f) | 0xa0;
	P0 = 0x00;
	P2 = P2 & 0x1f;
}


void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xCD;		//设置定时初值
	TH0 = 0xD4;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
}

void Timer0(void) interrupt 1
{
	static u16 T0count1 = 0;
	static u16 T0count2 = 0;
	u16 time = 0;
	static bit flag_led = 0;
	u8 leddat;
	
	T0count1 ++;
	T0count2 ++;
	
	if(T0count1 >= 400)	//200ms
	{
		T0count1 = 0;
		flag_200ms = 1;
	}
	
	if(mode == 0)
	{
		time = 800;
		P2 = (P2 & 0x1f) | 0xa0;
		P0 = 0x00;
		P2 = P2 & 0x1f;
	}
	else if(mode == 1)
	{
		time = 400;
		P2 = (P2 & 0x1f) | 0xa0;
		P0 = 0x00;
		P2 = P2 & 0x1f;
	}
	else if(mode == 2)
	{
		time = 200;
		P0 = 0x00;
		P2 = (P2 & 0x1f) | 0xa0;
		P0 = 0x10;
		P2 = P2 & 0x1f;
	}
		
	if(T0count2 >= time)
	{
		T0count2 = 0;	
		flag_led = ~flag_led;
		if(flag_led == 1)
			leddat = 0xfe;
		else
			leddat = 0xff;
	}
	
	if(flag_option == 0)
		LEDLight(leddat);
	else if((flag_option = 1) && (flag_right == 1))
		LEDLight(0xff);
	else if((flag_option = 1) && (flag_right == 0))
		LEDLight(0xfd);
	
	TubeScan();
	KeyScan();
}

sys.h

#ifndef _SYS_H_
#define _SYS_H_

typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;

#include <stc15.h>
#include <intrins.h>
#include "ds18b20.h"

extern u8 temper_low, temper_high, mode;
extern u8 temper_range[], temp_backup[];
extern int Realtemper;
extern bit flag_option;
extern bit flag_right;
extern bit flag_200ms;

//function
void AllInit(void);
void Timer0Init(void);

void TubeScan(void);
void TubeShow(void);
void LEDLight(unsigned char dat);

void KeyScan(void);
void KeyAction(u8 keycode);
void KeyPress(void);

//pin
sbit relay = P0^5;

#endif


display.c

#include "sys.h"

unsigned char code table[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 
                            0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,
														0xff, 0xbf};
u8 TubeBuff[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
u8 smg1, smg2, smg3, smg4, smg5, smg6, smg7, smg8;

void TubeScan(void)
{
	static u8 index = 0;
	
	P2 = (P2 & 0x1f) | 0xe0;
	P0 = 0xff;
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = (0x01 << index);
	P2 = (P2 & 0x1f) | 0xe0;
	P0 = TubeBuff[index];
	P2 = P2 & 0x1f;
	
	index ++;
	index &= 0x07;
}

void TubeShow(void)
{
	if(flag_option)
	{
		smg1 = smg6 = 17;	   //-
		smg4 = smg5 = 16;    //熄灭
		smg2 = temper_range[0];
		smg3 = temper_range[1];
		smg7 = temper_range[2];
		smg8 = temper_range[3];
	}
	else if(flag_option == 0)
	{
		smg1 = smg3 = 17;					//-
		smg4 = smg5 = smg6 = 16;	//熄灭
		smg2 = mode;
		smg7 = Realtemper / 10;
		smg8 = Realtemper % 10;
	}
	
	TubeBuff[0] = table[smg1];
	TubeBuff[1] = table[smg2];
	TubeBuff[2] = table[smg3];
	TubeBuff[3] = table[smg4];
	TubeBuff[4] = table[smg5];
	TubeBuff[5] = table[smg6];
	TubeBuff[6] = table[smg7];
	TubeBuff[7] = table[smg8];
}

void LEDLight(unsigned char dat)
{
	P0 = 0xff;
	P2 = (P2 & 0x1f) | 0x80;
	P0 = dat;
	P2 = P2 & 0x1f;
}

key.c

#include "sys.h"

sbit Output0 = P4^4;
sbit Output1 = P4^2;
sbit Output2 = P3^5;
sbit Output3 = P3^4;
sbit Input0 = P3^0;
sbit Input1 = P3^1;
sbit Input2 = P3^2;
sbit Input3 = P3^3;

u8 code KeyMap[4][4] = {{0, 1, 2, 19},
												{3, 4, 5, 18}, 
												{6, 7, 8, 17}, 
												{9, 0x88, 0x99, 16}};
u8 KeyBuff[4][4] = {{0xff, 0xff, 0xff, 0xff}, {0xff, 0xff, 0xff, 0xff},
									{0xff, 0xff, 0xff, 0xff}, {0xff, 0xff, 0xff, 0xff}};
u8 KeySta[4][4] = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};
u8 KeyBackup[4][4] = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};
	

void KeyScan(void)
{
	static u8 index = 0;
	u8 i, j;
	
	KeyBuff[0][index] = (KeyBuff[0][index] << 1) | Input0;	//第一行
	KeyBuff[1][index] = (KeyBuff[1][index] << 1) | Input1;	//第二行
	KeyBuff[2][index] = (KeyBuff[2][index] << 1) | Input2;	//第三行
	KeyBuff[3][index] = (KeyBuff[3][index] << 1) | Input3;	//第四行
	
	index ++;
	index &= 0x03;
	switch(index)
	{
		case 0: Output3 = 1; Output0 = 0; break;
		case 1: Output0 = 1; Output1 = 0; break;
		case 2: Output1 = 1; Output2 = 0; break;
		case 3: Output2 = 1; Output3 = 0; break;
	}
	
	for(i = 0; i < 4; i++)
	{
		for(j = 0; j < 4; j++)
		{
			if(KeyBuff[i][j] == 0x00)				//按键按下
				KeySta[i][j] = 0;
			else if(KeyBuff[i][j] == 0xff)	//按键松开
				KeySta[i][j] = 1;
			else		//按键抖动
			{}
		}
	}
}

void KeyAction(u8 keycode)
{
	static u8 length = 0;
	
	if((keycode >= 0) && (keycode <= 9) && (length < 4) && (flag_option == 1))
	{
		temper_range[length] = keycode;
		
		length ++;
		if(length >= 4)
		{
			length = 4;
			temper_low  = temper_range[3] + temper_range[2] * 10;
			temper_high = temper_range[1] + temper_range[0] * 10;
			
			if(temper_low > temper_high)		//检测到错误
				flag_right = 0;
		}
	}
	else if((keycode == 0x88) && ((length == 0) || (length == 4)) && (temper_low <= temper_high))
	{		
		flag_right = 1;
		if(flag_option == 0)
		{
			flag_option = 1;
			temp_backup[0] = temper_range[0];
			temp_backup[1] = temper_range[1];
			temp_backup[2] = temper_range[2];
			temp_backup[3] = temper_range[3];
			temper_range[0] = 16;
			temper_range[1] = 16;
			temper_range[2] = 16;
			temper_range[3] = 16;
			
			length = 0;
		}
		else if(flag_option == 1)
		{
			flag_option = 0;
			temp_backup[0] = temper_range[0];
			temp_backup[1] = temper_range[1];
			temp_backup[2] = temper_range[2];
			temp_backup[3] = temper_range[3];
		}
	}
	else if((keycode == 0x99) && (flag_option == 1))		//清除键
	{
		length = 0;
		temper_range[0] = 16;
		temper_range[1] = 16;
		temper_range[2] = 16;
		temper_range[3] = 16;
	}
}


void KeyPress(void)
{
	u8 i, j;
	
	for(i = 0; i < 4; i ++)
	{
		for(j = 0; j < 4; j ++)
		{
			if(KeyBackup[i][j] != KeySta[i][j])
			{
				if(KeySta[i][j] == 0)
					KeyAction(KeyMap[i][j]);
				KeyBackup[i][j] = KeySta[i][j];
			}
		}
	}
}

ds18b20.c

 #include "sys.h"

sbit DS18B20_IO = P1^4;

void Delayus(unsigned int us)
{
	do{
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
	}while(--us);
}

bit Get18B20Ack(void)
{
	bit ack;
	
	DS18B20_IO = 0;			//产生500us的复位脉冲
	Delayus(500);
	EA = 0;						//禁止定时器0中断
	DS18B20_IO = 1;			//延时60us
	Delayus(60);
	EA = 1;							//重新使能总中断
	ack = DS18B20_IO;		//读取存在脉冲
	while(!DS18B20_IO);	//等待存在脉冲结束
	
	return ack; 	
}

void DS18B20Write(unsigned char dat)
{
 	unsigned char mask;
						
	for(mask = 0x01; mask != 0; mask <<= 1)	//低位在先,依次移出8个bit
	{
		EA = 0;
		DS18B20_IO = 0;				//产生2us低电平脉冲
		Delayus(2);
	 	if(dat & mask)				//输出该bit值
		 	DS18B20_IO = 1;
		else
		 	DS18B20_IO = 0;
		Delayus(60);					//延时60us
		DS18B20_IO = 1;				//拉高通信引脚
		EA = 1;
	}
}

unsigned char DS18B20Read(void)
{
 	unsigned char mask, dat = 0;
	
	for(mask = 0x01; mask != 0; mask <<= 1)	//低位在先,依次采集8个bit
	{
		EA = 0;
		DS18B20_IO = 0;				//产生2us低电平脉冲
		Delayus(2);
		DS18B20_IO = 1;				//结束低电平脉冲,等待18B20输出数据
		Delayus(2);						//延时2us
	 	if(DS18B20_IO)				//读取通信引脚上的值
		 	dat |= mask;
		Delayus(60);					//再延时60us
		EA = 1;
	}
	
	return dat;	
}

bit Start18B20()
{
 	bit ack;
	static bit flag = 1;

	ack = Get18B20Ack();		//执行总线复位,并获取18B20应答
	if(ack == 0)						//如18B20正确应答,则启动一次转换
	{
		DS18B20Write(0xCC);		//跳过ROM操作
		
		if(flag)
		{
			flag = 0;
			DS18B20Write(0x4e);			//写暂存器指令4E
			DS18B20Write(0x4b);			//写高速缓存器TH高温限值75度
			DS18B20Write(0x00);			//写高速缓存器TL低温限值0度
			DS18B20Write(0x1f);			//写配置寄存器4
															//0x1f : 0.5000°C  转换时间93.75ms
															//0x3f : 0.2000°C  转换时间187.5ms
															//0x5f : 0.1250°C  转换时间375ms
															//0x7f : 0.0625°C  转换时间750ms
		}
		
		ack = Get18B20Ack();		//执行总线复位,并获取18B20应答
		if(ack == 0)						//如18B20正确应答,则启动一次转换
		{
			DS18B20Write(0xCC);		//跳过ROM操作
			DS18B20Write(0x44);		//启动一次温度转换
		}
	}

	return ~ack;						//ack == 0 表示操作成功,所以返回值对其取反
}

bit Get18B20Temp(int *temp)
{
 	bit ack;
	unsigned char LSB, MSB;			//16bit温度值的低字节和高字节

	ack = Get18B20Ack();				//执行总线复位,并获取18B20应答
	if(ack == 0)								//如18B20正确应答,则读取温度值
	{
	 	DS18B20Write(0xCC);				//跳过ROM操作
		DS18B20Write(0xBE);				//发送读命令
		LSB = DS18B20Read();			//读温度值的低字节
		MSB = DS18B20Read();			//读温度值的高字节
		*temp = ( MSB << 8) + LSB;	//合成16bit的整数
	}

	return ~ack;								//ack == 0 表示操作应答,所以返回值为1其取反值
} 

ds18b20.h

#ifndef __DS18B20_H
#define __DS18B20_H


//单总线延时函数
void Delayus(unsigned int us);
bit Get18B20Ack(void);
void DS18B20Write(unsigned char dat);
unsigned char DS18B20Read(void);
bit Start18B20();
bit Get18B20Temp(int *temp);


#endif

猜你喜欢

转载自blog.csdn.net/Xiaomo_haa/article/details/88368992
今日推荐