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

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
main.c程序

#include<stc15f2k60s2.h>
#include "ds18b20.h"
#include <ds1302.h>

#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};//数字0~9,“-”“关”
uchar yi,er,san,si,wu,liu,qi,ba;   //定义字符型变量yi,er,san,si,wu,liu,qi,ba,当作数码管显示控制变量

extern unsigned char shijian[];   //调用DS1302定义的时间数组

uchar wendu,shezhi=0,jiange=1,s4=0;	
uint tt=0;
uchar Save[10],Save_n=0;
bit fla=0,LED_shan=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();             //初始化DS1302
	Timer0Init();          //初始化定时器0
	while(1)
	{
    
    
		wendu=Tempget();   //获取温度
		if(shezhi==0)      //参数设置页面
		{
    
    
			yi=11;er=11;san=11;si=11;wu=11;liu=10;qi=jiange/10;ba=jiange%10;   //显示间隔
		}
		else if(shezhi==1)   //时钟显示页面
		{
    
    
			DS_get();		
			yi=shijian[2]/10;er=shijian[2]%10;
			si=shijian[1]/10;wu=shijian[1]%10;
			qi=shijian[0]/10;ba=shijian[0]%10;
			if(shijian[0]%10%2==0){
    
    san=10;liu=10;}  //判断秒是奇数还是偶数,用来让数码管三、六位间隔闪烁
			else{
    
    san=11;liu=11;}
		}
		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(shezhi==3)shezhi=0;  //判断此时是否在第三个页面,也就是说采集到的10个数据均已在数码管上显示完毕,按键后返回到参数设置页面   
		}
		while(!P30);   //如果按键不松开,则一直循环
	}
	else if(P31==0)  //判断P31是否等于0
	{
    
    
		delayms(5);    //延时5ms
		if(P31==0)     //再次判断P31是否等于0 
		{
    
    
			if(shezhi==2){
    
    LED_shan=0;P2=0X80;P0=0XFF;}   //判断此时是否在第二个页面,也就是10个参数采集过后,L1灯亮起,按键后L1熄灭,数码管循环显示采集到的10个数据 
		}
		while(!P31);   //如果按键不松开,则一直循环
	}
	else if(P32==0)  //判断P32是否等于0
	{
    
    
		delayms(5);    //延时5ms
		if(P32==0)     //再次判断P32是否等于0 
		{
    
    
			if(shezhi==0){
    
    shezhi=1;tt=0;}   //判断在设置页面下按键是否按下,按下后进入到时钟显示页面,并开始采集数据
		}
		while(!P32);   //如果按键不松开,则一直循环
	}
	else if(P33==0)  //判断P33是否等于0
	{
    
    
		delayms(5);    //延时5ms
		if(P33==0)     //再次判断P33是否等于0 
		{
    
    
			if(shezhi==0)
			{
    
    
				if(jiange==1)jiange=5;           //判断间隔是否在1s上,如果是按键按下后间隔改为5s
				else if(jiange==5)jiange=30;     //判断间隔是否在5s上,如果是按键按下后间隔改为30s
				else if(jiange==30)jiange=60;    //判断间隔是否在30s上,如果是按键按下后间隔改为60s
				else if(jiange==60)jiange=1;     //判断间隔是否在60s上,如果是按键按下后间隔改为1s
			}
		}
		while(!P33);   //如果按键不松开,则一直循环
	}
}
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++;
	if((tt==jiange*200)&&(shezhi==1))
	{
    
    
		tt=0;
		Save[Save_n]=wendu;
		Save_n++;
		if(Save_n==10)
		{
    
    
			shezhi=2;LED_shan=1;Save_n=0;
			yi=10;er=0;san=0;si=11;wu=11;liu=11;qi=Save[0]/10;ba=Save[0]%10;
		}
	}
	
	if((tt==200)&&(shezhi==2))
	{
    
    
		tt=0;
		if(LED_shan==1)
		{
    
    
			if(fla==0){
    
    fla=1;P2=0X80;P0=0XFE;}
			else if(fla==1){
    
    fla=0;P2=0X80;P0=0XFF;}
		}
		else if(LED_shan==0)
		{
    
    
			yi=10;er=Save_n/10;san=Save_n%10;si=11;wu=11;liu=11;qi=Save[Save_n]/10;ba=Save[Save_n]%10;
			Save_n++;
			if(Save_n==10)
			{
    
    
				Save_n=0;shezhi=3;
			}
		}
	}
}
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<stc15f2k60s2.h>
#include <intrins.h>
#include <ds1302.h>

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

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

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<stc15f2k60s2.h>
#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 low,high,temp;
	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

在这里插入图片描述

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

猜你喜欢

转载自blog.csdn.net/qq_45385706/article/details/115178357