蓝桥杯单片机第8届-电子时钟

题目

在这里插入图片描述

main.c

#include<stc15f2k60s2.h>
#include<intrins.h>

#define uchar unsigned char

#define s0 0
#define s1 1
#define s2 2

uchar get_tempr();
void write_ds1302_main(char time[]);
void write_ds1302_interrupt(char time[]);
char * read_ds1302(void);

uchar semg[13] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90,
									0xbf, 0xc6, 0xff};
uchar semg_bit[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
uchar semg_temp[8] = {12, 12, 12, 12, 12, 12, 12, 12};
char time[2][3] = {{23, 59, 59}, {0, 0, 0}};

uchar state = s0;
uchar state_set = s0;
uchar keycode;
uchar keycount = 3;
uchar alarm = 0;
uchar tempr = 25;


void Delay5ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 54;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}


void allinit()
{
	P2 = 0x80;	P0 = 0xff;
	P2 = 0xa0;	P0 = 0x00;
	P2 = 0xc0;	P0 = 0xff;
	P2 = 0xe0;	P0 = 0xff;
}


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


void distime(uchar i, int time_dis)
{
	if(time_dis < 250)
	{
		P2 = 0xe0;
		P0 = semg[semg_temp[i]];
	}
	else
	{
		P2 = 0xe0;
		P0 = 0xff;			
	}
}


void display()
{
	static uchar i = 0;
	static int time_dis = 0;
	
	if(state == s0)
	{
		P2 = 0xe0;
		P0 = semg[semg_temp[i]];
	}
	else
	{
		if(keycount == 0 && (i == 0 || i == 1))
			distime(i, time_dis);
		else if(keycount == 1 && (i == 3 || i == 4))
			distime(i, time_dis);
		else if(keycount == 2 && (i == 6 || i == 7))
			distime(i, time_dis);
		else
		{
				P2 = 0xe0;
				P0 = semg[semg_temp[i]];
		}
	}
	
	P2 = 0xc0;	P0 = semg_bit[i];
	P2 = 0x00;	P0 = 0xff;
	
	i++;	time_dis++;
	if(i == 8)
		i = 0;
	if(time_dis == 500)
		time_dis = 0;
}


void led()
{
	uchar j;
	static uchar state_led = s0;
	static int time_led = 0;

	switch(state_led)
	{
		case s0:
		{
			P0 = 0x00;	P2 = 0xa0;	P2 = 0x00;
			P0 = 0xff;  P2 = 0x80;	P2 = 0X00;
			alarm = 0;
			for(j = 0; j < 3; j++)
				if(time[0][j] != time[1][j])
				{
					time_led = 0;
					break;
				}

			if(j == 3)
			{
				state_led = s1;
				alarm = 1;
			}
			else
				state_led = s0;
		}	break;
	
		case s1:
		{
			time_led++;
			if( (time_led % 100) == 0)
			{
				if( (time_led / 100) % 2 == 0 )
				{
					P0 = 0x40;	P2 = 0xa0;	P2 = 0x00;
					P0 = 0xfe;	P2 = 0x80;	P2 = 0x00;
				}
				else
				{
					P0 = 0x00;	P2 = 0xa0;	P2 = 0x00;
					P0 = 0xff;	P2 = 0x80;	P2 = 0x00;
				}
			}

			if(!alarm || time_led == 2500)
			{
				state_led = s0;
				alarm = 0;
			}
		}	break;
		
		default:	state_led = s0;	break;
	}
		
	P2 = 0x00;	P0 = 0xff;
}


void fun()	interrupt 1
{
	char *time_temp, i, j;
		
	display();
	led();
	
	if(state == s0 || (state ==  s1 && state_set == s1))
	{
		i++;
		if(i == 120)
		{
			i = 0;
			time_temp = read_ds1302();
			time[0][0] = time_temp[0];
			time[0][1] = time_temp[1];
			time[0][2] = time_temp[2];
		}
	}
	else
	{
		j++;
		if(j == 120)
		{
			j = 0;
			write_ds1302_interrupt(time[0]);
		}
	}
}


char keyscan()
{
	uchar trg, keybefore;
	static char keyvalue = -1;
	
	P44 = 0;	P42 = 0; P35 = 0;
	keycode = (P3 ^ 0xff) & 0x0f;
	trg = keycode & (keycode ^ keybefore);
	keybefore = keycode;
	
	if(trg == 0x01)				keyvalue = 7;
	else if(trg == 0x02)	keyvalue = 6;
	else if(trg == 0x04)	keyvalue = 5;
	else if(trg == 0x08)	keyvalue = 4;
	else 									keyvalue = -1;

	return keyvalue;
}


void menu(char keyvalue)
{
	uchar i;
	
	if((keyvalue != -1) && (alarm == 1))
		alarm = 0;

	switch(state)
	{
		case s0:
		{
			if(keycode == 0x08)
			{
				for(i =0; i < 5; i++)
					semg_temp[i] = 12;
				semg_temp[5] = tempr /10;
				semg_temp[6] = tempr % 10;
				semg_temp[7] = 11;
			}
			else
			{
				semg_temp[0] = time[0][0] / 10;
				semg_temp[1] = time[0][0] % 10;
				semg_temp[2] = 10;
				semg_temp[3] = time[0][1] / 10;
				semg_temp[4] = time[0][1] % 10;
				semg_temp[5] = 10;
				semg_temp[6] = time[0][2] / 10;
				semg_temp[7] = time[0][2] % 10;
			}
			
			if(keyvalue == 7)
			{
				state = s1;
				state_set = s0;
				keycount = 0;
			}
			else if(keyvalue == 6)
			{
				state = s1;
				state_set = s1;
				keycount = 0;
			}
			
		}	break;
		
		case s1:
		{
			semg_temp[0] = time[state_set][0] / 10;
			semg_temp[1] = time[state_set][0] % 10;
			semg_temp[2] = 10;
			semg_temp[3] = time[state_set][1] / 10;
			semg_temp[4] = time[state_set][1] % 10;
			semg_temp[5] = 10;			
			semg_temp[6] = time[state_set][2] / 10;
			semg_temp[7] = time[state_set][2] % 10;
			
			if(keyvalue == 4)
			{
				time[state_set][keycount] = time[state_set][keycount] - 1;
				if(keycount == 0)
				{
					if(time[state_set][keycount] < 0)
						time[state_set][keycount] = 23;
				}
				else
				{
					if(time[state_set][keycount] < 0)
						time[state_set][keycount] = 59;
				}
			}
			else if(keyvalue == 5)
			{
				time[state_set][keycount] = time[state_set][keycount] + 1;
				if(keycount == 0)
				{
					if(time[state_set][keycount] > 23)
						time[state_set][keycount] = 0;
				}
				else
				{
					if(time[state_set][keycount] > 59)
						time[state_set][keycount] = 0;
				}			
			}
	
			switch(state_set)
			{
				case s0:
				{
					if(keyvalue == 7)
					{
						keycount++;
						if(keycount == 3)
						{
							keycount = 3;
							state = s0;
							break;
						}
					}
				}	break;
				
				case s1:
				{
					if(keyvalue == 6)
					{
						keycount++;
						if(keycount == 3)
						{
							keycount = 3;
							state = s0;
							break;
						}
					}
				}	break;
				
				default: state_set = s0;	break;
			}
			
		}	break;
		
		default: state = s0;	break;
	}

}


void main()
{
	static char keyvalue = -1;
	write_ds1302_main(time[0]);
	allinit();
	Timer0Init( );	
	
	while(1)
	{
		keyvalue = keyscan();
		menu(keyvalue);
		tempr = get_tempr();
		Delay5ms();
	}
}

ds1302.c

/*
  程序说明: DS1302驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char											

sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;   // DS1302复位												

void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK=0;
		SDA=temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	RST=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();

	return (temp);			
}

void write_ds1302_main(char *time)
{
	uchar addr, i;
	
	addr = 0x84;
	
	Write_Ds1302_Byte(0x8e, 0x00);
	for(i = 0; i < 3; i++)
	{
		Write_Ds1302_Byte(addr, (time[i]/10)<<4 | time[i] % 10);
		addr -= 2;
	}
	Write_Ds1302_Byte(0x8e, 0x80);
}

void write_ds1302_interrupt(char *time)
{
	uchar addr, i;
	
	addr = 0x84;
	
	Write_Ds1302_Byte(0x8e, 0x00);
	for(i = 0; i < 3; i++)
	{
		Write_Ds1302_Byte(addr, (time[i]/10)<<4 | time[i] % 10);
		addr -= 2;
	}
	Write_Ds1302_Byte(0x8e, 0x80);
}

char * read_ds1302()
{
	uchar addr, i;
	char time[3];
	
	addr = 0x85;
	
	Write_Ds1302_Byte(0x8e, 0x00);
	for(i = 0; i < 3; i++)
	{
		time[i] = Read_Ds1302_Byte(addr);
		time[i]= (time[i] / 16) * 10 + time[i] % 16;
		addr -= 2;
	}
	Write_Ds1302_Byte(0x8e, 0x80);
	
	return time;
}

ds18b20.c

/*
  程序说明: 单总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
  日    期: 2011-8-9
*/
#include "reg52.h"

#define uchar unsigned char

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

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	unsigned char i;
	while(t--)
	{
		for(i=0;i<12;i++);
	}
}

//通过单总线向DS18B20写一个字节
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 get_tempr()
{
	uchar high, low;
	
	init_ds18b20( );
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(500);
	
	init_ds18b20( );
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);

	low = Read_DS18B20();
	high = Read_DS18B20();
	
	return (high<<4 | low>>4);
}
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值