蓝桥杯第八届省赛——电子时钟

花了两天时间才算写出来吧,借鉴了其他人的(闪烁一开始真没想到什么好办法),不多说上代码,代码有一点小问题,就是设置时钟时,加1功能有bug,想了好长时间想不出来,如有知道的麻烦给我讲讲,一起进步哈哈!

main.C

#include "reg52.h"
#include "onewire.h"
#include "ds1302.h"
#include "intrins.h"
#define uchar unsigned char
sfr AUXR=0x8e;
sbit s4=P3^3;
sbit s5=P3^2;
sbit s6=P3^1;
sbit s7=P3^0;
sbit L1=P0^0;
uchar code read_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
uchar code write_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
uchar time[7]={0x55,0x59,0x23,0x00,0x00,0x00,0x00};//秒,分,时,日,月,星期,年
uchar code smgduanma[19]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,
0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f,0xff};//0~f;-;.;全灭
uchar temp=0;       //温度
uchar h=0;          //闹钟的时分秒
uchar m=0;
uchar s=0;  
uchar clock=0;      //时钟设置的时分秒标志位
uchar alarm=0;      //闹钟设置的时分秒标志位
uchar ms0=0,ms1=0;    //定时器0,50毫秒计数,定时器1,50毫秒计数
bit flash=0;        //时钟设置,闹钟设置闪烁标志位; =1闪烁
bit led=1;
uchar smg_state=0;  //数码管显示状态; =0显示时间; =1显示闹钟
void select573(uchar n)
{
	switch(n)
	{
		case 0:
			P2=(P2 & 0x1f) | 0x00;
		break;
		case 4:
			P2=(P2 & 0x1f) | 0x80;
		break;
		case 5:
			P2=(P2 & 0x1f) | 0xa0;
		break;
		case 6:
			P2=(P2 & 0x1f) | 0xc0;
		break;
		case 7:
			P2=(P2 & 0x1f) | 0xe0;
		break;
	}
}
void delaysmg(uchar t)
{
	while(t--);
}
void display_onesmg(uchar value,uchar pos)
{
	select573(7);
	P0=0xff;
	select573(6);
	P0=0x01 << pos;
	select573(7);
	P0=value;
}
void close_allsmg(uchar value)
{
	select573(6);
	P0=0xff;
	select573(7);
	P0=value;
}
void display_time()
{
	if((clock == 1) && (flash == 1))
	{
		display_onesmg(smgduanma[18],0);
		display_onesmg(smgduanma[18],1);
	}
	else
	{
		display_onesmg(smgduanma[time[2]/16],0);
		delaysmg(100);
		display_onesmg(smgduanma[time[2]%16],1);
		delaysmg(100);
	}
	  display_onesmg(smgduanma[16],2);
	  delaysmg(100);
	if((clock == 2) && (flash == 1))
	{
		display_onesmg(smgduanma[18],3);
		display_onesmg(smgduanma[18],4);
	}
	else
	{
		display_onesmg(smgduanma[time[1]/16],3);
		delaysmg(100);
		display_onesmg(smgduanma[time[1]%16],4);
		delaysmg(100);
	}
	  display_onesmg(smgduanma[16],5);
	  delaysmg(100);
	if((clock == 3) && (flash == 1))
	{
		display_onesmg(smgduanma[18],6);
		display_onesmg(smgduanma[18],7);
	}
	else
	{
		display_onesmg(smgduanma[time[0]/16],6);
		delaysmg(100);
		display_onesmg(smgduanma[time[0]%16],7);
		delaysmg(100);
	}
	close_allsmg(0xff);
}
void display_alarm()
{
	if((alarm == 1) && (flash == 1))
	{
		display_onesmg(smgduanma[18],0);
		display_onesmg(smgduanma[18],1);
	}
	else
	{
		display_onesmg(smgduanma[h/10],0);
		delaysmg(100);
		display_onesmg(smgduanma[h%10],1);
		delaysmg(100);
	}
	  display_onesmg(smgduanma[16],2);
	  delaysmg(100);
	if((alarm == 2) && (flash == 1))
	{
		display_onesmg(smgduanma[18],3);
		display_onesmg(smgduanma[18],4);
	}
	else
	{
		display_onesmg(smgduanma[m/10],3);
		delaysmg(100);
		display_onesmg(smgduanma[m%10],4);
		delaysmg(100);
	}
	  display_onesmg(smgduanma[16],5);
	  delaysmg(100);
	if((alarm == 3) && (flash == 1))
	{
		display_onesmg(smgduanma[18],6);
		display_onesmg(smgduanma[18],7);
	}
	else
	{
		display_onesmg(smgduanma[s/10],6);
		delaysmg(100);
		display_onesmg(smgduanma[s%10],7);
		delaysmg(100);
	}
	close_allsmg(0xff);
}
void display_temp()
{
	display_onesmg(smgduanma[temp/10],5);
	delaysmg(100);
	display_onesmg(smgduanma[temp%10],6);
	delaysmg(100);
  display_onesmg(smgduanma[12],7);
	delaysmg(100);
	close_allsmg(0xff);
}
void initsystem()  //初始化系统
{
	select573(4);
	P0=0xff;
	select573(5);
	P0=0x00;
	select573(0);
}
void set_time()    //设置时间
{
	uchar i=0;
	Write_Ds1302_Byte(0x8e,0x00);
	for(i=0;i<7;i++)
	{
		Write_Ds1302_Byte(write_address[i],time[i]);
	}
	Write_Ds1302_Byte(0x8e,0x80);
}
void read_time()   //读取DS1302上的时间
{
	uchar i=0;
	for(i=0;i<7;i++)
	{
		time[i]=Read_Ds1302_Byte(read_address[i]);
	}
}


void initt0()      //定时器0,方式一,50毫秒
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD = 0x11;		//设置定时器模式
	TL0 = (65535 - 50000) % 256;		//设置定时初值
	TH0 = (65535 - 50000) / 256;		//设置定时初值
	TF0 = 0;		    //清除TF0标志
	EA=1;
	ET0=1;
	TR0=0;
}
void servicet0() interrupt 1
{
	TL0 = (65535 - 50000) % 256;		
	TH0 = (65535 - 50000) / 256;		
	ms0++;
	if(ms0 % 4 == 0)     //定时0.2秒
	{
		led = ~led;
	}
	if(ms0 == 100)       //定时5秒
	{
		ms0=0;
		led=1;
		TR0=0;
		select573(4);
		P0=0xff;
		select573(0);
	}
}
void led_flash()   //闹钟时间led闪烁
{
	if((time[2] == h) && (time[1] == m) && (time[0] == s))
	{
		TR0=1;
	}
	select573(4);
	L1 = led;
}
void initt1()     //定时器1,方式一,50毫秒
{
	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD = 0x11;		//设置定时器模式
	TL1 = (65535 - 50000) % 256;		//设置定时初值
	TH1 = (65535 - 50000) / 256;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	EA=1;
	ET1=1;
	TR1 = 0;		//定时器1开始计时
}
void servicet1() interrupt 3
{
	TL1 = (65535 - 50000) % 256;		
	TH1 = (65535 - 50000) / 256;		
	ms1++;
	if(ms1 == 10)
	{
		flash = ~flash;
		ms1=0;
	}
}
void scanner_s7()
{
	if(s7 == 0)
	{
		delaysmg(100);
		if(s7 == 0)
		{
			TR0 = 0;
			led = 1;
			if(alarm == 0)
			{
				switch(clock)
				{
					case 0:
						clock=1;TR1=1;break;   //设置时,打开计时器1中断,
					case 1:
						clock=2;break;
					case 2:
						clock=3;break;
					case 3:
						clock=0;TR1=0;break;   //显示时间,关闭计时器1中断;
				}
			}
			while(s7 == 0)
			{
				display_time();
			}
		}
	}
}
void scanner_s6()
{
	if(s6 == 0)
	{
		delaysmg(100);
		if(s6 == 0)
		{
			TR0=0;
			led=1;
			if(clock == 0)
			{
				switch(alarm)
				{
					case 0:
						smg_state=1;;alarm=1;TR1=1;break;
					case 1:
						alarm=2;break;
					case 2:
						alarm=3;break;
					case 3:
						smg_state=0;alarm=0;TR1=0;break;
				}
				while(s6 == 0)
			{
				display_alarm();
			}
			}
		}
	}
}
void scanner_s5()
{
	if(s5 == 0)
	{
		delaysmg(100);
		if(s5 == 0)
		{
			TR0=0;
			led=1;
			if((clock != 0) && (smg_state == 0))
			{
				if(clock == 1)
				{
					time[2]++;
					if((time[2] / 16) * 10 + (time[2] % 16) == 24) {time[2]=0;}
				}
				else if(clock == 2)
				{
					time[1]++;
					if((time[1] / 16) * 10 + (time[1] % 16) == 60) {time[1]=0;}
				}
				else if(clock == 3)
				{
					time[0]++;
					if((time[0] / 16) * 10 + (time[0] % 16) == 60) {time[1]=0;}
				}
				while(s5 == 0)
				{
					display_time();
				}
				set_time();
			}
			if((alarm != 0) && (smg_state == 1))
			{
				if(alarm == 1)
				{
					h++;
					if(h == 24) {h=0;}
				}
				else if(alarm == 2)
				{
					m++;
					if(m == 60) {m=0;}
				}
				else if(alarm == 3)
				{
					s++;
					if(s == 60) {s=0;}
				}
				while(s5 == 0)
				{
					display_alarm();
				}
			}
		}
	}
}
void scanner_s4()
{
	if(s4 == 0)
	{
		delaysmg(100);
		if(s4 == 0)
		{
			TR0=0;
			led=1;
			 if((smg_state == 0) && (clock == 0))
			 {
				temp=read_temp();
				 while(s4 == 0)
				 {
				  display_temp();
				 }
			 }
			else if((smg_state == 0) && (clock != 0))
			{
				 if(clock == 1)
				 {
				  if(time[2] > 0)
				  {
					 time[2]--;
				  }
			  }
				else if(clock == 2)
			  {
				 if(time[1] > 0)
				 {
					time[1]--;
				 }
			 }
			 else if(clock == 3)
			 {
				 if(time[0] > 0)
				 {
					time[0]--;
				 }
			 }
			 while(s4 == 0)
			 {
				display_time();
			 }
			 set_time();
			}
			else if((smg_state == 1) && (alarm != 0))
			{
				if(alarm == 1)
				 {
				  if(h > 0)
				  {
					 h--;
				  }
			  }
				else if(alarm == 2)
			  {
				 if(m > 0)
				 {
					m--;
				 }
			 }
			 else if(alarm == 3)
			 {
				 if(s > 0)
				 {
					s--;
				 }
			 }
			 while(s4 == 0)
			 {
				 display_alarm();
			 }
			}
		}
	}
}
void main()
{
	initsystem();
	initt0();
	initt1();
	set_time();
	while(1)
	{
		if((smg_state == 0)&&(clock == 0))    //只在时钟显示时,读取当前时间
		{
			read_time();
		}
		switch(smg_state)
		{
			case 0:
				display_time();	   //显示时钟
				break;
			case 1:
				display_alarm();   //显示闹钟
				break;
		}
		scanner_s7();
		scanner_s6();
		scanner_s5();
		scanner_s4();
		led_flash();
	}
}


ds1302.h
#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 );
#endif


ds1302.c

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

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);			
}


owewire.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);
unsigned char read_temp();

#endif


onewire.c
#include "reg52.h"

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

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	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;
}
unsigned char read_temp()
{
	unsigned char low=0,higt=0;
	unsigned char T=0;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(1000);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	low=Read_DS18B20();
	higt=Read_DS18B20();
  T=(higt << 8) | low;
	if((T & 0xf800) == 0x0000)
	{
		T=T >> 4;
	}
	return T;
}





  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 蓝桥杯是全国性的计算机大赛,旨在提高大学生的计算机技术水平和创新能力。嵌入式STM32G431是一款嵌入式芯片,具有高性能和低功耗的特点。第十二届第一场省赛停车计费系统是蓝桥杯的一道工程题目,要求参赛选手设计一个停车场计费系统。 停车计费系统是指通过嵌入式技术实现对车辆进入和离开停车场的自动检测、计时和计费的系统。对于这个题目,参赛选手可以根据题目要求,使用STM32G431芯片设计一个具有以下功能的系统: 1. 车辆进入检测:使用车辆传感器检测车辆的进入,触发计时。 2. 车辆离开检测:使用车辆传感器检测车辆的离开,停止计时。 3. 计时功能:使用内部时钟模块获取进入和离开的时间,并计算停车时间。 4. 计费功能:根据停车时间,按照一定的计费规则进行计费。 5. 显示功能:使用液晶显示屏显示当前的停车信息,如车牌号、停车时间、费用等。 6. 数据存储功能:使用闪存等储存介质将停车数据进行存储,以便后续的数据分析和查询。 设计一个停车计费系统涉及到硬件设计和软件编程两个方面。硬件方面,参赛选手需要选择合适的传感器、显示屏、存储介质等,以及设计电路和接口进行连接。软件方面,需要使用C语言或者汇编语言编写程序,对芯片进行编程,实现各项功能。 通过此次比赛,选手们可以锻炼嵌入式系统的设计能力和编程能力,了解实际应用中嵌入式系统的工作原理和应用场景。同时,也能提升对STM32G431芯片的理解和运用能力。这对于培养嵌入式技术人才,推动物联网技术的发展都具有积极意义。 ### 回答2: 蓝桥杯是面向计算机爱好者的智力竞赛,而嵌入式STM32G431是一款嵌入式系统开发板。第十二届第一场省赛的停车计费系统真题工程,则是要求参赛选手设计并实现一个能够进行停车计费的系统。 停车计费系统是一种用于自动计费和管理停车场的系统。这个系统可以通过识别车辆的进出以及停车的时间,自动计算并收费。在这个工程中,选手需要使用嵌入式STM32G431开发板以及相关的硬件和软件,来设计一个能够实现停车计费功能的系统。 首先,选手需要使用传感器或摄像头来实现车辆进出的检测。当车辆进入或离开停车场时,传感器会发出信号并通过STM32G431进行检测。接着,选手需要编程实现识别车辆的算法,以便能够识别不同的车辆。当车辆停放时,系统会通过计时器记录停车的时间。 然后,选手需要编写计费算法,根据停车的时间来计算费用。这个算法可以根据停车场的规则来确定费用的计算方式,例如按小时计费或按照不同的时间段采用不同的费率。 最后,选手还需要设计一个界面,使得系统能够与用户进行交互。用户可以通过该界面查询停车费用,并进行付款。同时,选手还需要保证系统的稳定性和安全性,确保数据的准确性和保密性。 总而言之,蓝桥杯嵌入式STM32G431第十二届第一场省赛停车计费系统真题工程要求选手使用硬件和软件开发能力,设计并实现一个完整的停车计费系统。这需要选手具备嵌入式系统开发、传感器技术、算法设计和界面设计等多方面的知识和技能。 ### 回答3: 蓝桥杯嵌入式stm32g431——第十二届第一场省赛停车计费系统真题工程是一个基于STM32G431开发板的停车计费系统设计题目。该系统的主要功能是实现停车场的车辆进入、出场的计费管理。 首先,该系统需要实现一个车辆进入检测的功能。当车辆进入停车场时,系统会通过传感器检测到车辆的到达,并记录下进入的时间。 然后,系统需要实现一个车辆出场的功能。当车辆准备离开停车场时,系统会通过传感器检测到车辆的离开,并记录下离开的时间。 接下来,系统需要计算车辆停留的时间。通过进入时间和离开时间的差值计算得出车辆停留的时长。 最后,系统需要计算停车费用。根据停车场的计费规则,根据车辆停留的时长计算出停车费用,并将费用显示在屏幕上。 在实现上述功能的过程中,需要运用STM32G431开发板的各种功能和模块,包括GPIO口、定时器、中断、串口通信等。通过编写相应的代码,实现按钮的控制、传感器检测、时间的计算以及屏幕的显示等功能。 该项目的设计需要考虑多种情况,比如车辆重复进入出场、车辆进入出场顺序错乱等,要充分考虑这些异常情况并进行相应的处理。在代码编写过程中,还需注意代码的优化和资源的合理利用,以提高系统的性能和效率。 通过完成这个项目的设计与实现,可以加深对STM32G431嵌入式系统的了解和应用,并提升嵌入式系统开发的能力。同时,也能锻炼自己的逻辑思维、问题解决能力和团队合作精神。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值