蓝桥杯单片机组第12届国赛

//求最小值的时候把第一次测的值赋值给最小值,依次再作比较,这样防止定义最小值的时候为0,最小值一直为0的情况
//矩阵按键***************可以换成2×2(如果 data超出)********完美代码****************
//计算距离平均值的时候保留一位小数需要乘10,不在算出平均值的时候乘,直接对dsitance乘,这样可以把小数点后的一位显示出来
//=因为没有触发采集距离的时候,数据位不显示,但是平均值那个小数点会显示,所以加一个小数点标志位
//在参数界面下的采集时间设置界面2-4数码管显示了ad采集光照的值

题目如下

 代码

main函数:

//求最小值的时候把第一次测的值赋值给最小值,依次再作比较,这样防止定义最小值的时候为0,最小值一直为0的情况
//矩阵按键***************可以换成2×2(如果 data超出)********完美代码****************
//计算距离平均值的时候保留一位小数需要乘10,不在算出平均值的时候乘,直接对dsitance乘,这样可以把小数点后的一位显示出来
//=因为没有触发采集距离的时候,数据位不显示,但是平均值那个小数点会显示,所以加一个小数点标志位
//在参数界面下的采集时间设置界面2-4数码管显示了ad采集光照的值

#include "stc15f2k60s2.h"
#include "intrins.h"
#include "ds1302.h"	
#include "iic.h"

sbit h0=P3^0;
sbit h1=P3^1;
sbit h2=P3^2;
sbit h3=P3^3;
sbit l0=P4^4;
sbit l1=P4^2;
sbit l2=P3^5;
sbit l3=P3^4;

unsigned char code tab[]=
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff, //10(灭)
0xbf, //11(-)
0xfe, //12(上划)
0xf7, //13(下划)
0xc6, //14(C)
0x8e, //15(F)
0xc7,	//16(L)
0x89,	//17(H)
0x8c	//18(P)
};
unsigned char code keycode[4][4]={{7,11,15,19},{6,10,14,18},{5,9,13,17},{4,8,12,16}};
unsigned char keysta[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
unsigned char keybackup[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
unsigned char keybuff[4][4]={{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}};
unsigned char dscom=0;
unsigned char dsbuff[8];
unsigned char number=0;
unsigned char ym_mode=1;
unsigned char shuju_mode=1;
unsigned char canshu_mode=1;
unsigned char lcf_mode=1;
unsigned char value_mode=1;
unsigned char caijishijian=2;
unsigned char juli_canshu=20;
unsigned char l5_number=0;
unsigned char time_count=0;
unsigned char ad_value;
unsigned char ad_value_last;
unsigned char ad_count=0;
unsigned char da_count=0;
unsigned char csb_count=0;
unsigned char i=0;
unsigned int distance;
unsigned int distance_min;
unsigned int distance_max;
unsigned int n;

float distance_ave;
float y;

bit time_bit=0;
bit csb_bit=0;
bit ad_bit=0;
bit da_bit=0;
bit not_bit=0;

void yemian();
void keysong(unsigned char dat);
void keyaction(unsigned char dat);


void select573(channel)
{
	P2&=0x1f;
	P0=0xff;
	switch(channel)
	{
		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;
	}
}
void allinit()
{
	select573(4);P0=0xff;
	select573(5);P0=0x00;
	select573(6);P0=0xff;
	select573(7);P0=0xff;
}
void display()
{
	select573(7);P0=0xff;
	select573(6);
	P0=1<<dscom;
	select573(7);
	if(dscom==6 && ym_mode==1 && shuju_mode==3 && value_mode==2 && not_bit==1)
	{
		P0=tab[dsbuff[dscom]]&0x7f;
	}
	else
		P0=tab[dsbuff[dscom]];
		
	P2&=0x1f;
	P0=0xff;
	if(++dscom==8)
		dscom=0;
}

void timerinit()
{
	TMOD=0x00;
	TH1=(65536-1000)/256;
	TL1=(65536-1000)%256;
	TF1=0;
	ET1=1;
	EA=1;
	TR1=1;
	
	TH0=0;
	TL0=0;
	TF0=0;
	
}
//=============================按键函数========================================================================================================
//=============按键扫描================
void keyscan()
{
	unsigned char i;
	static unsigned char keyout=0;
	keybuff[keyout][0]=keybuff[keyout][0]<<1|l0;
	keybuff[keyout][1]=keybuff[keyout][1]<<1|l1;
	keybuff[keyout][2]=keybuff[keyout][2]<<1|l2;
	keybuff[keyout][3]=keybuff[keyout][3]<<1|l3;
	
	for(i=0;i<4;i++)
	{
		if((keybuff[keyout][i]&0x0f)==0)
		{
			keysta[keyout][i]=0;
		}
		else if((keybuff[keyout][i]&0x0f)==0x0f)
		{
			keysta[keyout][i]=1;
		}
	}
	keyout++;
	if(keyout>=4)
	{
		keyout=0;
	}	
	switch(keyout)
	{
		case 0:h0=0;h3=1;break;
		case 1:h1=0;h0=1;break;
		case 2:h2=0;h1=1;break;
		case 3:h3=0;h2=1;break;
	}
}
//=========按键处理====================
void key_handle()
{
	unsigned char i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			if(keybackup[i][j]!=keysta[i][j])
			{
				if(keysta[i][j]==0)
				{
					keyaction(keycode[i][j]);
				}
				else if(keysta[i][j]==1)
				{
					keysong(keycode[i][j]);
				}
				keybackup[i][j]=keysta[i][j];
			}
		}
	}
}
//=========按键按下====================

void keyaction(unsigned char dat)
{
	//=====S4=====界面按键=========
	if(dat==4) 
	{
		if(ym_mode==1)
		{
			ym_mode=2; //参数设置界面 
			canshu_mode=1; //从数据显示界面进入参数设置界面默认采集时间界面(P1)
		}         
		else if(ym_mode==2) 
		{
			ym_mode=1; //数据显示界面
			shuju_mode=1; //从参数设置界面进入数据显示界面默认时间数据显示界面
		}	
	}
	//=====S5=====切换按键=========
  if(dat==5)
	{
		if(ym_mode==1) //如果在数据显示界面
		{
			if(shuju_mode==1)
			{
				shuju_mode=2; //距离数据显示
			}
			else if(shuju_mode==2)
			{
				shuju_mode=3; //数据记录显示
				value_mode=1; //每次进入数据记录显示界面,默认当前显示为测距最大值
			}
			else if(shuju_mode==3)
			{
				shuju_mode=1; //时间数据显示
			}
		}
		else if(ym_mode==2) //如果在参数设置界面
		{
			if(canshu_mode==1)
			{
				canshu_mode=2; // P2--距离参数设置界面
			}
			else if(canshu_mode==2)
			{
				canshu_mode=1; // P1--采集时间设置界面
			}
		}
	}
	//=====S8=====模式按键=========
	if(dat==8)
	{
		if(ym_mode==1) //数据显示界面
		{
			if(shuju_mode==2) //距离数据显示
			{
				if(lcf_mode==1)
				{
					lcf_mode=2; // LF--定时模式
				}
				else if(lcf_mode==2)
				{
					lcf_mode=1; // LC--触发模式
				}
			}
			else if(shuju_mode==3) //数据记录显示
			{
				if(value_mode==1)
				{
					value_mode=2; // 平均值
				}
				else if(value_mode==2)
				{
					value_mode=3; // 最小值
				}
				else if(value_mode==3)
				{
					value_mode=1; // 最大值
				}
			}
		}
	}
	//=====S9=====调整按键=========
	if(dat==9)
	{
		if(ym_mode==2) //参数设置界面
		{
			if(canshu_mode==1) // P1--采集时间设置界面
			{
				if(caijishijian==2)      caijishijian=3;
				else if(caijishijian==3) caijishijian=5;
				else if(caijishijian==5) caijishijian=7;
				else if(caijishijian==7) caijishijian=9;
				else if(caijishijian==9) caijishijian=2;
			}
			else if(canshu_mode==2) // P2--距离参数设置界面
			{
				juli_canshu+=10;
				if(juli_canshu>80)
				{
					juli_canshu=10;
				}
			}
		}
	}
}
//============================超声波测距=======================================================================================================
sbit TX=P1^0;
sbit RX=P1^1;

void Delay12us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}
void send_wave()
{
	unsigned char i=0;
	for(i=0;i<8;i++)
	{
		TX=1;
		Delay12us();
		TX=0;
		Delay12us();
	}
}
void csb_ceju()
{
	unsigned int disttt;
	
	TH0=0;
	TL0=0;
	TF0=0;
	ET0=0;
	
	send_wave();
	TR0=1;
	while((RX==1)&&(TF0==0));
	TR0=0;
	disttt=TH0*256+TL0;
	if(TF0==0)
	{
		distance=disttt*0.017;
	}
	else
	{
		distance=999;
		TF0=0;
	}
		
	TH0=0;
	TL0=0;
	
}
//=========按键松开====================
void keysong(unsigned char dat)
{
	if(dat==4)
	{
		
	}
}
//=============================LED函数========================================================================================================
unsigned char led_number=0xff;
void led_handle()
{
	P0=0xff;
	select573(4);
	P0=led_number;
	P2&=0x1f;
}
void func_led()
{
	//==========L1=L2=L3=================
	if(ym_mode==1)
	{
		//==========L1==================
		if(shuju_mode==1)
		{
			led_number=led_number & 0xfe;
		}
		else
		{
			led_number=led_number | 0x01;
		}
		//==========L2==================
		if(shuju_mode==2)
		{
			led_number=led_number & 0xfd;
		}
		else
		{
			led_number=led_number | 0x02;
		}
		//==========L3==================
		if(shuju_mode==3)
		{
			led_number=led_number & 0xfb;
		}
		else
		{
			led_number=led_number | 0x04;
		}	
	}
	//==========L4======================
	if(lcf_mode==1)
	{
		led_number=led_number & 0xf7;
	}
	else
	{
		led_number=led_number | 0x08;
	}
	//==========L5======================
	if(distance>=(juli_canshu-5) && distance<=(juli_canshu+5) && lcf_mode==2)
	{
		l5_number++;
		if(l5_number>=3)
		{
			l5_number=0;
			led_number=led_number & 0xef;
		}
		else
		{
			led_number=led_number | 0x10;
		}
	}
	//==========L6======================
	if(ad_value>=80)
	{
		led_number=led_number & 0xdf;
	}
	else
	{
		led_number=led_number | 0x20;
	}
}
//=============================中断函数========================================================================================================
void timer()interrupt 3
{
	keyscan();
	yemian();
	display();
	led_handle();
	//============读取ds1302时间==============
	time_count++;
	if(time_count>=250)
	{
		time_count=0;
		time_bit=1;
	}
	//============测距离=====================================================
	if(ym_mode==1 && shuju_mode==2)
	{
		//=========定时模式=============
			if((((clk[0]/16)*10+clk[0]%16)%caijishijian==0)&&(lcf_mode==2))
			{
				csb_count++;
				if(csb_count>=200)
				{
					csb_bit=1;
					csb_count=0;
				}
			}
			else if((ad_value_last-ad_value)>30 &&lcf_mode==1)
			{
				csb_count++;
				if(csb_count>=200)
				{
					csb_bit=1;
					csb_count=0;
				}
			}		
	}
	//============ad采集光照=====================================================
	ad_count++;
	if(ad_count>=200)
	{
		ad_count=0;
		ad_bit=1;
	}
  //============da输出=====================================================
	da_count++;
	if(da_count>=200)
	{
		da_count=0;
		da_bit=1;
	}
}
//=============================main函数========================================================================================================
void main()
{
	allinit();
	timerinit();
	ds1302_init();
	while(1)
	{
		//=========读取ds1302时间============
		if(time_bit==1)
		{
			time_bit=0;
			ds1302_read();			
		}
		//=========超声波测距==============
		if(csb_bit==1)
		{
			//=因为没有触发采集距离的时候,数据位不显示,但是平均值那个小数点会显示,所以加一个小数点标志位
			not_bit=1;
			i++;
			csb_bit=0;
			csb_ceju();
			//=========把第一次测量的值赋值给最小值=和平均值========
			if(i==1)
			{
				distance_min=distance;
				distance_ave=distance;
			}
			//=========求出最大--最小--平均值=================================
			//=========最大
			if(distance>=distance_max)
			{
				distance_max=distance;
			}
			else
			{
				distance_max=distance_max;
			}
			//=========最小
			if(distance<=distance_min)
			{
				distance_min=distance;
			}	
			else
			{
				distance_min=distance_min;
			}
			//=========平均
			distance_ave=(((distance_ave*(i-1))+distance*10.0)/(i*1.0));
		}
		//=========采集adc光照==============
		if(ad_bit==1)
		{
			ad_value_last=ad_value;
			ad_bit=0;
			ad_value=pcf_ad(0x01);
		}
		//=========dac输出==============
		if(da_bit==1)
		{
			da_bit=0;
			if(distance<=10)
			{
				pcf_da(51);
			}
			else if(distance>=80)
			{
				pcf_da(255);
			}
			else
			{
				y=(0.057143*distance+0.42857)*51;
				pcf_da((unsigned char)(y));
			}
		}
		
		func_led();
		key_handle();
	}
}
//=========================页面函数============================================================================================================
unsigned char j=0;
void yemian()
{
	if(ym_mode==1) //数据显示界面
	{
		if(shuju_mode==1)//时间数据显示
		{
			dsbuff[0]=clk[2]/16;
			dsbuff[1]=clk[2]%16;
			dsbuff[2]=11;
			dsbuff[3]=clk[1]/16;
			dsbuff[4]=clk[1]%16;
			dsbuff[5]=11;
			dsbuff[6]=clk[0]/16;
			dsbuff[7]=clk[0]%16;
		}
		else if(shuju_mode==2)//距离数据显示
		{
			if(lcf_mode==1) // LC--触发模式
			{
				n=distance;
				dsbuff[0]=16;
				dsbuff[1]=14;
				dsbuff[2]=10;
				dsbuff[3]=10;
				dsbuff[4]=10;
//				dsbuff[5]=distance/100;
//				dsbuff[6]=distance/10%10;
//				dsbuff[7]=distance%10;
				dsbuff[5]=10;
				dsbuff[6]=10;
				dsbuff[7]=10;
				for(j=7;((j>3)&&(n!=0));j--)
				{
					dsbuff[j]=n%10;
					n=n/10;
				}
			}
			else if(lcf_mode==2) // LF--定时模式
			{
				n=distance;
				dsbuff[0]=16;
				dsbuff[1]=15;
				dsbuff[2]=10;
				dsbuff[3]=10;
				dsbuff[4]=10;
//				dsbuff[5]=distance/100;
//				dsbuff[6]=distance/10%10;
//				dsbuff[7]=distance%10;
				dsbuff[5]=10;
				dsbuff[6]=10;
				dsbuff[7]=10;
				for(j=7;((j>3)&&(n!=0));j--)
				{
					dsbuff[j]=n%10;
					n=n/10;
				}
			}
		}
		else if(shuju_mode==3)//数据记录显示
		{
			if(value_mode==1) // 最大值
			{
				n=distance_max;
				dsbuff[0]=17;
				dsbuff[1]=12;
				dsbuff[2]=10;
				dsbuff[3]=10;
				dsbuff[4]=10;
//				dsbuff[5]=distance_max/100;
//				dsbuff[6]=distance_max/10%10;
//				dsbuff[7]=distance_max%10;
				dsbuff[5]=10;
				dsbuff[6]=10;
				dsbuff[7]=10;
				for(j=7;((j>3)&&(n!=0));j--)
				{
					dsbuff[j]=n%10;
					n=n/10;
				}
			}
			else if(value_mode==2)// 平均值
			{
				n=(unsigned int)distance_ave;
				dsbuff[0]=17;
				dsbuff[1]=11;
				dsbuff[2]=10;
				dsbuff[3]=10;
//				dsbuff[4]=((unsigned int)distance_ave)/1000%10;
//				dsbuff[5]=((unsigned int)distance_ave)/100%10;
//				dsbuff[6]=((unsigned int)distance_ave)/10%10;
//				dsbuff[7]=((unsigned int)distance_ave)%10;		
				dsbuff[4]=10;
				dsbuff[5]=10;
				dsbuff[6]=10;
				dsbuff[7]=10;
				for(j=7;((j>3)&&(n!=0));j--)
				{
					dsbuff[j]=n%10;
					n=n/10;
				}
			}
			else if(value_mode==3) // 最小值
			{
				n=distance_min;
				dsbuff[0]=17;
				dsbuff[1]=13;
				dsbuff[2]=10;
				dsbuff[3]=10;
				dsbuff[4]=10;
//				dsbuff[5]=distance_min/100;
//				dsbuff[6]=distance_min/10%10;
//				dsbuff[7]=distance_min%10;
				dsbuff[5]=10;
				dsbuff[6]=10;
				dsbuff[7]=10;
				for(j=7;((j>3)&&(n!=0));j--)
				{
					dsbuff[j]=n%10;
					n=n/10;
				}
			}
		}
	}
	else if(ym_mode==2) //参数设置界面
	{
		if(canshu_mode==1)// P1--采集时间设置界面
		{
			dsbuff[0]=18;
			dsbuff[1]=1;
			dsbuff[2]=ad_value/100;
			dsbuff[3]=ad_value/10%10;
			dsbuff[4]=ad_value%10;
			dsbuff[5]=10;
			dsbuff[6]=caijishijian/10;
			dsbuff[7]=caijishijian%10;
		}
		else if(canshu_mode==2)// P2--距离参数设置界面
		{
			dsbuff[0]=18;
			dsbuff[1]=2;
			dsbuff[2]=10;
			dsbuff[3]=10;
			dsbuff[4]=10;
			dsbuff[5]=10;
			dsbuff[6]=juli_canshu/10;
			dsbuff[7]=juli_canshu%10;
		}
	}
}

ds1302函数

#include "ds1302.h"							
#include "intrins.h"
//
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST=P1^3;

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);			
}
unsigned char clk[3];
void ds1302_init()
{
	Write_Ds1302_Byte(0x8e,0x00);
	Write_Ds1302_Byte(0x80,0x01);
	Write_Ds1302_Byte(0x82,0x20);
	Write_Ds1302_Byte(0x84,0x13);
	Write_Ds1302_Byte(0x8e,0x80);
}
void ds1302_read()
{
	clk[2]=Read_Ds1302_Byte(0x85);
	clk[1]=Read_Ds1302_Byte(0x83);
	clk[0]=Read_Ds1302_Byte(0x81);
}

IIC函数

#include "iic.h"
#include "intrins.h"

#define DELAY_TIME	5


sbit scl=P2^0;
sbit sda=P2^1;
//
static void I2C_Delay(unsigned char n)
{
    do
    {
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_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);
}
unsigned char pcf_ad(unsigned channel)
{
	unsigned char adt;
	EA=0;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(channel);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	adt=I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	EA=1;
	return adt;
}
void pcf_da(unsigned char adt)
{
	EA=0;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x40);
	I2CWaitAck();
	I2CSendByte(adt);
	I2CWaitAck();
	EA=1;
	
}

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值