蓝桥杯单片机14届省赛

蓝桥杯单片机14届省赛代码(省一)
在这里插入图片描述

欢迎使用Markdown编辑器在这里插入图片描述

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

#include "HC138.h"
#include "PCF8591.h"
#include "onewire.h"
#include "ds1302.h"
sbit R1=P3^2;
sbit R2=P3^3;
sbit C1=P4^4;
sbit C2=P4^2;
unsigned char code Write_ADDR[3]={0x80,0x82,0x84};
unsigned char code Read_ADDR[3]={0x81,0x83,0x85};
unsigned char Time[3]={0},hour,fen,smg_count,F_ne;
unsigned char count_N,F_smg,mode,led_sta=0xff,S,T;
unsigned char para_T=30,T_max,S_max,times,sta;
float ave_T,ave_S;
unsigned int dat_f,count_f=0,sum_T,sum_S;
unsigned char F_error,key_count,key_sta,F_key,led_count,F_led;
unsigned char xdata S_dat[50]={0};
unsigned char xdata T_dat[50]={0};
unsigned char old_smg,old_mode,F_adc,adc_count,m,n,change_la,adc_value,old_adc;
void LED_control();

void DS1302_Write()
{
	int i;
	Write_Ds1302_Byte(0x8e,0x00);
	for(i=0;i<3;i++)
	{
		Write_Ds1302_Byte(Write_ADDR[i],Time[i]);
	}
	Write_Ds1302_Byte(0x8e,0x80);
}

void DS1302_Read()
{
	int i;
	for(i=0;i<3;i++)
	{
		Time[i]=Read_Ds1302_Byte(Read_ADDR[i]);
	}
}

void Display_Time()//时间界面
{
	DS1302_Read();
	SMG_bit(0,SMG_Duanma[Time[2]/16]);
	SMG_bit(1,SMG_Duanma[Time[2]/16]);
	SMG_bit(2,SMG_Duanma[15]);
	SMG_bit(3,SMG_Duanma[Time[1]/16]);
	SMG_bit(4,SMG_Duanma[Time[1]%16]);
	SMG_bit(5,SMG_Duanma[15]);
	SMG_bit(6,SMG_Duanma[Time[0]/16]);
	SMG_bit(7,SMG_Duanma[Time[0]%16]);

	
void Display_C()//回显界面--温度
{
	SMG_bit(0,SMG_Duanma[10]);
	if(times==0)
	{
		SMG_close();
	}
	else 
	{
		SMG_bit(2,SMG_Duanma[T_max/10]);
		SMG_bit(3,SMG_Duanma[T_max%10]);
		SMG_bit(4,SMG_Duanma[15]);
		SMG_bit(5,SMG_Duanma[(int)(ave_T*10)/100]);
		SMG_bit(6,SMG_Duanma_Dot[(int)(ave_T*10)/10%10]);
		SMG_bit(7,SMG_Duanma[(int)(ave_T*10)%10]);
	}
}

void Display_H()//回显界面--湿度
{
	SMG_bit(0,SMG_Duanma[11]);
	if(times==0)
	{
		SMG_close();
	}
	else
	{
		SMG_bit(2,SMG_Duanma[S_max/10]);
		SMG_bit(3,SMG_Duanma[S_max%10]);
		SMG_bit(4,SMG_Duanma[15]);
		SMG_bit(5,SMG_Duanma[(int)(ave_S*10)/100]);
		SMG_bit(6,SMG_Duanma_Dot[(int)(ave_S*10)/10%10]);
		SMG_bit(7,SMG_Duanma[(int)(ave_S*10)%10]);
	}
}

void Display_F()//回显界面--时间
{
	SMG_bit(0,SMG_Duanma[12]);
	if(times==0)
	{
		SMG_close();
	}
	else
	{
		SMG_bit(1,SMG_Duanma[times/10]);
		SMG_bit(2,SMG_Duanma[times%10]);
		SMG_bit(3,SMG_Duanma[hour/16]);
		SMG_bit(4,SMG_Duanma[hour%16]);
		SMG_bit(5,SMG_Duanma[15]);
		SMG_bit(6,SMG_Duanma[fen/16]);
		SMG_bit(7,SMG_Duanma[fen%16]);
	}
}

void Display_P()//参数界面
{
	SMG_bit(0,SMG_Duanma[13]);
	SMG_bit(6,SMG_Duanma[para_T/10]);
	SMG_bit(7,SMG_Duanma[para_T%10]);
}

void Display_E()//温湿度界面
{
	SMG_bit(0,SMG_Duanma[14]);
	SMG_bit(3,SMG_Duanma[T/10]);
	SMG_bit(4,SMG_Duanma[T%10]);
	SMG_bit(5,SMG_Duanma[15]);
	if(F_error)
	{
		SMG_bit(6,SMG_Duanma[16]);
		SMG_bit(7,SMG_Duanma[16]);
	}
	else
	{
		SMG_bit(6,SMG_Duanma[S/10]);
		SMG_bit(7,SMG_Duanma[S%10]);
	}
}

void Display()//数码管显示
{
	if(F_smg==0)
	{
		Display_Time();
	}
	else if(F_smg==1)
	{
		if(mode==0)
		{
			Display_C();
		}
		else if(mode==1)
		{
			Display_H();
		}
		else
		{
			Display_F();
		}
	}
	else if(F_smg==2)
	{
		Display_P();
	}
	else 
	{
		Display_E();
	}
}

void Dat_Collect()
{
	if(F_ne)//NE555读取
	{
		F_ne=0;
		dat_f=count_f;
		count_f=0;
	}
	if(F_adc)//ADC读取---200ms
	{
		F_adc=0;
		if(sta==0)
		{
			Read_AIN(1);
			old_adc=Read_AIN(1);
			sta=1;
		}
		else if(change_la==0)
		{
			Read_AIN(1);
			adc_value=Read_AIN(1);
			if(adc_value<127&&old_adc>127)//亮--->暗
			{
				change_la=1;
				times++;
				hour=Time[2];
				fen=Time[1];
				T=Read_T();
				T_dat[m++]=T;
				sum_T+=T;ave_T=sum_T/(float)(m);//平均值--温度
				T_max=T>T_max?T:T_max;//最大值--温度
				if(dat_f>=200&&dat_f<=2000)
				{
					F_error=0;
					S=(2*dat_f+50)/45.0;//湿度与NE555
					S_dat[n++]=S;
					sum_S+=S;ave_S=sum_S/(float)(n);//平均值--湿度
					S_max=S>S_max?S:S_max;//最大值--湿度
				}
				else
				{
					F_error=1;//无效数据标志
				}			
				old_smg=F_smg;old_mode=mode;	
				F_smg=3;
			}
			old_adc=adc_value;//本次数据--->上次数据
		}
	}
}

void Key_scan()
{
	R1=R2=1;
	C1=0,C2=1;
	if(R2==0)		//S4
	{
		Delay(250);
		if(R2==0)
		{
			if(F_smg==0)
			{
				mode=0;
				F_smg=1;
			}
			else if(F_smg==1)
			{
				F_smg=2;
			}
			else if(F_smg==2)
			{
				F_smg=0;
			}
		}
		while(R2==0)
		{
			Display();
			Dat_Collect();
			LED_control();
		}
	}
	else if(R1==0)		//S5
	{
		Delay(250);
		if(R1==0)
		{
			if(F_smg==1)
			{
				if(mode==0)
				{
					mode=1;
				}
				else if(mode==1)
				{
					mode=2;
				}
				else
				{
					mode=0;
				}
			}			
		}
		while(R1==0)
		{
			Display();
			Dat_Collect();
			LED_control();
		}
	}
	
	R1=R2=1;
	C1=1,C2=0;
	if(R2==0)		//S8
	{
		Delay(250);
		if(R2==0)
		{
			if(F_smg==2)
			{
				para_T++;
				if(para_T>99)
				{
					para_T=99;
				}
			}
		}
		while(R2==0)
		{
			Display();
			Dat_Collect();
			LED_control();
		}
	}
	else if(R1==0)		//S9
	{
		Delay(250);
		if(R1==0)
		{
			if(F_smg==2)
			{
				para_T--;
				if(para_T==255)
				{
					para_T=0;
				}
				while(R1==0)
				{
					Display();
					Dat_Collect();
					LED_control();
				}
			}
			else if(F_smg==1)
			{
				if(mode==2)
				{
					key_sta=1;//按键状态--按下
					while(R1==0)
					{
						Display();
						Dat_Collect();
						LED_control();
					}
					key_sta=0;
					key_count=0;
					if(F_key)//数据清除,长按键
					{
						times=0,sum_S=0,sum_T=0;
						n=0,m=0;
						Clear(S_dat);
						Clear(T_dat);
					}
					F_key=0;
				}
			}				
		}
	}
}

void LED_control()
{
	if(F_smg==0)
	{
		led_sta=(led_sta&0xfe)|0x06;
	}
	else if(F_smg==1)
	{
		led_sta=(led_sta&0xfd)|0x05;
	}
	else if(F_smg==3)
	{
		led_sta=(led_sta&0xfb)|0x03;
	}
	else
	{
		led_sta|=0x07;
	}
	
	if(T>para_T)
	{
		if(F_led)
		{
			F_led=0;
			led_sta^=0x08;
		}	
	}
	else
	{
		led_sta|=0x08;
	}
	
	if(F_error)
	{
		led_sta&= ~0x10;
	}
	else
	{
		led_sta|=0x10;
	}
	if(times>=2)
	{
		if(S_dat[n-1]>S_dat[n-2]&&T_dat[m-1]>T_dat[m-2])
		{
			led_sta&=~0x20;
		}
		else
		{
			led_sta|=0x20;
		}
	}
	HC138set(4,led_sta);
}

void T1_service() interrupt 3
{
	if(++count_N==20)
	{
		count_N=0;
		F_ne=1;
	}
	if(key_sta)
	{
		if(++key_count>40)
		{
			key_count=0;
			key_sta=0;
			F_key=1;
		}
	}
	if(++led_count==2)
	{
		led_count=0;
		F_led=1;
	}
	if(++adc_count==4)
	{
		adc_count=0;
		F_adc=1;
	}
	if(F_smg==3)
	{
		if(++smg_count>60)
		{
			smg_count=0;
			F_smg=old_smg;
			mode=old_mode;
			change_la=0;
		}
	}
}

void T0_service() interrupt 1
{
	count_f++;
}

void main()
{
	Sys_init();
	Read_T();
	Delay750ms();
	DS1302_Write();
	while(1)
	{
		Key_scan();
		Dat_Collect();
		LED_control();
		Display();	
	}
}

HC138.c

#include "HC138.h"
unsigned char code SMG_Duanma[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
0xf8,0x80,0x90,0xc6,0x89,0x8e,0x8c,0x86,0xbf,0x88};
unsigned char code SMG_Duanma_Dot[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,
0x78,0x00,0x10};
void HC138set(unsigned char n,unsigned char dat)
{
	P0=dat;
	switch(n)
	{
		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;
	}
	P2=(P2&0x1f)|0x00;
}

void Delay(unsigned int time)
{
	while(time--);
}

void SMG_bit(unsigned char pos,unsigned char value)
{
	HC138set(7,0xff);
	HC138set(6,0x01<<pos);
	HC138set(7,value);
	Delay(400);
}

void T_init()
{
	TMOD=0x06;
	TH1=(65536-50000)/256;
	TL1=(65536-50000)%256;
	TH0=0xff;
	TL0=0xff;
	TR1=1;
	TR0=1;
	ET0=1;
	ET1=1;
	EA=1;
}

void Sys_init()
{
	HC138set(4,0xff);
	HC138set(5,0xaf);
	HC138set(6,0xff);
	HC138set(7,0xff);
	T_init();
}

void Clear(unsigned char a[])
{
	int i;
	for(i=0;i<50;i++)
		a[i]=0;
}

void SMG_close()
{
	SMG_bit(2,SMG_Duanma[0xff]);
	SMG_bit(3,SMG_Duanma[0xff]);
	SMG_bit(4,SMG_Duanma[0xff]);
	SMG_bit(5,SMG_Duanma[0xff]);
	SMG_bit(6,SMG_Duanma[0xff]);
	SMG_bit(7,SMG_Duanma[0xff]);
}

HC138.h

#ifndef _HC138_H
#define _HC138_H
#include <STC15F2K60S2.h>
extern unsigned char code SMG_Duanma[17];
extern unsigned char code SMG_Duanma_Dot[10];
void HC138set(unsigned char n,unsigned char dat);
void Delay(unsigned int time);
void SMG_bit(unsigned char pos,unsigned char value);
void T_init();
void Clear(unsigned char a[]);
void Sys_init();
void SMG_close();
#endif

onewire.c

/*	# 	单总线代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/

#include "onewire.h"
void Delay_OneWire(unsigned int t)  
{
	while(t--);
}

//
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(35);
		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(35);
	}
	return dat;
}

//
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	//DQ = 1;
  	//Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(400);
  	DQ = 1;
  	Delay_OneWire(20); 
    initflag = DQ;     
  	Delay_OneWire(100);
  
  	return initflag;
}

unsigned int Read_T()
{
	unsigned int T_dat;
	unsigned char LSB,MSB;
	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0x44);
	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0xBE);
	LSB=Read_DS18B20();
	MSB=Read_DS18B20();
	init_ds18b20();
	T_dat=(MSB<<8)|LSB;
	T_dat>>=4;
	return T_dat;
}

void Delay750ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 35;
	j = 51;
	k = 182;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

onewire.h

#ifndef _ONEWIRE_H
#define _ONEWIRE_H
#include <STC15F2K60S2.h>
#include <intrins.h>
sbit DQ=P1^4;
void Delay_OneWire(unsigned int t);  
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
unsigned int Read_T();
void Delay750ms();
#endif

ds1302.c

/*	# 	DS1302代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/								

#include "ds1302.h"
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);			
}


ds1302.h

#ifndef _DS1302_H
#define _DS1302_H
#include <STC15F2K60S2.h>
#include <intrins.h>
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST=P1^3;
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

PCF8591.c

#include "PCF8591.h"
unsigned char Read_AIN(unsigned char m)
{
	unsigned char tem;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x00|m);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	tem=I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return tem;
}

PCF8591.h

#ifndef _PCF8591_H
#define _PCF8591_H
#include "iic.h"
unsigned char Read_AIN(unsigned char m);
#endif

iic.c

/*	#   I2C代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/

#include "iic.h"
#define DELAY_TIME	5
void I2C_Delay(unsigned char n)
{
    do{_nop_();}
    while(n--);      	
}

//
void I2CStart(void)
{
    sda = 1;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 0;
	I2C_Delay(DELAY_TIME);
    scl = 0;    
}

//
void I2CStop(void)
{
    sda = 0;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 1;
	I2C_Delay(DELAY_TIME);
}

//
void I2CSendByte(unsigned char byt)
{
    unsigned char i;
	
    for(i=0; i<8; i++){
        scl = 0;
		I2C_Delay(DELAY_TIME);
        if(byt & 0x80){
            sda = 1;
        }
        else{
            sda = 0;
        }
		I2C_Delay(DELAY_TIME);
        scl = 1;
        byt <<= 1;
		I2C_Delay(DELAY_TIME);
    }
	
    scl = 0;  
}

//
unsigned char I2CReceiveByte(void)
{
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++){   
		scl = 1;
		I2C_Delay(DELAY_TIME);
		da <<= 1;
		if(sda) 
			da |= 0x01;
		scl = 0;
		I2C_Delay(DELAY_TIME);
	}
	return da;    
}

//
unsigned char I2CWaitAck(void)
{
	unsigned char ackbit;
	
    scl = 1;
	I2C_Delay(DELAY_TIME);
    ackbit = sda; 
    scl = 0;
	I2C_Delay(DELAY_TIME);
	
	return ackbit;
}

//
void I2CSendAck(unsigned char ackbit)
{
    scl = 0;
    sda = ackbit; 
	I2C_Delay(DELAY_TIME);
    scl = 1;
	I2C_Delay(DELAY_TIME);
    scl = 0; 
	sda = 1;
	I2C_Delay(DELAY_TIME);
}

iic.h

#ifndef _IIC_H
#define _IIC_H
#include <STC15F2K60S2.h>
#include <intrins.h>
sbit sda=P2^1;
sbit scl=P2^0;
void I2C_Delay(unsigned char n);
void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
unsigned char I2CWaitAck(void);
void I2CSendAck(unsigned char ackbit);
#endif
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值