蓝桥杯第八届省赛 模拟电子钟

【冉冰的成长日记002】
没鸽,but,出问题了,我觉得程序所有出问题的地方逻辑上都是正确的,可惜就是不对,问题已用数字标出,如果有大哥闲来无事,麻烦帮弟弟解决一下吧QAQ万分感谢

另外,真的累啊,比上一篇累多了,代码也写得很繁杂,不够精简

看文章吧,不多废话


```c
#include
#include"ds1302.h"
#include"onewire.h"

unsigned char LED[] = 
{
     
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xBF ,0xFF ,0xC6
}; //数码管真值表
unsigned char LEDbuff[] = 
{
     
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
}; //数码管缓冲区
extern unsigned char Time_Get[7];//ds的外部数据存放
unsigned char flag=0,S7_flag=0,S6_flag=0;//falg用来判断时钟模式还是闹钟模式和温度
unsigned char clock_shi=0,clock_fen=0,clock_miao=0;//闹钟模式的初值
unsigned char T;//温度的获取
unsigned cnt=0,num=0;//中断计时
bit check_S7=0,check_S6=0,check_S5=0,check_S4=0;//check用来按键消抖。

sbit S4=P3^3;	 //按键定义
sbit S5=P3^2;
sbit S6=P3^1;
sbit S7=P3^0;

void Timer0Init();	//定时器0,1ms
void Initial();		//模块初始化
void KEY();			//按键模块,包括S7.S6.S5.S4
void DisPlay();		//数码管模块,两个模式,每个模式四个状态
void DisPlay_Temp();//温度显示(存在问题)
void main()
{
     
	Timer0Init();
	DS1302_Init();
	Initial();
	while(1)
	{
     
		KEY();
		DisPlay();
		if(cnt>=1000)					//每一秒获取一次温度
		{
     
			DS18B20_Start();
			T=DS18B20_Get();
			cnt=0;
		}
		DS1302_Get();					 
	}
}

void delay(unsigned int x)			 //延时函数,ms单位
{
     
	if(num>=x)
	{
     
		num=0;
	}	
}

void Initial()		//初始化函数
{
     
	P2 = (P2&0x1F)|0x80;
	P0 = 0xFF;		//初始化LED

	P2 = (P2&0x1F)|0xA0;
	P0 = 0x00;		//初始化继电器和蜂鸣器

	P2 = (P2&0x1F)|0xC0;
	P0 = 0xFF;
	P2 = (P2&0x1F)|0xE0;
	P0 = 0xFF;      //初始化数码管
}

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

	EA = 1;
	ET0 = 1;
}

void KEY_S7()					 
{
     
	if(S7==0)
	{
     
		delay(10);
		if(S7==0)
			check_S7=1;	
	}
	if((S7==1)&&(check_S7==1))
	{
     
		flag=0;					//时钟模式
		check_S7=0;
		S7_flag++;				//时钟模式的四个状态切换
		if(S7_flag>=4)
			S7_flag=0;
	}	
}

void KEY_S6()
{
     
	if(S6==0)
	{
     
		delay(10);
		if(S6==0)
			check_S6=1;	
	}
	if((S6==1)&&(check_S6==1))
	{
     
		flag=1;					  //闹钟模式
		check_S6=0;
		S6_flag++;				 //闹钟模式的四个状态切换
		if(S6_flag>=4)
			S6_flag=0;
	}
}

void KEY_S5()
{
     
   if(S5==0)
	{
     
		delay(10);
		if(S5==0)
			check_S5=1;	
	}
	if((S5==1)&&(check_S5==1))
	{
     
		check_S5=0;
		if(flag==0)
		{
     						
			if(S7_flag==1)				

 1. //这个数组地方加一不知道哪出了问题,感觉逻辑上没问题呀,有大哥麻烦解答一下

			{
     Time_Get[2]=Time_Get[2]+1;if(Time_Get[2]>23)  Time_Get[2]=0;}
			if(S7_flag==2)
			{
     Time_Get[1]=Time_Get[1]+1;if(Time_Get[1])  Time_Get[1]=0;}
			if(S7_flag==3)
			{
     Time_Get[0]=Time_Get[0]+1;if(Time_Get[0])  Time_Get[0]=0;}
		}
		if(flag==1)					 //闹钟模式正常
		{
     
			if(S6_flag==1)
			{
     clock_shi++;if(clock_shi>23)  clock_shi=0;}
			if(S6_flag==2)
			{
     clock_fen++;if(clock_fen>59)  clock_fen=0;}
			if(S6_flag==3)
			{
     clock_miao++;if(clock_miao>59)  clock_miao=0;}
		}
	}
}

void KEY_S4()
{
     
   if(S4==0)
	{
     
		delay(10);
		if(S4==0)
		{
     
			check_S4=1;

 1. //这里没写按下显示温度,可以用while(S4==0)判断实现按下显示温度,弹起返回,但是在com6数码选中上keil显示Target not created ,不知道是什么情况

		}		
	}

	if((S4==1)&&(check_S4==1))
	{
     
		check_S4=0;
		if(flag==0)
		{
     
			if(S7_flag==1)						//时钟模式问题同上
			{
     Time_Get[2]--;if(Time_Get[2]<0)  Time_Get[2]=23;}
			if(S7_flag==2)
			{
     Time_Get[1]--;if(Time_Get[1]<0)  Time_Get[1]=59;}
			if(S7_flag==3)
			{
     Time_Get[0]--;if(Time_Get[0]<0) Time_Get[0]=59;}
		}
		if(flag==1)
		{
     
		if(S6_flag==1)
			{
     clock_shi--;if(clock_shi<0)  clock_shi=23;}
			if(S6_flag==2)
			{
     clock_fen--;if(clock_fen<0)  clock_fen=59;}
			if(S6_flag==3)
			{
     clock_miao--;if(clock_miao<0) clock_miao=59;}
		}
	}
}

void KEY()
{
     
	KEY_S7();
	KEY_S6();
	KEY_S5();
	KEY_S4();
}

void DisPlay_S7()
{
     
	if(S7_flag==0)
	{
     
		LEDbuff[0] = LED[Time_Get[0]%10];
		LEDbuff[1] = LED[Time_Get[0]/10];
		LEDbuff[2] = LED[10];
		LEDbuff[3] = LED[Time_Get[1]%10];
		LEDbuff[4] = LED[Time_Get[1]/10];
		LEDbuff[5] = LED[10];
		LEDbuff[6] = LED[Time_Get[2]%10];
		LEDbuff[7] = LED[Time_Get[2]/10];
	}
	if(S7_flag==1)
	{
     
		LEDbuff[0] = LED[Time_Get[0]%10];
		LEDbuff[1] = LED[Time_Get[0]/10];
		LEDbuff[2] = LED[10];
		LEDbuff[3] = LED[Time_Get[1]%10];
		LEDbuff[4] = LED[Time_Get[1]/10];
		LEDbuff[5] = LED[10];

		if(Time_Get[0]%2==0)	 //对秒进行取余,偶数显示,奇数熄灭,达到每一秒闪烁的效果,看b站学的,感觉up好聪明
		{
     
			LEDbuff[6] = LED[Time_Get[2]%10];
			LEDbuff[7] = LED[Time_Get[2]/10];
		}
		else
		{
     
			LEDbuff[6] = LED[11];
			LEDbuff[7] = LED[11];
		}
	}
	if(S7_flag==2)
	{
     
		LEDbuff[0] = LED[Time_Get[0]%10];
		LEDbuff[1] = LED[Time_Get[0]/10];
		LEDbuff[2] = LED[10];
		
		LEDbuff[5] = LED[10];
		LEDbuff[6] = LED[Time_Get[2]%10];
		LEDbuff[7] = LED[Time_Get[2]/10];
		if(Time_Get[0]%2==0)
		{
     
			LEDbuff[3] = LED[Time_Get[1]%10];
			LEDbuff[4] = LED[Time_Get[1]/10];	
		}
		else
		{
     
			LEDbuff[3] = LED[11];
			LEDbuff[4] = LED[11];
		}
	}
	if(S7_flag==3)
	{
     
		
		LEDbuff[2] = LED[10];
		LEDbuff[3] = LED[Time_Get[1]%10];
		LEDbuff[4] = LED[Time_Get[1]/10];
		LEDbuff[5] = LED[10];
		LEDbuff[6] = LED[Time_Get[2]%10];
		LEDbuff[7] = LED[Time_Get[2]/10];
		if(Time_Get[0]%2==0)
		{
     
			LEDbuff[0] = LED[Time_Get[0]%10];
			LEDbuff[1] = LED[Time_Get[0]/10];		
		}
		else
		{
     
			LEDbuff[0] = LED[11];
			LEDbuff[1] = LED[11];
		}
	}
}

void DisPlay_S6()
{
     
	if(S6_flag==0)
	{
     
		LEDbuff[0] = LED[Time_Get[0]%10];
		LEDbuff[1] = LED[Time_Get[0]/10];
		LEDbuff[2] = LED[10];
		LEDbuff[3] = LED[Time_Get[1]%10];
		LEDbuff[4] = LED[Time_Get[1]/10];
		LEDbuff[5] = LED[10];
		LEDbuff[6] = LED[Time_Get[2]%10];
		LEDbuff[7] = LED[Time_Get[2]/10];
	}
	if(S6_flag==1)
	{
     
		LEDbuff[0] = LED[clock_miao%10];
		LEDbuff[1] = LED[clock_miao/10];
		LEDbuff[2] = LED[10];
		LEDbuff[3] = LED[clock_fen%10];
		LEDbuff[4] = LED[clock_fen/10];
		LEDbuff[5] = LED[10];

		if(Time_Get[0]%2==0)
		{
     
			LEDbuff[6] = LED[clock_shi%10];
			LEDbuff[7] = LED[clock_shi/10];
		}
		else
		{
     
			LEDbuff[6] = LED[11];
			LEDbuff[7] = LED[11];
		}
	}
	if(S6_flag==2)
	{
     
		LEDbuff[0] = LED[clock_miao%10];
		LEDbuff[1] = LED[clock_miao/10];
		LEDbuff[2] = LED[10];

		LEDbuff[5] = LED[10];
		LEDbuff[6] = LED[clock_shi%10];
		LEDbuff[7] = LED[clock_shi/10];

		if(Time_Get[0]%2==0)
		{
     
			LEDbuff[3] = LED[clock_fen%10];
			LEDbuff[4] = LED[clock_fen/10];
		}
		else
		{
     
			LEDbuff[3] = LED[11];
			LEDbuff[4] = LED[11];
		}
	}
	if(S6_flag==3)
	{
     
	
		LEDbuff[2] = LED[10];
		LEDbuff[3] = LED[clock_fen%10];
		LEDbuff[4] = LED[clock_fen/10];
		LEDbuff[5] = LED[10];
		LEDbuff[6] = LED[clock_shi%10];
		LEDbuff[7] = LED[clock_shi/10];

		if(Time_Get[0]%2==0)
		{
     
			LEDbuff[0] = LED[clock_miao%10];
			LEDbuff[1] = LED[clock_miao/10];
		}
		else
		{
     
			LEDbuff[0] = LED[11];
			LEDbuff[1] = LED[11];
		}
	}	
}

void DisPlay()
{
     
	if(flag==0)
		DisPlay_S7();
	if(flag==1)
		DisPlay_S6();
}

void Flash()
{
     
	static unsigned char i;
	if((Time_Get[0]==clock_miao)&&(Time_Get[1]==clock_fen)&&(Time_Get[2]==clock_shi))

 1. //这个地方,闹钟模式和时钟模式时,分,秒相同时闪烁,在我板子上也出现问题不知道为啥,我依旧觉得程序逻辑没问题QAQ求助

	{
     
		P2=0x80;
		for(i=0;i<11;i++)
		{
     
			P2 = (P2&0x1F)|0x80;
			P0 = 0xFE;
			delay(200);
			P2 = (P2&0x1F)|0x80;
			P0 = 0xFF;
			delay(200);
		}
		P2 = (P2&0x1F)|0x80;
		P0 = 0xFE;
		delay(200);
		P2 = (P2&0x1F)|0x80;
		P0 = 0xFF;
	}
}

void InterruptTimer0() interrupt 1
{
     
	static unsigned char i=0;
	TL0 = 0xCD;		//设置定时初值
	TH0 = 0xD4;		//设置定时初值
	switch(i)
	{
     
		case 0:P2 = 0xC0;P0=0x80;P2=0xE0;P0=LEDbuff[0];i++;break;
		case 1:P2 = 0xC0;P0=0x40;P2=0xE0;P0=LEDbuff[1];i++;break;
		case 2:P2 = 0xC0;P0=0x20;P2=0xE0;P0=LEDbuff[2];i++;break;
		case 3:P2 = 0xC0;P0=0x10;P2=0xE0;P0=LEDbuff[3];i++;break;
		case 4:P2 = 0xC0;P0=0x08;P2=0xE0;P0=LEDbuff[4];i++;break;
		case 5:P2 = 0xC0;P0=0x04;P2=0xE0;P0=LEDbuff[5];i++;break;
		case 6:P2 = 0xC0;P0=0x02;P2=0xE0;P0=LEDbuff[6];i++;break;
		case 7:P2 = 0xC0;P0=0x01;P2=0xE0;P0=LEDbuff[7];i=0;break;
		default : break;
	}
	num++;
	cnt++;
	Flash(); //闹钟模式闪烁
}
main函数,这次写的这么长就突出了拆分成多个c文件的重要性,我写的好乱emmm

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

#include
#include"ds1302.h"
#include 

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

unsigned char Time_Init[7]={
     50, 59, 23, 1, 1, 1, 1};
unsigned char Time_Get[7];

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/10<<4)|(dat%10));						
 	RST=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
     
 	unsigned char dat1,dat2;
	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_();

	dat1=temp/16;
	dat2=temp%16;
	temp=dat1*10+dat2;
	return (temp);			
}

void DS1302_Init()
{
     
	unsigned char add=0x80,i=0;
	Write_Ds1302_Byte(0x8E,0);
	for(i=0;i<7;i++)
	{
     
		Write_Ds1302_Byte(add,Time_Init[i]);
		add = add +2;
	}
	Write_Ds1302_Byte(0x8E,0x80);
}

void DS1302_Get()
{
     
	unsigned char add=0x81,i=0;
	Write_Ds1302_Byte(0x8E,0x80);
	for(i=0;i<7;i++)
	{
     
		Time_Get[i] = Read_Ds1302_Byte(add);
		add = add +2;
	}
	Write_Ds1302_Byte(0x8E,0x80);
}
以上是ds1302.c的文件

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

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

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

//通过单总线向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;
}

void DS18B20_Start()
{
     
	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0x44);
	Delay_OneWire(200);
}

unsigned char DS18B20_Get()
{
     
   	char temp=0;
	unsigned char high=0,low=0;
	
	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0xBE);
	
	low=Read_DS18B20();	
	high=Read_DS18B20();

	temp = high<<4;
	temp = temp|(low>>4);
	return temp;
}

以上是DS18B20.c的文件

#ifndef __DS1302_H
#define __DS1302_H

void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );

void DS1302_Init();
void DS1302_Get();
#endif

ds1302.h的文件

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

unsigned char rd_temperature(void);  //; ;
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
void DS18B20_Start();
unsigned char DS18B20_Get();

#endif

ds18b20.h的文件

这次的题真的是让我写的又臭又长,真的拉跨,这水平基本告别比赛了,散会散会,咕咕咕~~

蓝桥杯第八届省赛 模拟电子钟_第1张图片

蓝桥杯第八届省赛 模拟电子钟_第2张图片

感谢大佬观看,烦请请指正错误,

QAQ希望我还有良心,趁着这两天把这写问题解决一下吧

你可能感兴趣的:(蓝桥杯,单片机,物联网)