蓝桥杯之单片机设计与开发(26)——2015_第六届_蓝桥杯_省赛——“温度记录器”

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

1、题目

这个题目还是很简单的,一般在DS1302和DS18B20的驱动写好情况下,两个小时就可以写好。

就用到了DS1302显示实时时间,四个独立按键功能很简单,注意模式切换就可以了,数码管显示也是模式切换就行了。

2、代码

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

main.c

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

bit flag_start = 0;
bit flag_50ms = 0;
bit flag_temper = 0;
bit flag_led = 0;
u8 mode = 1, Temper_time = 1;
u8 temperno = 0;
int Realtemper[11];
u8 Realtime[] = {0x19, 0x03, 0x07, 0x23, 0x59, 0x50, 0x04};


void main(void)
{
	u8 index = 0, t = 1, leddat = 0xff;
	int temp = 0;
	
	AllInit();
	Start18B20();
	EA = 0;
	Timer0Init();
	InitDS1302(&Realtime);
	EA = 1;
	while(1)
	{
		KeyPress();
		
		if(flag_50ms)
		{
			flag_50ms = 0;
			GetRealTime(&Realtime);		//读取1302时间
			if(flag_led)
			{
				leddat = 0xfe | t;
				t = ~t;
			}
            else
                leddat = 0xff;
		}
		
		if(flag_temper == 1)
		{
			flag_temper = 0;
			Get18B20Temp(&temp);
			temp >>= 4;
			Realtemper[index] = temp;
			index ++;
			Start18B20();
			if(index >= 10)
			{
				mode = 3;						//自动切换到温度显示界面
				flag_start = 0;			//停止采集温度
				flag_led = 1;		//显示温度
			}
		}
		
		if(flag_start == 0)
			index = 0;

        LEDLight(leddat);
	}
}

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)		//2毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x9A;		//设置定时初值
	TH0 = 0xA9;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
}

void Timer0(void) interrupt 1
{
	static u8 T0count1 = 0;
	static u16 T0count2 = 0;
	u16 time_temp = 0;
	
	T0count1 ++;
	T0count2 ++;
	time_temp = Temper_time * 500;
	
	if(T0count1 >= 25)
	{
		T0count1 = 0;
		flag_50ms = 1;
	}
	
	if(flag_start)
	{
		if(T0count2 >= time_temp)
		{
			T0count2 = 0;
			flag_temper = 1;
		}
	}
	else
	{
		T0count2 = 0;
		flag_temper = 0;
	}

	KeyScan();
	TubeShow();
	TubeScan();
}

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"
#include "ds1302.h"

extern bit flag_start;
extern bit flag_50ms;
extern bit flag_temper;
extern bit flag_led;
extern u8 mode, Temper_time;
extern u8 temperno;
extern int Realtemper[11];
extern u8 Realtime[];

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

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

void KeyScan(void);
void KeyAction(unsigned char key);
void KeyPress(void);

//pin
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;

#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(mode == 1)						//设置时间间隔界面
	{
		smg1 = smg2 = smg3 = smg4 = smg5 = 16;
		smg6 = 17;
		smg7 = Temper_time / 10;
		smg8 = Temper_time % 10;
	}
	else if(mode == 2)			//采集温度时显示温度
	{
		smg1 = BCDToNum(Realtime[3]) / 10;
		smg2 = BCDToNum(Realtime[3]) % 10;
		smg4 = BCDToNum(Realtime[4]) / 10;
		smg5 = BCDToNum(Realtime[4]) % 10;
		smg7 = BCDToNum(Realtime[5]) / 10;
		smg8 = BCDToNum(Realtime[5]) % 10;
		
		if(smg8 % 2 == 0)
			smg3 = smg6 = 16;
		else
			smg3 = smg6 = 17;
	}
	else if(mode == 3)
	{
		smg1 = smg6 = 17;
		smg4 = smg5 = 16;
		smg2 = temperno / 10;
		smg3 = temperno % 10;
		smg7 = Realtemper[temperno] / 10;
		smg8 = Realtemper[temperno] % 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;
}

unsigned char BCDToNum(unsigned char bcd)
{
	unsigned char a, b;
	
	a = (bcd >> 4);
	b = bcd & 0x0f;
	
	return (a * 10 + b);
}

key.c

#include "sys.h"
 
u8 KeySta[] = {1, 1, 1, 1};
u8 KeyBackup[] = {1, 1, 1, 1};
u8 KeyBuff[] = {0xff, 0xff, 0xff, 0xff};
 
void KeyScan(void)
{
	u8 i;
	
	KeyBuff[0] = (KeyBuff[0] << 1) | S7;
	KeyBuff[1] = (KeyBuff[1] << 1) | S6;
	KeyBuff[2] = (KeyBuff[2] << 1) | S5;
	KeyBuff[3] = (KeyBuff[3] << 1) | S4;
	
	for(i = 0; i < 4; i ++)
	{
		if(KeyBuff[i] == 0xff)				//Key release
			KeySta[i] = 1;
		else if(KeyBuff[i] == 0x00)		//Key press
			KeySta[i] = 0;
		else
		{}
	}
}
 
void KeyAction(unsigned char key)
{
	static u8 index = 1;
	
	if((key == 3) && (mode == 1))		//S4
	{
		index ++;
		switch(index)
		{
			case 1: Temper_time = 1; break;
			case 2: Temper_time = 5; break;
			case 3: Temper_time = 30; break;
			case 4: Temper_time = 60; break;
			default: index = 1; Temper_time = 1; break;
		}
	}
	else if((key == 2) && (mode == 1))			//S5
	{
		flag_start = 1;
		mode = 2;
	}
	else if((key == 1) && (mode == 3))			//S6
	{
		if(flag_led)
			flag_led = 0;
		temperno ++;
		if(temperno >= 10)
			temperno = 0;
	}
	else if((key == 0) && (mode == 3))			//S7
	{
		mode = 1;
		temperno = 0;
	}
}
 
void KeyPress(void)
{
	u8 i;
	
	for(i = 0; i < 4; i ++)
	{
		if(KeySta[i] != KeyBackup[i])
		{
			if(KeySta[i] == 0)					//action when key press
				KeyAction(i);
			KeyBackup[i] = KeySta[i];
		}
	}
}
 

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;							//禁止总中断
	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;
		EA = 1;
		Delayus(60);					//延时60us
		DS18B20_IO = 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
		EA = 1;
	 	if(DS18B20_IO)				//读取通信引脚上的值
		 	dat |= mask;
		Delayus(60);					//再延时60us
	}
	
	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

ds1302.c

#include "sys.h"

sbit DS1302_IO = P2^3;
sbit DS1302_CK = P1^7;
sbit DS1302_CE = P1^3;

void DS1302ByteWrite(unsigned char dat) 
{
	unsigned char mask;
	DS1302_IO = 1;					//拉低IO总线
	for(mask = 0x01; mask != 0; mask <<= 1)	//低位在前,逐位移出
	{
		if((dat&mask) != 0)		//首先输出该位数据
			DS1302_IO = 1;
		else
			DS1302_IO = 0;
		DS1302_CK = 1;				//拉高时钟线
		DS1302_CK = 0;				//拉低时钟线,完成一个位的操作
	}
	DS1302_IO = 1;  				//写完之后确保释放IO总线
}  

unsigned char DS1302ByteRead(void)
{
	unsigned char mask, dat = 0;
	
	for(mask = 0x01; mask != 0; mask <<= 1)	//低位在前,逐位读取
	{
		if(DS1302_IO)			//首先读取此时的IO引脚,并设置dat中的对应位
			dat |= mask;

		DS1302_CK = 1;		//拉高时钟
		DS1302_CK = 0;		//再拉低时钟,完成一个位的操作
	}
	return dat;					//返回读到的字节数据
} 

void DS1302SingleWrite(unsigned char reg, unsigned char dat)     
{
	DS1302_CE = 1;					//使能片选信号
	DS1302ByteWrite((reg << 1) | 0x80);	//发送写寄存器指令
	DS1302ByteWrite(dat);		//写入字节数据
	DS1302_CE = 0;					//除能片选信号
}

unsigned char DS1302SingleRead(unsigned char reg)
{
	unsigned char dat;
	
	DS1302_CE = 1;					//使能片选信号
	DS1302ByteWrite((reg << 1) | 0x81);	//发送读寄存器指令
	dat = DS1302ByteRead();	//读取字节数据
	DS1302_CE = 0;					//除能片选信号
	
	DS1302_IO = 0;					//单字节读必须加的!
	
	return dat;         
}

void DS1302BurstWrite(unsigned char *dat)
{
	unsigned char i;
	
	DS1302_CE = 1;
	DS1302ByteWrite(0xBE);				//发送突发写寄存器指令
	for(i = 0; i < 7; i ++)				//连续写入8字节数据
		DS1302ByteWrite(*dat++);        
	DS1302_CE = 0;      
}

void DS1302BurstRead (unsigned char *dat)
{
	unsigned char i;
	
	DS1302_CE = 1;
	DS1302ByteWrite(0xBF);				//发送突发读寄存器指令
	for(i = 0; i < 7; i++)				//连续读取8个字节
		dat[i] = DS1302ByteRead();      
	DS1302_CE = 0;  
	
	DS1302_IO = 0;								//突发读必须加
}	

void GetRealTime(unsigned char *time)
{
	unsigned char buf[8];
	
	DS1302BurstRead(buf);
	time[0] = buf[6];
	time[1] = buf[4];
	time[2] = buf[3];
	time[3] = buf[2];
	time[4] = buf[1];
	time[5] = buf[0];
	time[6] = buf[5];
}

void SetRealTime(unsigned char *time)
{
	unsigned char buf[8];
	
	buf[7] = 0;
	buf[6] = time[0];
	buf[4] = time[1];
	buf[3] = time[2];
	buf[2] = time[3];
	buf[1] = time[4];
	buf[0] = time[5];
	buf[5] = time[6];
	DS1302BurstWrite(buf);
}

void InitDS1302(unsigned char *time)
{
	unsigned char dat;
	signed char i = 7;
	unsigned char timeinit[8];
	
	while(i >= 0)
	{
		timeinit[i] = time[i];
		i --;
	}
	
	DS1302_CE = 0;								//初始化DS1302通信引脚
	DS1302_CK = 0;
	dat = DS1302SingleRead(0);			//读取秒寄存器
	DS1302SingleWrite(7, 0x00);  	//撤销写保护以允许写入数据
	SetRealTime(&timeinit);					//设置DS1302时间
//	DS1302SingleWrite(7, 0x80);  	//写保护以禁止写入数据
}

ds1302.h

#ifndef __DS1302_H
#define __DS1302_H

void DS1302ByteWrite(unsigned char dat);
unsigned char DS1302ByteRead(void);
void DS1302SingleWrite(unsigned char reg, unsigned char dat);
unsigned char DS1302SingleRead(unsigned char reg);
void DS1302BurstWrite(unsigned char *dat);
void DS1302BurstRead (unsigned char *dat);
void GetRealTime(unsigned char *time);
void SetRealTime(unsigned char *time);
void InitDS1302(unsigned char *time);


#endif

猜你喜欢

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