蓝桥杯单片机第十三届模拟题01——源代码

该代码实现了一个基于RTC DS1302的实时时钟系统,能够读取时间并动态显示在数码管上。同时,系统集成了温度传感器DS18B20,可以获取并显示环境温度。用户可以通过按键切换显示模式,包括当前时间与温度。此外,系统还包含了一个简单的报警功能,当时间达到特定设置时会触发继电器和蜂鸣器响应。
摘要由CSDN通过智能技术生成

还有一天比赛了,先看原题请添加图片描述
很简单,感觉就是前几届不常考的考点,注意那个L10操作

MAIN.C

#include<reg51.h>
#include<ds1302.h>
#include<onewire.h>

#define uchar unsigned char
#define uint unsigned int


unsigned char  TIME_buffer2[7];
unsigned char  TIME_buffer1[7];
unsigned char  TIME_buffer[7];
uchar mode;
int temp;
uchar shi;
uchar ge;
uchar shi_p;
uchar ge_p;
int temp2;
uchar count; 
uchar count_a;
 0    1     2    3    4    5    6   7    8    9    -   全灭   .
unsigned char code shuzi[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0xbf,0xff,0x7f};
/// A     b   C     d    E    F    H   L     P    U   n
unsigned char code zimu[]={0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0xc7,0x8c,0xc1,0xc8};
  0     1     2    3    4    5    6    7   
unsigned char code weizhi[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00};
//   1    2   3    4    5    6    7    8    灭
unsigned char ledweizhi[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff};

unsigned char code WRITE_RTC_ADDR[7] = 
	{0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};   //定义写操作的日历时钟寄存器地址
unsigned char code READ_RTC_ADDR[7] = 
	{0x81,0x83,0x85,0x87,0x89,0x8b,0xbd};   //定义读操作的日历时钟寄存器地址
unsigned char TIME[7] = 
	{0x00,0x00,0x12,0x18,0x02,0x02,0x20};	//定义日历时钟寄存器配置参数(秒、分、时、日、月、星期、年)
unsigned char code SEG_code[18] = 
	{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
	 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
	 0xbf,0x7f};	                        //定义共阳数码管段码内容:0~F,—,.
	
sbit R1=P3^0;
sbit R2=P3^1;
sbit R3=P3^2;
sbit R4=P3^3;
	 
sbit Relay= P0^4; //继电器
sbit Buzz=P0^6;//蜂鸣器
void delay_ms(int ms)
{
	int q,w;
	for(q=0;q<ms;q++){
	for(w=845;w>0;w--);
	}
}
void ledlight(uchar x)
{
	P2=(P2&0X1f)|0x80;
	P0=ledweizhi[x];
}
void DS1302_Config()
{
	unsigned char n;
	Write_Ds1302_Byte(0x8e,0x00);   //允许向内存写入数据
	for(n=0;n<7;n++)
	{
		Write_Ds1302_Byte(WRITE_RTC_ADDR[n],TIME[n]);   //低位先写
	}
	Write_Ds1302_Byte(0x8e,0x80);   //禁止向内存写入数据
}
void shumaguan_shuzi(uchar a,uchar b)
{
	delay_ms(1);
	P2=(P2&0X1f)|0xC0;P0=weizhi[a];
	P2=(P2&0X1f)|0xE0;P0=shuzi[b];
	delay_ms(1);
	//消隐
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 0x00;
	P2 = P2 & 0x1f;
}
//数码管字母显示
void shumaguan_zimu(uchar a,uchar b)
{
	delay_ms(1);
	P2=(P2&0X1f)|0xC0;P0=weizhi[a];
	P2=(P2&0X1f)|0xE0;P0=zimu[b];
	delay_ms(1);
	//消隐
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 0x00;
	P2 = P2 & 0x1f;
}
void timer0()  //定时模式
{
	ET0=1;
	EA=1;		
	TMOD &= 0xF0;		
	TH0 = (65535-50000)/256;//50000us=50ms		
	TL0 = (65535-50000)%256;		
	TF0 = 1;		
	TR0 = 1;
}
//数字时钟,需要重装载
void Service_timer0() interrupt 1//定时器0
{
	TH0 = (65535-50000)/256;//50000us=50ms		
	TL0 = (65535-50000)%256;	
	count++;
	if(count==20)   
	{
		count=0;
		count_a++;
	}	
}
//读取实时时间
void DS1302_ReadTime()
{
	unsigned char n;
	for(n=0;n<7;n++)
	{
		TIME_buffer[n]=TIME[n];
	}
	for(n=0;n<7;n++)
	{
		TIME[n] = Read_Ds1302_Byte(READ_RTC_ADDR[n]);
	}
}


//数码管延时函数
void Delay_tube(unsigned char t)
{
	while(t--);
}

//数码管显示
void Show_tube(unsigned char position,unsigned char value)
{
	P2 = (P2 & 0x1f) | 0xc0;//数码管的片选端
	P0 = 0x01 << position;
	P2 = (P2 & 0x1f) | 0xe0;//数码管的数据
	P0 = value;
}

//数码管动态显示
void Display_tube()
{

	Show_tube(0,SEG_code[TIME_buffer[2]/16]);     //显示时的十位(TIME[n]为16进制数,所以除以16)
	Delay_tube(500);
	Show_tube(1,SEG_code[TIME_buffer[2]%16]);     //显示时的个位
	Delay_tube(500);
	
	Show_tube(2,SEG_code[16]);	           //显示分隔符
	Delay_tube(500);

	Show_tube(3,SEG_code[TIME_buffer[1]/16]);     //显示分的十位
	Delay_tube(500);
	Show_tube(4,SEG_code[TIME_buffer[1]%16]);     //显示分的个位
	Delay_tube(500);

	Show_tube(5,SEG_code[16]);             //显示分隔符
	Delay_tube(500);

	Show_tube(6,SEG_code[TIME_buffer[0]/16]);     //显示秒的十位
	Delay_tube(500);
	Show_tube(7,SEG_code[TIME_buffer[0]%16]);     //显示秒的个位
	Delay_tube(500);
	
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 0x00;
	P2 = P2 & 0x1f;
	
}
void jisuan()
{
if(TIME_buffer[2]==10)
{
	TIME_buffer2[2]=0;
	TIME_buffer1[2]++;
	TIME_buffer[2]=TIME_buffer1[2]<<4|(TIME_buffer2[2]&0x0f);//0x10
}
	if(TIME_buffer[2]==0x1a)
	{
		TIME_buffer2[2]=0;
		TIME_buffer1[2]++;   
		TIME_buffer[2]=TIME_buffer1[2]<<4|(TIME_buffer2[2]&0x0f);
	}
	if(TIME_buffer[2]==0x24)
	{
		TIME_buffer2[2]=0;
		TIME_buffer1[2]=0;
		TIME_buffer[2]=0;  		
	}
	if(TIME_buffer[1]==10)
{
	TIME_buffer2[1]=0;
	TIME_buffer1[1]++;
	TIME_buffer[1]=TIME_buffer1[1]<<4|(TIME_buffer2[1]&0x0f);//0x10
}
	if(TIME_buffer[1]==0x1a)
	{
		TIME_buffer2[1]=0;
		TIME_buffer1[1]++;   
		TIME_buffer[1]=TIME_buffer1[1]<<4|(TIME_buffer2[1]&0x0f);
	}
	if(TIME_buffer[1]==0x2a)
	{
		TIME_buffer2[1]=0;
		TIME_buffer1[1]++;   
		TIME_buffer[1]=TIME_buffer1[1]<<4|(TIME_buffer2[1]&0x0f);
	}
	if(TIME_buffer[1]==0x3a)
	{
		TIME_buffer2[1]=0;
		TIME_buffer1[1]++;   
		TIME_buffer[1]=TIME_buffer1[1]<<4|(TIME_buffer2[1]&0x0f);
	}
	if(TIME_buffer[1]==0x4a)
	{
		TIME_buffer2[1]=0;
		TIME_buffer1[1]++;   
		TIME_buffer[1]=TIME_buffer1[1]<<4|(TIME_buffer2[1]&0x0f);
	}
	if(TIME_buffer[1]==0x5a)
	{
		TIME_buffer2[1]=0;
		TIME_buffer1[1]=0;
		TIME_buffer[1]=0;  		
	}
	

}
void display_ds1302()//显示ds1302的时钟
{
	
		DS1302_ReadTime();
		Display_tube();
		ledlight(0);
}

void Init_Keys()
{
	R1=R2=R3=R4=1;
}
void temperature_get()
{
	uchar high,low;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);

	
	
  init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	low=Read_DS18B20();
	high=Read_DS18B20();
	
	
	temp=((high<<4)|(low>>4));//不带小数点,注掉后面一行就行
	temp2=low&0x0f*100/16;//取小数点两位,注掉上面一行就行
	shi=temp%100/10;//不带小数点
	ge=temp%10;
	shi_p=temp2/10;//带两位小数点
	ge_p=temp%10;
}
void display_temp()
{
	shumaguan_zimu(0,2);
	
	shumaguan_shuzi(5,shi);
	shumaguan_shuzi(6,ge);
	shumaguan_shuzi(6,12);//显示小数点
	shumaguan_shuzi(7,ge_p);
	
	ledlight(1);
}
void select_mode()
{
	switch(mode)
	{
		case(0):display_ds1302();break;
		case(1):temperature_get();display_temp();break;
	}
}
void Scan_S4()
{
	if(R4==0)
	{
		while(R4==0);
		mode++;
		if(mode>1) mode=0;
	}
}
void Scan_S5()
{
	uchar n;
	if(R3==0)
	{
		while(R3==0)display_ds1302();
		    TIME_buffer[2]++;
				jisuan();
	      Write_Ds1302_Byte(0x8e,0x00);   //允许向内存写入数据
	      for(n=0;n<7;n++)
					{
		      Write_Ds1302_Byte(WRITE_RTC_ADDR[n],TIME_buffer[n]);   //低位先写
					}
	     Write_Ds1302_Byte(0x8e,0x80);   //禁止向内存写入数据
			}
}
void Scan_S6()
{
	uchar n;
	if(R2==0)
	{
		while(R2==0)display_ds1302();
		    TIME_buffer[1]++;
				jisuan();
	      Write_Ds1302_Byte(0x8e,0x00);   //允许向内存写入数据
	      for(n=0;n<7;n++)
					{
		      Write_Ds1302_Byte(WRITE_RTC_ADDR[n],TIME_buffer[n]);   //低位先写
					}
	     Write_Ds1302_Byte(0x8e,0x80);   //禁止向内存写入数据
			}
}
void Scan_S7()
{
	uchar n;
	if(R1==0)
	{
		while(R1==0) display_ds1302();
		TIME_buffer[0]=0;
		Write_Ds1302_Byte(0x8e,0x00);   //允许向内存写入数据
	      for(n=0;n<7;n++)
					{
		      Write_Ds1302_Byte(WRITE_RTC_ADDR[n],TIME_buffer[n]);   //低位先写
					}
	   Write_Ds1302_Byte(0x8e,0x80);   //禁止向内存写入数据
		}
}
void alarm()
{
	if(TIME_buffer[0]==0x00&&TIME_buffer[1]==0x00)
	{
		P2=0xA0;Relay=1;Buzz=0;
			
	}
else if(count_a%3==0)
		{
			P2=0xA0;Relay=0;Buzz=0;
		}
}
void main()
{
	Init_Keys();
	DS1302_Config();
	timer0();
	while(1)
	{
		temperature_get();
		Scan_S7();
		Scan_S6();
		Scan_S5();
		Scan_S4();
		select_mode();
		alarm();
	}
}

写复杂了,大家主要看思路简化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sol-itude

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

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

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

打赏作者

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

抵扣说明:

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

余额充值