第八届蓝桥杯单片机省赛----程序题

第八届蓝桥杯单片机省赛----程序题_第1张图片
第八届蓝桥杯单片机省赛----程序题_第2张图片

第八届蓝桥杯单片机省赛----程序题_第3张图片
第八届蓝桥杯单片机省赛----程序题_第4张图片
第八届蓝桥杯单片机省赛----程序题_第5张图片

main.c程序

#include
#include "ds18b20.h"
#include 

#define uchar unsigned char   //定义无符号字符类型uchar
#define uint unsigned int     //定义无符号整型类型uint

uchar code tab[]={
     0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc6};
uchar yi,er,san,si,wu,liu,qi,ba;   //定义字符型变量yi,er,san,si,wu,liu,qi,ba,当作数码管显示控制变量
extern unsigned char shijian[];

uchar s7=5,s6=0,s4=0,wendu=0,LED_kai=0;
uchar naozhong[3]={
     0,0,0};
uint miao=0,tt=0;
bit fla=0;

void delayms(int ms);          //延时函数
void allinit();                //初始化函数
void keyscan();                //独立按键函数
void display1(uchar yi,uchar er);   //第一、二段数码管函数
void display2(uchar san,uchar si);  //第三、四段数码管函数
void display3(uchar wu,uchar liu);  //第五、六段数码管函数
void display4(uchar qi,uchar ba);   //第七、八段数码管函数
void Timer0Init(void);		//5毫秒@11.0592MHz

void main()//主函数
{
     
	allinit();                  //初始化函数
	DS_init();
	Timer0Init();
	while(1)
	{
     
		DS_get();
		if(wendu==0)
		{
     
			if(s7==5)
			{
     
				yi=shijian[2]/10;er=shijian[2]%10;san=10;si=shijian[1]/10;wu=shijian[1]%10;liu=10;qi=shijian[0]/10;ba=shijian[0]%10;    //显示时钟页面
			}
			else if(s7==1)
			{
     
				if(shijian[0]%2==0){
     yi=shijian[2]/10;er=shijian[2]%10;san=10;si=shijian[1]/10;wu=shijian[1]%10;liu=10;qi=shijian[0]/10;ba=shijian[0]%10;}    //时钟时选中页面
				else {
     yi=11;er=11;}
			}
			else if(s7==2)
			{
     
				if(shijian[0]%2==0){
     yi=shijian[2]/10;er=shijian[2]%10;san=10;si=shijian[1]/10;wu=shijian[1]%10;liu=10;qi=shijian[0]/10;ba=shijian[0]%10;}    //时钟分选中页面
				else {
     si=11;wu=11;}
			}
			else if(s7==3)
			{
     
				if(shijian[0]%2==0){
     yi=shijian[2]/10;er=shijian[2]%10;san=10;si=shijian[1]/10;wu=shijian[1]%10;liu=10;qi=shijian[0]/10;ba=shijian[0]%10;}    //时钟秒选中页面
				else {
     qi=11;ba=11;}
			}
			
			if(s6==5)
			{
     
				yi=naozhong[2]/10;er=naozhong[2]%10;san=10;si=naozhong[1]/10;wu=naozhong[1]%10;liu=10;qi=naozhong[0]/10;ba=naozhong[0]%10;;    //显示闹钟页面
			}
			else if(s6==1)
			{
     
				if(shijian[0]%2==0){
     yi=naozhong[2]/10;er=naozhong[2]%10;san=10;si=naozhong[1]/10;wu=naozhong[1]%10;liu=10;qi=naozhong[0]/10;ba=naozhong[0]%10;}    //闹钟时选中页面
				else {
     yi=11;er=11;}
			}
			else if(s6==2)
			{
     
				if(shijian[0]%2==0){
     yi=naozhong[2]/10;er=naozhong[2]%10;san=10;si=naozhong[1]/10;wu=naozhong[1]%10;liu=10;qi=naozhong[0]/10;ba=naozhong[0]%10;}    //闹钟分选中页面
				else {
     si=11;wu=11;}
			}
			else if(s6==3)
			{
     
				if(shijian[0]%2==0){
     yi=naozhong[2]/10;er=naozhong[2]%10;san=10;si=naozhong[1]/10;wu=naozhong[1]%10;liu=10;qi=naozhong[0]/10;ba=naozhong[0]%10;}    //闹钟秒选中页面
				else {
     qi=11;ba=11;}
			}
		}
		else if(wendu==1)
		{
     
			yi=11;er=11;san=11;si=11;wu=11;liu=Tempget()/10;qi=Tempget()%10;ba=12;   //温度显示页面
		}
		if((shijian[0]==naozhong[0])&&(shijian[1]==naozhong[1])&&(shijian[2]==naozhong[2]))  //判断时钟时分秒是否跟闹钟时分秒重合
		{
     
			LED_kai=1;tt=0;miao=0;  //是的话打开L1灯
		}
		
		keyscan();                //独立按键函数
		display1(yi,er);          //第一、二段数码管函数
		display2(san,si);         //第三、四段数码管函数
		display3(wu,liu);         //第五、六段数码管函数
		display4(qi,ba);          //第七、八段数码管函数
	}
}
void keyscan()//独立按键函数
{
     
	if(P30==0)       //判断P30是否等于0
	{
     
		delayms(5);    //延时5ms
		if(P30==0)     //再次判断P30是否等于0 
		{
     
			if(LED_kai==0)    //非闹钟提醒状态下
			{
     
				if(s7==0){
     s7=5;s6=0;}    //按键按下切换相应状态,这里有按键按下s6清零,方便显示时钟页面
				else if(s7==5){
     s7=1;}    //按键按下切换相应状态,进入时钟时选中页面
				else if(s7==1){
     s7=2;}    //按键按下切换相应状态,进入时钟分选中页面
				else if(s7==2){
     s7=3;}    //按键按下切换相应状态,进入时钟秒选中页面
				else if(s7==3){
     s7=5;}    //按键按下切换相应状态,进入时钟显示页面
			}
			else if(LED_kai==1)    //闹钟提醒状态下,按键按下则关L1灯
			{
     
				LED_kai=0;P2=0X80;P0=0XFF;
			}
		}
		while(!P30);   //如果按键不松开,则一直循环
	}
	else if(P31==0)  //判断P31是否等于0
	{
     
		delayms(5);    //延时5ms
		if(P31==0)     //再次判断P31是否等于0 
		{
     
			if(LED_kai==0)    //非闹钟提醒状态下
			{
     
				if(s6==0){
     s6=5;s7=0;}    //按键按下切换相应状态,这里有按键按下s6清零,方便显示闹钟页面  
				else if(s6==5){
     s6=1;}    //按键按下切换相应状态,进入闹钟时选中页面
				else if(s6==1){
     s6=2;}    //按键按下切换相应状态,进入闹钟分选中页面
				else if(s6==2){
     s6=3;}    //按键按下切换相应状态,进入闹钟秒选中页面
				else if(s6==3){
     s6=5;}    //按键按下切换相应状态,进入闹钟显示页面
			}
			else if(LED_kai==1)    //闹钟提醒状态下,按键按下则关L1灯
			{
     
				LED_kai=0;P2=0X80;P0=0XFF;
			}
		}
		while(!P31);   //如果按键不松开,则一直循环
	}
	else if(P32==0)  //判断P32是否等于0
	{
     
		delayms(5);    //延时5ms
		if(P32==0)     //再次判断P32是否等于0 
		{
     
			if(LED_kai==0)    //非闹钟提醒状态下
			{
     
				if(s7==1)      
				{
     
					if(shijian[2]==23)shijian[2]=23;//判断时钟时是否大于等于23,是的话时还是等于23
					else shijian[2]++;              //否则时钟时进行加一
					DS_init();                      //初始化时钟
				}
				else if(s7==2)
				{
     
					if(shijian[1]==59)shijian[1]=59;//判断时钟分是否大于等于59,是的话分还是等于59
					else shijian[1]++;              //否则时钟分进行加一
					DS_init();                      //初始化时钟
				}
				else if(s7==3)
				{
     
					if(shijian[0]==59)shijian[0]=59;//判断时钟秒是否大于等于59,是的话秒还是等于59
					else shijian[0]++;              //否则时钟秒进行加一
					DS_init();                      //初始化时钟
				}
				if(s6==1)
				{
     
					if(naozhong[2]==23)naozhong[2]=23;//判断闹钟时是否大于等于23,是的话时还是等于23
					else naozhong[2]++;               //否则闹钟时进行加一
				}
				else if(s6==2)
				{
     
					if(naozhong[1]==59)naozhong[1]=59;//判断闹钟分是否大于等于59,是的话分还是等于59
					else naozhong[1]++;               //否则闹钟分进行加一
				}
				else if(s6==3)
				{
     
					if(naozhong[0]==59)naozhong[0]=59;//判断闹钟秒是否大于等于59,是的话秒还是等于59
					else naozhong[0]++;               //否则闹钟秒进行加一
				}
			}
			else if(LED_kai==1)    //闹钟提醒状态下,按键按下则关L1灯
			{
     
				LED_kai=0;P2=0X80;P0=0XFF;
			}
		}
		while(!P32);   //如果按键不松开,则一直循环
	}
	else if(P33==0)  //判断P33是否等于0
	{
     
		delayms(5);    //延时5ms
		if(P33==0)     //再次判断P33是否等于0 
		{
     
			s4=1;        	//按键按下s4置1
			if(s7==5)wendu=1;   //判断是否是在始终显示状态下按键,是的话显示温度页面
		}
	}
	else if((s4==1)&&(P33==1))   //判断s4是否等于1且按键抬起
	{
     
		s4=0;            //s4置0,为下次按键按下做准备
		wendu=0;         //温度不显示
		if(LED_kai==0)    //非闹钟提醒状态下
		{
     
			if(s7==1)      
			{
     
				if(shijian[2]==0)shijian[2]=0;//判断时钟时是否大于等于0,是的话时还是等于0
				else shijian[2]--;              //否则时钟时进行减一
				DS_init();                      //初始化时钟
			}
			else if(s7==2)
			{
     
				if(shijian[1]==0)shijian[1]=0;//判断时钟分是否大于等于0,是的话分还是等于0
				else shijian[1]--;              //否则时钟分进行减一
				DS_init();                      //初始化时钟
			}
			else if(s7==3)
			{
     
				if(shijian[0]==0)shijian[0]=0;//判断时钟秒是否大于等于0,是的话秒还是等于0
				else shijian[0]--;              //否则时钟秒进行减一
				DS_init();                      //初始化时钟
			}
			if(s6==1)
			{
     
				if(naozhong[2]==0)naozhong[2]=0;//判断闹钟时是否大于等于0,是的话时还是等于0
				else naozhong[2]--;               //否则闹钟时进行减一
			}
			else if(s6==2)
			{
     
				if(naozhong[1]==0)naozhong[1]=0;//判断闹钟分是否大于等于0,是的话分还是等于0
				else naozhong[1]--;               //否则闹钟分进行减一
			}
			else if(s6==3)
			{
     
				if(naozhong[0]==0)naozhong[0]=0;//判断闹钟秒是否大于等于0,是的话秒还是等于0
				else naozhong[0]--;               //否则闹钟秒进行减一
			}
		}
		else if(LED_kai==1)    //闹钟提醒状态下,按键按下则关L1灯
		{
     
			LED_kai=0;P2=0X80;P0=0XFF;
		}
	}
}
void Timer0Init(void)		//5毫秒@11.0592MHz
{
     
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x28;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA=1;ET0=1;
}
void time0() interrupt 1  //定时器中断函数
{
     
	tt++,miao++;
	if((tt==40)&&(LED_kai==1))//判断计时是否到了0.2s并且LED_kai等于1
	{
     
		tt=0;           //tt置0
		if(fla==0){
     fla=1;P2=0X80;P0=0XFE;}        //判断fla是否等于0,是的话L1开,fla置1
		else if(fla==1){
     fla=0;P2=0X80;P0=0XFF;}   //判断fla是否等于1,是的话L1关,fla置0
	}
	if(miao==1000)    //定义5秒钟
	{
     
		LED_kai=0;      //LED_kai标志位置0
		miao=0;         //秒置0
		P2=0X80;P0=0XFF;//关闭LED灯
	}
}
void delayms(int ms)//延时函数
{
     
	uint i,j;
	for(i=ms;i>0;i--)
		for(j=845;j>0;j--);
}
void allinit()//初始化函数
{
     
	P2=0XA0;P0=0X00;      //关闭蜂鸣器继电器
	P2=0X80;P0=0XFF;      //关闭所有LED灯
	
	P2=0XC0;P0=0XFF;      //选中所有数码管段选
	P2=0XFF;P0=0XFF;      //关闭所有数码管
}
void display1(uchar yi,uchar er)//第一、二段数码管函数
{
     
	P2=0XC0;P0=0X01;               //选中第一个数码管位选
	P2=0XFF;P0=tab[yi];            //让第一个数码管显示yi指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X02;               //选中第二个数码管位选
	P2=0XFF;P0=tab[er];            //让第一个数码管显示er指向的值
	delayms(1);	                   //延时1ms
}
void display2(uchar san,uchar si)//第三、四段数码管函数
{
     
	P2=0XC0;P0=0X04;               //选中第s三个数码管位选
	P2=0XFF;P0=tab[san];           //让第一个数码管显示san指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X08;               //选中第四个数码管位选
	P2=0XFF;P0=tab[si];            //让第一个数码管显示si指向的值
	delayms(1);	                   //延时1ms
}
void display3(uchar wu,uchar liu)//第五、六段数码管函数
{
     
	P2=0XC0;P0=0X10;               //选中第五个数码管位选
	P2=0XFF;P0=tab[wu];            //让第一个数码管显示wu指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X20;               //选中第六个数码管位选
	P2=0XFF;P0=tab[liu];           //让第一个数码管显示liu指向的值
	delayms(1);	                   //延时1ms
}
void display4(uchar qi,uchar ba)//第七、八段数码管函数
{
     
	P2=0XC0;P0=0X40;               //选中第七个数码管位选
	P2=0XFF;P0=tab[qi];            //让第一个数码管显示qi指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X80;               //选中第八个数码管位选
	P2=0XFF;P0=tab[ba];            //让第一个数码管显示ba指向的值
	delayms(1);                    //延时1ms
	P2=0XC0;P0=0X80;               //选中第八个数码管位选
	P2=0XFF;P0=0XFF;               //让第八个数码管熄灭             
}

ds1302.c程序

#include
#include 
#include 


unsigned char shijian[]={
     50,59,23,0,0,0,0};

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

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

void Write_Ds1302( unsigned char address,unsigned char dat )     
{
     
 	RST=0;
	_nop_();
 	SCK=0;
	_nop_();
 	RST=1;	
   	_nop_();  
 	Write_Ds1302_Byte(address);	
 	Write_Ds1302_Byte((dat/10<<4)|(dat%10));		
 	RST=0; 
}

unsigned char Read_Ds1302 ( unsigned char address )
{
     
 	unsigned char i,temp=0x00,dat1,dat2;
 	RST=0;
	_nop_();
 	SCK=0;
	_nop_();
 	RST=1;
	_nop_();
 	Write_Ds1302_Byte(address);
 	for (i=0;i<8;i++) 	
 	{
     		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;
	_nop_();
 	RST=0;
	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 DS_init()
{
     
	unsigned char add,i;
	add=0x80;
	Write_Ds1302(0x8e,0x00);
	for(i=0;i<7;i++)
	{
     
		Write_Ds1302(add,shijian[i]);
		add=add+2;
	}
	Write_Ds1302(0x8e,0x80);
}
void DS_get()
{
     
	unsigned char add,i;
	add=0x81;
	Write_Ds1302(0x8e,0x00);
	for(i=0;i<7;i++)
	{
     
		shijian[i]=Read_Ds1302(add);
		add=add+2;
	}
	Write_Ds1302(0x8e,0x80);
}

ds18b20.c程序

#include
#include "ds18b20.h"

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

//单总线延时函数
void Delay_OneWire(unsigned int 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(50);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(50);
}

//从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(50);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
     
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(120);
  	DQ = 0;
  	Delay_OneWire(800);
  	DQ = 1;
  	Delay_OneWire(100); 
    	initflag = DQ;     
  	Delay_OneWire(50);
  
  	return initflag;
}
unsigned char Tempget()
{
     
	unsigned char temp,low,high;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(200);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	low=Read_DS18B20();
	high=Read_DS18B20();
	
	temp=high<<4;
	temp|=(low>>4);
	
	return temp;
}

ds1302.h程序

#ifndef __DS1302_H
#define __DS1302_H

void Write_Ds1302_Byte(unsigned  char temp);
void Write_Ds1302( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302 ( unsigned char address );
void DS_init();
void DS_get();

#endif

ds18b20.h程序

#ifndef __DS18B20_H
#define __DS18B20_H

//单总线延时函数
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
unsigned char Tempget();

#endif

在这里插入图片描述

第八届蓝桥杯单片机省赛作品演示

你可能感兴趣的:(《蓝桥杯》系列,蓝桥杯,单片机)