蓝桥杯第八届国赛——超声波测距机

main.c

#include "STC15F2K60S2.h"
#include "intrins.h"
#include "iic.h"						   //2020-11-6 10:46

#define u8 unsigned char
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_mask 0x0f
#define KEY P3

#define TX P10
#define RX P11

#define somenop	{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();};

sbit buzzer=P0^6;
sbit relay=P0^4;

u8 code smg_duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
u8 code smg_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};


void Delay10ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 108;
	j = 145;
	do
	{
		while (--j);
	} while (--i);
}



u8 key_scan()
{
  static unsigned char key_state=key_state_0;
  u8 key_temp,key_return=0;
  key_temp=KEY&key_mask;
  switch(key_state)
  {
    case key_state_0:
	if(key_temp!=key_mask)
	{
	  key_state=key_state_1;
	}
	break;

	case key_state_1:
	if(key_temp==(key_mask&KEY))
	{
	  key_state=key_state_2;
	  switch(key_temp)
	  {
	    case 0x07:key_return=4;break;
        case 0x0b:key_return=5;break;
		case 0x0d:key_return=6;break;
		case 0x0e:key_return=7;break;
	  }
	}
    else
	{
	  key_state=key_state_0;
	}
	break;

	case key_state_2:
	if(key_temp==key_mask)
	{
	  key_state=key_state_0;
	}
	break;
  }
  return key_return;
}



void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xCD;		//设置定时初值
	TH0 = 0xD4;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
	EA = 1;
}


void Timer1Init(void)		//1毫秒@11.0592MHz
{
//	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x00;		//设置定时初值
	TH1 = 0x00;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
}


void send_wave()
{
  TX=1;
  somenop;somenop;somenop;somenop;somenop;
  somenop;somenop;somenop;somenop;somenop;
  TX=0;
}


unsigned int get_distance()
{
  unsigned int dis;
  TR1=1;
  send_wave();
  while((TF1==0)&&(RX==1));
  TR1=0;
  if(TF1==1)
  {
    TF1=0;
	dis=999;
  }
  else
  {
    dis=(TH1<<8)|TL1;
	dis*=0.017;
  }
  TH1=TL1=0;
  return dis;
}


bit key_flag;

bit read_sonic_flag;

u8 sonic_display[8];

u8 menu_index=0;

//回显模式
u8 sonic_cunchu_display[8];
u8 cunchu_index=1;	    //存数据时的索引
u8 display_index=1;         //显示时的索引
unsigned int cunchu_table[5];     //1 2 3 4  用于存放4个distance

//参数设置界面
u8 mangqu_val=0;
u8 canshu_display[8];
bit s6_flag=0;
u8 volt_out;

//led 
bit blink_flag;
bit led_flag;
u8 L7_index,L8_index,L1_index;

//eeprom
unsigned int ee_cunchu[5];
u8 ee_add=2;     //存储地址,2,3,4,5
u8 ee_i;        //2 3 4 5
unsigned int data_test;

void main()
{
  u8 keyvalue;
  unsigned int distance=0,now_distance=0,last_distance=0;
  P2=0x80;P0=0xff;P2=0;
  P2=0xa0;P0=0;P2=0;
  Timer0Init();
  Timer1Init();

  //eeprom_read
  ET0=0;
  mangqu_val=read_24c02(1);
  for(ee_i=2;ee_i<6;ee_i++)
  {
    data_test=read_24c02(ee_i+100);       //判别地址 :1-- >=10,要处理   2---<10不处理
	if(data_test==1)    //说明当前ee_i地址里的数据是>=10的 ,要做*10处理
      cunchu_table[ee_i-1]=read_24c02(ee_i)*10;
	else if(data_test==2)
	  cunchu_table[ee_i-1]=read_24c02(ee_i);
  }
  ET0=1;
  while(1)
  {
    //sonic  测量显示数组
    sonic_display[0]=0x39;
	sonic_display[1]=0x00;
	sonic_display[2]=smg_duan[now_distance/100];
	sonic_display[3]=smg_duan[now_distance%100/10];
	sonic_display[4]=smg_duan[now_distance%10];
	sonic_display[5]=smg_duan[last_distance/100];;
	sonic_display[6]=smg_duan[last_distance%100/10];;
	sonic_display[7]=smg_duan[last_distance%10];
	//-------------------------------------------------
    // sonic 回显查看数组
	sonic_cunchu_display[0]=smg_duan[display_index];
	sonic_cunchu_display[1]=0x00;
	sonic_cunchu_display[2]=0x00;
	sonic_cunchu_display[3]=0x00;
	sonic_cunchu_display[4]=0x00;
	sonic_cunchu_display[5]=smg_duan[cunchu_table[display_index]/100];
	sonic_cunchu_display[6]=smg_duan[cunchu_table[display_index]%100/10];
	sonic_cunchu_display[7]=smg_duan[cunchu_table[display_index]%10];

	//参数设置界面
	canshu_display[0]=0x71;
	canshu_display[1]=0x00;
	canshu_display[2]=0x00;
	canshu_display[3]=0x00;
	canshu_display[4]=0x00;
	canshu_display[5]=0x00;
	canshu_display[6]=smg_duan[mangqu_val/10];
	canshu_display[7]=smg_duan[mangqu_val%10];;

	//超声波测量一次--------------------------------------
    if(read_sonic_flag)
	{
	  read_sonic_flag=0;
	  last_distance=now_distance;
	  now_distance=get_distance();
	  cunchu_table[cunchu_index]=now_distance;
	  cunchu_index++;
	  if(cunchu_index==5)cunchu_index=1;

	  if(now_distance<mangqu_val)
	  {
	    SetDAC(0);
	  }
	  else
	  {	 
	    volt_out=(now_distance-mangqu_val)*0.02/5.0*255;
		if(volt_out>255)volt_out=255;                            //数据处理
	    SetDAC(volt_out);					      // (s-s0)*0.02 V
	  }
	 //eeprom
      ET0=0;
	  if(now_distance>=255)
	  {
	    write_24c02(ee_add,now_distance/10);	   //2 3 4 5
		Delay10ms();
		write_24c02(ee_add+100,1);							  //根据地址100的数据来判别,有数据则要100的,否则要ee_add的
		Delay10ms();
	  }
	  else
	  {
	    write_24c02(ee_add+100,2);      //<10
		Delay10ms();
		write_24c02(ee_add,now_distance);
		Delay10ms();
	  }
	  ET0=1;
	  ee_add++;
	  if(ee_add==6)ee_add=2;
	}

	//led
	if(led_flag)
	{
	  if(blink_flag)
	  {
	    L1_index=0x01;
	  }
	  else
	  {
	    L1_index=0;
	  }
	}

	if(menu_index==2)L7_index=0x40;
	else L7_index=0;

	if(menu_index==1)L8_index=0x80;
	else L8_index=0;

	P2=0x80;P0=~(L1_index|L7_index|L8_index);P2=0;

    if(key_flag)
	{
	  key_flag=0;
	  keyvalue=key_scan();
	  switch(keyvalue)
	  {
	    case 4:
		       if(menu_index==0)
			   {
		         read_sonic_flag=1;
				 led_flag=1;
			   }
			   break;
		case 5:
		       if(menu_index==0||menu_index==1)
			   {
			       menu_index++;
				   if(menu_index==2)menu_index=0;     //0--sonic 测量; 1--sonic 存储显示
			   }
			   else
			   {
			     menu_index=0;
			   }
			   break;
		case 6:		         //参数设置
			   s6_flag=~s6_flag;
			   if(s6_flag==1)
			   {
			     menu_index=2;	    
			   }
			   else		              //保存盲区val
			   {
			     menu_index=0;
				 ET0=0;
				 write_24c02(1,mangqu_val);	  //0~30
				 Delay10ms();
				 ET0=1;		 
			   }
		       break;
		case 7:		       //翻页功能
		       if(menu_index==1)     //存储显示界面才能翻页
			   {
		         display_index++;
			     if(display_index==5)display_index=1;	  //1 2 3 4
			   }
			   if(menu_index==2)
			   {
			     mangqu_val+=10;
				 if(mangqu_val>30)mangqu_val=0;
			   }
			   break;		     
	  }

	}
  }
}


void timer0() interrupt 1
{
  static unsigned int key_count=0,smg_count=0,i=0,led_blink_count=0,jishu_count=0;
  key_count++;
  smg_count++;

  if(led_flag)
  {
	  led_blink_count++;
	  if(led_blink_count==1000)
	  {
	    led_blink_count=0;
		blink_flag=~blink_flag;
		jishu_count++;
		if(jishu_count==6)		 //亮灭3次
		{
		  jishu_count=0;
		  led_flag=0;
		  L1_index=0;
		}
	  }
  }
  if(key_count==10)
  {
    key_count=0;
	key_flag=1;
  }
  if(smg_count==3)
  {
    smg_count=0;
	P2=0xc0;P0=0;P2=0;
	if(menu_index==0)
	{
	  P2=0xe0;P0=~sonic_display[i];P2=0;
	}
	if(menu_index==1)	       //回显界面
	{
	  P2=0xe0;P0=~sonic_cunchu_display[i];P2=0;
	}
	if(menu_index==2)
	{
	  P2=0xe0;P0=~canshu_display[i];P2=0;
	}
	P2=0xc0;P0=smg_wei[i];P2=0;
	i++;
	if(i==8)i=0;
  }
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值