蓝桥杯13届第2场(51单片机)

题目是超声波测量可能大家比较陌生,这也是省赛第一次出,如果知道这个模块的话还是比较简单的(跟其他模块也差不多)然后下面 就贴代码了 。想要源码的工程文件可以去博主的资源中下载(免费)点点关注就行。

一.先看主函数

#include "config.h"
#include "iic.h"
void main()
{  
	 Init_System();//初始化
	while(1){
	if(flag_v) //电压采集标志位
	{ 
		
		 flag_v=0;
	   sum_v= read_adc()*1.96;  //电压采集
		if(sum_v>(param_min*10)&&sum_v<(param_max*10)) //电压在参数之间
			   flag_wave=1; //启用超声波功能
		else flag_wave=0;
		
		
		if(flag_wave) 
		{ 
	
		  wave= wave_recv();  //测距
			if(wave<=20)dac_out(1*51); 
			else if(wave>=20&&wave<=80)dac_out((wave*0.067-0.034)*51);
			else dac_out(255);
		}
		else dac_out(0);
	
		
	}
		
	scan_kbd();//扫描键盘
	key_real(); //按键功能
	SMG_show();  //数码管赋值
	
	
}
}

二.配置文件

#include "config.h"
#include "intrins.h"
unsigned char key_num=16;
unsigned char segbuff[8]={0};
unsigned int count_v=0;//电压采集计数
bit flag_v=0 ;//电压可以采集标志
unsigned int sum_v=0; //采集的电压数据
unsigned int param_max=30; //参数电压上限
unsigned int param_min=15;  //参数电压下限
unsigned int min_old=15;    //设置的参数下限
unsigned int max_old=30;    //设置的参数上限
unsigned int wave=10;     //超声波距离
unsigned char mod1=0; //界面切换
unsigned char mod2=0;  //模式切换
bit flag_wave=0;//超声波可以采集标志
unsigned int count_w=0;
unsigned char segtab[]={0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff, //Ϩİ -10
0xc1,  //U     -11
0xc0&0x7f,0xf9&0x7f,0xa4&0x7f,0xb0&0x7f,0x99&0x7f,0x92&0x7f,
0x82&0x7f,0xf8&0x7f,0x80&0x7f,0x90&0x7f,0x8c,0xc7,0x88
};


void Timer0Init(void)		//12??@12.000MHz
{
	//12T  12ms
	AUXR &= 0x7F;		
	TMOD &= 0xF0;		
	TL0 = 0xF4;		
	TH0 = 0xFF;
	TF0 = 0;		
	TR0 = 1;		
}

unsigned char wave_recv()
{
	unsigned char ucdist,num=10;
	TX=0;
	TL0=0xf4;
	TH0=0xff;
	TR0=1;
	//发送40Khz频率
	while(num--)
	{
		while(!TF0);
		TX^=1;
		TF0=0;
	}
	TR0=0;
	TL0=0;
	TH0=0;
	TR0=1;
	while(RX&&!TF0);
	TR0=0;
	if(TF0) //定时器溢出
	{
		TF0=0;
		ucdist=255;
	}
	else  //测距成功
		ucdist=((TH0<<8)+TL0)*0.017;
	return ucdist;
}

void time0 (void)		//1??@12.000MHz
{ 
	
	//1T 1ms
	AUXR &= 0xBF;		
	TMOD &= 0x0F;	
	TL1 = 0x18;	
	TH1 = 0xFC;		
	TF1 = 0;		
	TR1 = 1;		
	EA = 1;
	ET1= 1;
}


void Timer0() interrupt 3
{

	TL1 = 0x18;		
	TH1 = 0xFC;	
  segs();  //刷新数码管
  count_v++;  //采集电压计数
	count_w++;
	if(count_v==300) 0.3s采集一次
	{
	  count_v=0;
		 flag_v=1;  //可以采集
	}
	led_work();  //led灯


}
void segs()
{
	
	static unsigned char wei=0;
	P2=P2&0x1f|0xe0;
	P0=0xff;
	
	P2=P2&0x1f|0xc0;
	P0=1<<wei;
	P2=P2&0x1f|0xe0;
	P0=segtab[segbuff[wei]];
	if(++wei==8)wei=0;
	
}

void scan_kbd()  
{
   static unsigned char state=0;
	 unsigned char key_press;
	switch(state)
	{
		case state_0:
			kbd_io=0x0f;
		key_press=kbd_io;
		if(key_press!=kbd_maskrow)
			state=state_1;
		break;
		
		case state_1:
			key_press=kbd_io;
		if(key_press!=kbd_maskrow)
		{
		  if((kbd_io&0x08)==0)key_num=0;  //S4
			if((kbd_io&0x04)==0)key_num=1;  //S5
			if((kbd_io&0x02)==0)key_num=2;  //S6
			if((kbd_io&0x01)==0)key_num=3;   //S7
		 state=state_2;
		
		
		}
		else state=state_0;
		break;
		
		
		case state_2:
			
	  kbd_io=0x0f;
		key_press=kbd_io;
		if(key_press==kbd_maskrow)state=state_0;
		
		break;
		
		default :break;

	}


}
void key_real()
{
 switch(key_num)
 {
 
	 case 0:
	  mod1++;  //界面切换
	  if(mod1==3)mod1=0;
	 if(mod1==0)
	 {		 param_min=min_old;
	       param_max=max_old;
	 }
	 if(mod1==1)
	 {   
		 min_old=param_min;
		 max_old=param_max;
	 
	 }
	
	 break;
	 
	 case 1:   //模式切换
		 mod2++;
	  if(mod2==2)mod2=0;
	  break;
	 
	 case 2:
		   if(mod1==2)
			 {
		   if(mod2)
			 { 
				  min_old+=5;
				 if(min_old>50)min_old=0;
			 }
	      else
				{		
					  max_old+=5;
					if(max_old>50)max_old=0;
				}
			 }
			 break;
			 
			 
	 case 3:
	    if(mod1==2)
			 {
		   if(mod2)
			 {  
				 if(min_old==0)min_old=50;
				 	else min_old-=5;
					
					
			 }
	      else 
				{   
					 if(max_old==0)max_old=50;
					else  max_old-=5;
				
				
				}
			 }
			 break;
 
	 default :break;
 
 
 
 
 }
 key_num=16;

}
void SMG_show()
{

  switch(mod1)
	{ 
		//显示电压界面
		case 0: segbuff[0]=11;
		        segbuff[1]=10;
	          segbuff[2]=10;
		        segbuff[3]=10;
	          segbuff[4]=10;
		        segbuff[5]=sum_v/100+12;
	          segbuff[6]=sum_v/10%10;
		        segbuff[7]=sum_v%10;
		        break;
		//显示参数界面
		case 2:
			      segbuff[0]=22;
		        segbuff[1]=10;
	          segbuff[2]=10;
		        segbuff[3]=max_old/10;
	          segbuff[4]=max_old%10;
		        segbuff[5]=10;
	          segbuff[6]=min_old/10;
		        segbuff[7]=min_old%10;
		        break;
		//显示超声波界面
		case 1:  
			      segbuff[0]=23;
		        segbuff[1]=10;
	          segbuff[2]=10;
		        segbuff[3]=10;
	          segbuff[4]=10;
		        if(flag_wave)
						{
		        if(wave>99)
		        segbuff[5]=wave/100;
						else  segbuff[5]=10;
	          segbuff[6]=wave/10%10;
		        segbuff[7]=wave%10;
				  	}
						else 
						{
          	segbuff[5]=24;
	          segbuff[6]=24;
		        segbuff[7]=24;
						}
	      break;
	
	}
 




}
void led_work()
{ 
	unsigned char old=P0;
	P2=P2&0x1f|0x00;
 P0=0xff;
 if(mod1==0)
 {
	 P2=P2&0x1f|0x80;
   P0=0xfe;
 }
 else if(mod1==1)
 {
	    P2=P2&0x1f|0x80;
       P0=0xfd;
 }
 else if(mod1==2)
 {
    P2=P2&0x1f|0x80;
   P0=0xfb;
  
 
 }
 P2=P2&0x1f;
 P0=old;

}

//初始化
void Init_System()
{
  P2=P2&0x1f|0x80;
	P0=0xff;
	P2=P2&0x1f|0xa0;
	P0=0xaf;
	time0();
  Timer0Init();

}

 

三.H操作

#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>
#define kbd_io P3
#define state_0 0
#define state_1 1
#define state_2 2
#define kbd_maskrow 0x0f
sbit TX=P1^0;
sbit RX=P1^1;
extern unsigned int wave;
extern unsigned int sum_v;
extern bit flag_v;
extern bit flag_wave;
extern unsigned int param_max; //֧ѹʏО
extern unsigned int param_min;
extern  bit flag_w;
void segs();
void SMG_show();
void scan_kbd();
void segs();
unsigned char wave_recv();
void time0();
void led_work();
void key_real();
void Init_System();
void Timer0Init(void);
#endif

其他IIC.c

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

//
void I2C_Start(void)
{
    SDA = 1;
    SCL = 1;
	I2C_Delay(DELAY_TIME);
    SDA = 0;
	I2C_Delay(DELAY_TIME);
    SCL = 0;    
}

//
void I2C_Stop(void)
{
    SDA = 0;
    SCL = 1;
	I2C_Delay(DELAY_TIME);
    SDA = 1;
	I2C_Delay(DELAY_TIME);
}

//
void I2C_SendByte(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 I2C_ReceiveByte(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 I2C_WaitAck(void)
{
	unsigned char ackbit;
	
    SCL = 1;
	I2C_Delay(DELAY_TIME);
    ackbit = SDA; 
    SCL = 0;
	I2C_Delay(DELAY_TIME);
	
	return ackbit;
}

//
void I2C_SendAck(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);
}
void dac_out(unsigned int dat)
{
  I2C_Start();
	I2C_SendByte(0x90);
	I2C_WaitAck();
	I2C_SendByte(0x40);
	I2C_WaitAck();
  I2C_SendByte(dat);
	I2C_WaitAck();
	I2C_Stop();
	
}
unsigned int read_adc()   
{
	unsigned int  dat;
  I2C_Start();
	I2C_SendByte(0x90);
	I2C_WaitAck();
	I2C_SendByte(0x03);
	I2C_WaitAck();
	I2C_Stop();
	
	I2C_Start();
  I2C_SendByte(0x91);
	I2C_WaitAck();
	dat=I2C_ReceiveByte();
	I2C_SendAck(1);
	I2C_Stop();
	return dat;

}

IIC.H

#ifndef _I2C_H
#define _I2C_H

void I2C_Start(void);
void I2C_Stop(void);
void I2C_SendByte(unsigned char byt)	;
unsigned char I2C_ReceiveByte(void);
unsigned char I2C_WaitAck(void);
void I2C_SendAck(unsigned char ackbit);
void dac_out(unsigned int dat);
unsigned int read_adc();

#endif 







  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VersionGod

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值