蓝桥杯第十一届国赛完整无BUG版

文章描述了一个使用8051单片机的项目,涉及DS18B20温度传感器数据获取、DS1302实时时钟设置以及IIC通信。程序中展示了初始化、读写通信及中断处理等关键部分。
摘要由CSDN通过智能技术生成

写了三个小时,中间有点浪费了,个人感觉这套题刷下来还是很爽的,一些小细节处理得当会使得调试过程也大大省力,最后两百行内解决了~~~

(三个外设及以上似乎已经成为了标配)

#include <STC15F2K60S2.H>
#include <intrins.h>
#include "o.h"
#include "i.h"
#include "t.h"
u16 dif=0;
u8 liangdu=0;
u8 flag_d=0,flag_p=0;
u16 fenya=0;
u8 set1=17,set2=25,set3=4;
u8 set4=17,set5=25;set6=4;
u8 key=0,keys=0;
u8 hour=0,min=0,second=0;
u8 jiemian=0,shuju=0,canshu=0;
u16 temp=0;
u8 a[8]={10,10,10,10,10,10,10,10};
u8 k1(void)
{
	 u8 ret=0,hang=0,lie=0;
   P3=0x0f;P44=0;P42=0;
	 if(P30==0)hang=1;
	 if(P31==0)hang=2;
	 if(P32==0)hang=3;
	 if(P33==0)hang=4;
	 P3=0xf0;P44=1;P42=1;
	 if(P44==0)lie=1;
	 if(P42==0)lie=2;
	 if(P35==0)lie=3;
	 if(P34==0)lie=4;
	 if(lie!=0)ret=4*lie+(4-hang);
	 return ret;
}
u8 k2(void)
{
	 static u8 sta=0;
   u8 ret=0,val=0;val=k1();
	 keys=val;
	 switch(sta)
	 {
		 case 0:if(val!=0)sta=1;break;
		 case 1:if(val!=0){ret=val;sta=2;}else sta=0;break;
		 case 2:if(val==0)sta=0;break;
		 default:break;
	 
	 }
	 return ret;
}
void ctrl(u8 ctrl)
{
  P2=(ctrl<<5)|(P2&0x1f);
  P2=P2&0x1f;
}
void xianshi(u8 site,u8 light)
{
	P0=0xff;ctrl(7);
	P0=0x01<<site;ctrl(6);
	switch(light%20)
	{
		case 0:P0=0xc0;break;
		case 1:P0=0xf9;break;
		case 2:P0=0xa4;break;
		case 3:P0=0xb0;break;
		case 4:P0=0x99;break;
		case 5:P0=0x92;break;
		case 6:P0=0x82;break;
		case 7:P0=0xf8;break;
		case 8:P0=0x80;break;
		case 9:P0=0x90;break;
		case 10:P0=0xff;break;
		case 11:P0=0xbf;break;//-
    case 12:P0=0xc6;break;//c
    case 13:P0=0x8c;break;//p
    case 14:P0=0x86;break;//e
		default:break;
	}
	if(light>=20)P0=P0&0x7f;
  ctrl(7);

}
void get(u8 a0,u8 a1,u8 a2,u8 a3,u8 a4,u8 a5,u8 a6,u8 a7)
{a[0]=a0;a[1]=a1;a[2]=a2;a[3]=a3;a[4]=a4;a[5]=a5;a[6]=a6;a[7]=a7;}
	
void Timer2_Init(void)		//1000??@12.000MHz
{
	AUXR &= 0xFB;			//?????12T??
	T2L = 0x18;				//???????
	T2H = 0xFC;				//???????
	AUXR |= 0x10;			//???2????
	IE2 |= 0x04;			//?????2??
	EA=1;
}
void celiang(void)
{
	 if(flag_p%10==0){key=k2();}
	 if(flag_p%100==0){fenya=pcfad();}
   if(flag_p%152==0){temp=wendu();temp=temp*25/4;}

}

void main()
{
	P0=0x00;ctrl(5);
	P0=0xff;ctrl(4);
	shijian(16,59,50);
	Timer2_Init();
	while(1)
	{
	celiang();
	if(key==4){key=0;jiemian++;jiemian=jiemian%2;}
	if(jiemian==0)
	{
	set1=set4;set2=set5;set3=set6;
  if(key==5){key=0;shuju++;shuju=shuju%3;}
	if(shuju==0)get(hour/10,hour%10,11,min/10,min%10,11,second/10,second%10);
	if(shuju==1)get(12,10,10,10,10,temp/1000,temp%1000/100+20,temp%100/10);
	if(shuju==2)get(14,10,fenya/100+20,fenya%100/10,fenya%10,10,10,fenya<225);
	}
	if(jiemian==1)
	{
  if(key==5){key=0;canshu++;canshu=canshu%3;}
	if(canshu==0)
  {
	if(key==8&&set4>0)set4--;
	if(key==9&&set4<23)set4++;
	key=0;
	get(13,1,10,10,10,10,set4/10,set4%10);
	}
	if(canshu==1)
  {
	if(key==8&&set5>0)set5--;
	if(key==9&&set5<99)set5++;
	key=0;
	get(13,2,10,10,10,10,set5/10,set5%10);
	}
	if(canshu==2)
  {
	if(key==8&&set6>4)set6--;
	if(key==9&&set6<8)set6++;
	key=0;
	get(13,3,10,10,10,10,10,set6);
	}	
	}

	
	}

}

void Timer2_Isr(void) interrupt 12
{
	flag_d++;flag_d=flag_d%8;
	flag_p++;if(flag_p==200)
	{
		flag_p=0;
		hour=bcdtodec(Read_Ds1302_Byte(0x85));
		min=bcdtodec(Read_Ds1302_Byte(0x83));
		second=bcdtodec(Read_Ds1302_Byte(0x81));
	}
	xianshi(flag_d,a[flag_d]);
	if(liangdu!=(fenya<225)){if(dif>=3000)liangdu=(fenya<225);else dif++;}
	else dif=0;
	P0=~(((((hour>=set1)||(hour<=7))|((temp/100<set2)<<1))|(1<<(set3-1)))|(liangdu<<2));
	ctrl(4);
	
}


其他的.c,.h全部放这了

#include "o.h"
#include "reg52.h"
sbit DQ = P1^4;  //?????

//???????
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t=t*12;
	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;
}
u16 wendu(void)
{
   u16 ret=0;u8 low=0,high=0;
	 init_ds18b20();
	 Write_DS18B20(0xcc);
	 Write_DS18B20(0x44);
	 init_ds18b20();
	 Write_DS18B20(0xcc);
	 Write_DS18B20(0xbe);
	 low=Read_DS18B20();
	 high=Read_DS18B20();
	 ret=(high<<8)|low;
	 return ret;
}

#include "o.h"
#include "reg52.h"
sbit DQ = P1^4;  //?????

//???????
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t=t*12;
	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;
}
u16 wendu(void)
{
   u16 ret=0;u8 low=0,high=0;
	 init_ds18b20();
	 Write_DS18B20(0xcc);
	 Write_DS18B20(0x44);
	 init_ds18b20();
	 Write_DS18B20(0xcc);
	 Write_DS18B20(0xbe);
	 low=Read_DS18B20();
	 high=Read_DS18B20();
	 ret=(high<<8)|low;
	 return ret;
}

/*
  ????: DS1302????
  ????: Keil uVision 4.10 
  ????: CT107????????? 8051,12MHz
  ?    ?: 2011-8-9
*/
#include "t.h"
#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);			
}
void shijian(u8 hour,u8 min,u8 second)
{
  Write_Ds1302_Byte( 0x8e,0x00 );     
	Write_Ds1302_Byte( 0x80,dectobcd(second) );   
	Write_Ds1302_Byte( 0x82,dectobcd(min) );  
	Write_Ds1302_Byte( 0x84,dectobcd(hour) );  
	Write_Ds1302_Byte( 0x8e,0x80 );   

}
#ifndef _T_H
#define _T_H
#define dectobcd(dec) dec/10*16+dec%10
#define bcdtodec(bcd) bcd/16*10+bcd%16
#include "o.h"
void shijian(u8 hour,u8 min,u8 second);
u8 Read_Ds1302_Byte ( unsigned char address );
#endif
/*
  ????: IIC??????
  ????: Keil uVision 4.10 
  ????: CT107????????? 8051,12MHz
  ?    ?: 2011-8-9
*/
#include "i.h"
#include "reg52.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//??????
sbit SDA = P2^1;  /* ??? */
sbit SCL = P2^0;  /* ??? */

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//??????
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//??????
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//????
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:??,1:???
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//????
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//??I2C??????
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}

//?I2C???????
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
    return da;    
}

u16 pcfad(void)
{
	float zhongzhuan=0;
	u16 ret=0;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x41);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	ret=IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	zhongzhuan=ret*100/51;
	ret=(int)zhongzhuan;
	return ret;

}
#ifndef _I_H
#define _I_H
#include "o.h"
u16 pcfad(void);
#endif

 爽~

  • 13
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值