【蓝桥杯单片机学习】第13届第一场省赛

程序

        由于参加的是第二场比赛,第一场的试题就当做拿来练手,写的较为仓促应该有不少的bug,如果有哪里写的不好的地方、哪里写错得地方欢迎指出,积极改正!!

hex文件

程序hex文件,可以上板看看效果!!

main.c

#include "main.h"
#include "seg.h"
#include "onewire.h"
#include "ds1302.h"  
#include "key.h"
#include "isr.h"
uchar key_num=0;
uchar temp_sz_wd=23,key12_flag=0,key13_flag=0,zd_flag=0,relay_flag=0;
uchar led_buff=0xff;
uchar temp_sec,temp_min,temp_hour;
uint temp_wd;
void main()
{
	Sys_Init();  								//系统初始化
	set_time();									//DS1302初始化
	Timer0Init();
	Timer1Init();
	read_time();
//	temp_wd=rd_temperature();
	while(1)
	{
		key_num=key_scan();				//按键扫描
//		if(temp_wd!=0)
//		{
			switch(key12_flag)
			{
				case 0:display_wd();break; 
				case 1:display_sj();break;
				case 2:display_sz();break;
				default:break;
			}
//		}
		if(key_num==12)						//如果S12按下
		{
			key12_flag++;
			key12_flag=key12_flag%3;
		}
		if(key_num==13)						//如果S13按下
		{
			key13_flag++;
			key13_flag=key13_flag%2;
		}
		if(key_num==16&&key12_flag==2)//如果S16按下且在参数设置界面
		{
			temp_sz_wd++;
			if(temp_sz_wd>99)
				temp_sz_wd=99;
		}
		if(key_num==17&&key12_flag==2)//如果S17按下且在参数设置界面或时间显示
		{
			temp_sz_wd--;
			if(temp_sz_wd<10)
				temp_sz_wd=10;
		}
		if(key13_flag==0)							//如果S13标志位为0即温度控制模式
		{
			if((led_buff&0X02)==0X02)		//LED2点亮
			{
				led_buff=led_buff&~0X02; 
				Y4; 	P0=led_buff;	Y0; 
			}		
			if(temp_wd>temp_sz_wd*10)		//如果实际温度大于温度阈值
				relay_open();							//锁存器打开
			else	
				relay_close();						//锁存器关闭
		}
		else if(key13_flag==1)				//如果S13标志位为1即时间控制模式
		{	
			if((led_buff&0X02)==0X00)		//LED2熄灭
			{
				led_buff=led_buff|0X02; 
				Y4;	P0=led_buff;	Y0; 
			}
			if(temp_min==0&temp_sec==0)	//整点判断
			{
				zd_flag=2;								
				TR0 = 1;									//定时器0开始5s计时
			}	
		}
		if(zd_flag==2)
		{
			if((led_buff&0X01)==0X01)		//时间控制模式下整点时打开LED1
			{
				led_buff=led_buff&~0X01; 
				Y4; P0=led_buff;	Y0; 
			}
			relay_open();								//时间控制模式下整点时打开锁存器
		}
	}
}
void display_sz()									//参数设置显示
{
	seg_one(0,25);seg_one(1,3);
	seg_one(6,temp_sz_wd/10);
	seg_one(7,temp_sz_wd%10);
}
void display_sj()									//时间显示
{
	seg_one(0,25);seg_one(1,2);
	seg_one(2,16);
	seg_one(3,temp_hour/10);
	seg_one(4,temp_hour%10);
	seg_one(5,17);
	seg_one(6,temp_min/10);
	seg_one(7,temp_min%10);
}
void display_wd()									//温度显示
{
	seg_one(0,25);seg_one(1,1);
	seg_one(5,temp_wd/100%10);
	seg_one(6,temp_wd/10%10+32);
	seg_one(7,temp_wd%10);
}
void Sys_delay(uint t)						//1us延时
{
	while(t--);
}
void Sys_Init()										//初始化
{
	Y4; P0=0XFF; Y0;
	Y5; P0=0X00; Y0;
	Y6; P0=0X00; Y0;
}

main.h

#ifndef _MAIN_H_
#define _MAIN_H_

#include "STC15F2K60S2.h"

#define uchar unsigned char 		//偷懒
#define uint unsigned int
	
#define Y0 P2=(P2&0x1f)|0x00;		//偷懒
#define Y1 P2=(P2&0x1f)|0x20;
#define Y2 P2=(P2&0x1f)|0x40;
#define Y3 P2=(P2&0x1f)|0x60;
#define Y4 P2=(P2&0x1f)|0x80;
#define Y5 P2=(P2&0x1f)|0xA0;
#define Y6 P2=(P2&0x1f)|0xC0;
#define Y7 P2=(P2&0x1f)|0xE0;

void Sys_Init();
void Sys_delay(uint t);
void display_wd();
void display_sj();
void display_sz();
#endif

key.c

#include "key.h"
#include "ds1302.h" 
#include "seg.h"
extern uchar key12_flag,zd_flag;
extern uchar temp_sec,temp_min,temp_hour;
extern uchar led_buff;
uchar key_scan()
{
	uchar key_num=0;
	P32=1;P33=1;P34=0;P35=0;
	if(P32==0||P33==0)
	{
		Sys_delay(10);
		if(P32==0||P33==0)
		{
			if(P32==0)
			{
				P32=0;P33=0;P34=1;P35=1;
				if(P34==0||P35==0)
				{
					Sys_delay(10);
					if(P34==0||P35==0)
					{
						if(P34==0)
						{
							key_num=17;
							if(key12_flag==1)
							{
								while(P34==0)
								{
									read_time();
									seg_one(0,25);seg_one(1,2);
									seg_one(2,16);
									seg_one(3,temp_min/10);
									seg_one(4,temp_min%10);
									seg_one(5,17);
									seg_one(6,temp_sec/10);
									seg_one(7,temp_sec%10);
									if(temp_min==0&&temp_sec==0)
									{
										zd_flag=1;	
									}
									if(zd_flag==1)
									{		
										if((led_buff&0X01)==0X01)
										{
											led_buff=led_buff&~0x01; 
											Y4; P0=led_buff; Y0;
										}
										relay_open();
										TR0 = 1;		//定时器0开始计时
										zd_flag=2;
									}
									if(zd_flag==2)
									{
										if((led_buff&0X01)==0X01)
										{
											led_buff=led_buff&~0X01; 
										}
										Y4; P0=led_buff;	Y0; 
									}
								}
							}
							else
								while(P34==0);
						}
						if(P35==0)
						{
							key_num=13;
							while(P35==0);
						}
					}
				}
			}
			else if(P33==0)
			{
				P32=0;P33=0;P34=1;P35=1;
				if(P34==0||P35==0)
				{
					Sys_delay(10);
					if(P34==0||P35==0)
					{
						if(P34==0)
						{
							key_num=16;
							while(P34==0);
						}
						if(P35==0)
						{
							key_num=12;
							while(P35==0);
						}
					}
				}
			}
		}
		else 
			key_num=0;
	}
	return key_num;
}

isr.c

#include "isr.h"
#include "seg.h"
#include "onewire.h"
#include "ds1302.h"  	
extern uchar temp_sec,temp_min,temp_hour;
extern uchar zd_flag,relay_flag;
extern uchar led_buff;
extern uint temp_wd;
void Timer0Init(void)		//20毫秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xE0;		//设置定时初值
	TH0 = 0xB1;		//设置定时初值
	TF0 = 0;		//清除TF0标志
//	TR0 = 1;		//定时器0开始计时
	EA = 1 ;
	ET0 = 1;
} 
void Timer_service() interrupt 1
{
	uchar cnt;
	cnt++;
	if(cnt==50*5)			//定时5s
	{
		zd_flag=0;
		cnt=0;
		TR0=0; 
		if((led_buff&0X01)==0X00)
			led_buff=led_buff|0X01; 
		Y4;P0=led_buff;Y0; 
		if((led_buff&0X04)==0X00)
			led_buff=led_buff|0X04;
		Y4;P0=led_buff;Y0; 
		relay_close();
		P34=1;
		

	}
}
void Timer1Init(void)		//20毫秒@12.000MHz
{
	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xE0;		//设置定时初值
	TH1 = 0xB1;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	EA = 1 ;
	ET1 = 1;
}
void Timer1_service() interrupt 3
{
		uint relay_cnt,ds1302_cnt,ds18b20_cnt;
		ds1302_cnt++;
		ds18b20_cnt++;
		if(ds1302_cnt==50)			//1s读一次时间
		{
//			read_time();
//			ds1302_cnt=0;
		}
		if(ds18b20_cnt==50)		  //0.5读一次温度
		{
			read_time();
			temp_wd=rd_temperature();
			ds18b20_cnt=0;
		}
		if(relay_flag==1)
		{
			relay_cnt++;
			if(relay_cnt==2)			//锁存器打开时LED3以100ms翻转
			{
				relay_cnt=0;
				if((led_buff&0X04)==0X04)
				{
					led_buff=led_buff&~0X04;
					Y4;	P0=led_buff;	Y0;
				}
				else if((led_buff&0X04)==0X00)
				{
					led_buff=led_buff|0X04;
					Y4;	P0=led_buff;	Y0;
				}
				
			}
		}
}

ds1302.c

#include "ds1302.h"  									

uchar read_1302_add[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
uchar write_1302_add[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
//uchar TIME[7]={0,25,23,23,4,6,22};
uchar TIME[7]={40,59,23,28,4,6,22};
extern uchar temp_sec,temp_min,temp_hour;
//写字节
void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK = 0;
		SDA = temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

//向DS1302寄存器写入数据
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; 
}

//从DS1302寄存器读出数据
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);			
}
void set_time()
{
	uchar i;;
	Write_Ds1302_Byte(0x8E,0X00);
	for(i=0;i<7;i++)
	{
		Write_Ds1302_Byte(write_1302_add[i],DEC_BCD(TIME[i]));
	}
	Write_Ds1302_Byte(0x8E,0X80);
}

void read_time()
{
	temp_sec=BCD_DEC(Read_Ds1302_Byte(read_1302_add[0]));
	temp_min=BCD_DEC(Read_Ds1302_Byte(read_1302_add[1]));
	temp_hour=BCD_DEC(Read_Ds1302_Byte(read_1302_add[2]));
}
uchar BCD_DEC(uchar dat)
{
	return((dat>>4)*10+(dat&0x0f));
}
uchar DEC_BCD(uchar dat)
{
	return((dat/10<<4)|(dat%10));
}

seg.c

#include "seg.h"
extern uchar relay_flag;
extern uchar led_buff;
/*************  本地常量声明    **************/
uchar code t_display[]={                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

		
void seg_one(uchar wei,dat)
{
	Y6; P0=0X01<<wei; Y0;
	Y7; P0=~t_display[dat]; Sys_delay(300); P0=0XFF; Y0;
}
void relay_open()
{
	Y5; P0=(P0&0xaf)|0x10; Y0;
	relay_flag=1;
}
void relay_close()
{
	Y5; P0=P0&0Xaf; Y0; //1010 0000
	relay_flag=0;
	if((led_buff&0X04)==0X00)
	{
		led_buff=led_buff|0X04;
		Y4;	P0=led_buff;	Y0;
	}
}

onewire.c

#include "onewire.h"
#include "seg.h"
extern uint temp_wd;
extern uchar key12_flag;
//单总线内部延时函数
void Delay_OneWire(unsigned int t)  
{
	t=t*12;
	while(t--);
}

//单总线写操作
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);
}

//单总线读操作
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;
}
uint rd_temperature(void)
{
	uint temp_h,temp_l;
	float temp;
	init_ds18b20();
	if(key12_flag==0)
	{
		display_wd();
	}
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(200);
	
//	display_wd();
	do{
	init_ds18b20();
	if(key12_flag==0)
	{
		display_wd();
	}
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	temp_l=Read_DS18B20();
	temp_h=Read_DS18B20();
	temp=temp_h<<8|temp_l;
	temp=temp*0.0625*10;
	}while(temp == 850);		//小bug,为了跳过初始显示85
	
	return temp;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值