蓝桥杯第九届国赛——多功能测量仪表

main.c

#include "STC15F2K60S2.h"
#include "iic.h"
#include "onewire.h"
								 //2020-11-8     15:58    --Rsh
#define u8 unsigned char	     //涉及到频率,所以用普通版矩阵键盘
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
#define NO_KEY 0

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};

u8 key_scan()
{
  u8 key_temp,key_temporary=0;
  u8 key1,key2;
  P30=0;P31=0;P32=0;P33=0;P34=1;P35=1;P42=1;P44=1;
  if(P44==0)key1=0x70;
  if(P42==0)key1=0xb0;
  if(P35==0)key1=0xd0;
  if(P34==0)key1=0xe0;
  if((P44==1)&&(P42==1)&&(P35==1)&&(P34==1))key1=0xf0;

  P30=1;P31=1;P32=1;P33=1;P34=0;P35=0;P42=0;P44=0;
  if(P33==0)key2=0x07;
  if(P32==0)key2=0x0b;
  if(P31==0)key2=0x0d;
  if(P30==0)key2=0x0e;
  if((P33==1)&&(P32==1)&&(P31==1)&&(P30==1))key2=0x0f;

  key_temp=key1|key2;
  switch(key_temp)
  {
    case 0x77:key_temporary=4;break;
	case 0x7b:key_temporary=5;break;
	case 0x7d:key_temporary=6;break;
	case 0x7e:key_temporary=7;break;

	case 0xb7:key_temporary=8;break;
	case 0xbb:key_temporary=9;break;
	case 0xbd:key_temporary=10;break;
	case 0xbe:key_temporary=11;break;

	case 0xd7:key_temporary=12;break;
	case 0xdb:key_temporary=13;break;
	case 0xdd:key_temporary=14;break;
	case 0xde:key_temporary=15;break;

	case 0xe7:key_temporary=16;break;
	case 0xeb:key_temporary=17;break;
	case 0xed:key_temporary=18;break;
	case 0xee:key_temporary=19;break;
  }
  return key_temporary;
}


u8 key_long_short_click()	                   //key_val得到的是0,所以NO_KEY要为0,而不是0xff
{
  static unsigned char key_state=key_state_0,key_prev,key_time=0;
  u8 key_val=0,key_return=0;
  key_val=key_scan();
  switch(key_state)
  {
    case key_state_0:
	if(key_val!=NO_KEY)
	{
	  key_state=key_state_1;
	  key_prev=key_val;
	}
	break;

	case key_state_1:
	if(key_val==NO_KEY)
	{
	  key_state=key_state_0;
	}
	else
	{
	  key_state=key_state_2;
	  key_time=0;
	}
	break;

	case key_state_2:
	if(key_val==NO_KEY)     //short
	{
	  key_state=key_state_0;       
	  key_return=key_prev;
	}
	else
	{
	  key_time++;     //0.8s==800ms  10ms扫描一次  -->80
	  if(key_time>=80)
	  {
		key_return=key_val;      /*不松手一直快速增加,所以不进入松手检测key_state_3,key_state一直是key_state_2,松手后进入switch
	  							 	       后的case key_state_2时因为key_val==NO_KEY,所以会回到初始状态,系统将重新运行*/
      }											
	}
	break;
  }
  return key_return;
}


void Timer0Init(void)		//1毫秒@11.0592MHz	   //用作计数器
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x04;
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x00;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0
}


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




bit key_flag;

u8 menu_index=1;

//1.电压
u8 volt;
u8 volt_display[8];
bit volt_flag;

//2.频率
unsigned int freq;
u8 freq_display[8];
bit freq_flag;

//3.温度
float temperature;
u8 temp_display[8];
bit temp_flag;
u8 zhengshu_part;
u8 xiaoshu_part;

//4.回显
u8 huixian_display[8];
bit huixian_flag=0;
u8 cunchu_volt;
unsigned int cunchu_freq;
u8 cunchu_zhengshu;
u8 cunchu_xiaoshu;

//5.阈值界面
u8 volt_yuzhi=10;
u8 yuzhi_display[8];
bit yuzhi_flag;

u8 count=0;      //统计位数
unsigned int copy;
u8 freq_5=0,freq_4=0,freq_3=0,freq_2=0,freq_1=0;     //最多5位,到万
u8 data_message;

//6. led control
u8 led1_index=0;
u8 led2_index=0;
u8 led3_index=0;
u8 led8_index=0;
bit led_blink_flag;
bit blink_flag;


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

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


void main()
{
  u8 keyvalue;
  P2=0x80;P0=0xff;P2=0;
  P2=0xa0;P0=0;P2=0;
  Timer1Init();
  Timer0Init();
  ET0=0;
  cunchu_volt=read_24c02(1);
  //频率读取************--------------------------------------根据地址判断位数

  //cunchu_freq=read_24c02(2)*100;
  data_message=read_24c02(100);         //3 or 4 or 5
  if(data_message==3)
  {
     cunchu_freq=read_24c02(22)*100+read_24c02(12)*10+read_24c02(2);
  }	 
  if(data_message==4)
  {
     cunchu_freq=read_24c02(32)*1000+read_24c02(22)*100+read_24c02(12)*10+read_24c02(2);
  }
  if(data_message==5)
  {
     cunchu_freq=read_24c02(42)*10000+read_24c02(32)*1000+read_24c02(22)*100+read_24c02(12)*10+read_24c02(2);
  }

  //-----------------------------------------------------
  cunchu_zhengshu=read_24c02(3);
  cunchu_xiaoshu=read_24c02(4);
  ET0=1;
  while(1)
  {
     //电压
    if(volt_flag)
	{
	  volt_flag=0;
	  ET0=0;
	  volt=read_adc(0x03)/255.f*5*10;
	  ET0=1;
	  volt_display[0]=0x3e;
	  volt_display[1]=0x00;
	  volt_display[2]=0x00;
	  volt_display[3]=0x00;
	  volt_display[4]=0x00;
	  volt_display[5]=0x00;
	  volt_display[6]=smg_duan[volt/10]|0x80;
	  volt_display[7]=smg_duan[volt%10];
	}

	//频率
	if(freq_flag)
	{
	  freq_flag=0;
	  TR0=0;
	  freq=(TH0<<8)|TL0;
	  TH0=TL0=0;
	  TR0=1;
	  freq*=2;         //1s

	  freq_display[0]=0x71;  //F
	  freq_display[1]=0x00;
	  freq_display[2]=0x00;
	  freq_display[3]=smg_duan[freq/10000];
	  freq_display[4]=smg_duan[freq%10000/1000];
	  freq_display[5]=smg_duan[freq%1000/100];
	  freq_display[6]=smg_duan[freq%100/10];
	  freq_display[7]=smg_duan[freq%10];
	}

	//温度
	if(temp_flag)
	{
	  temp_flag=0;
	  ET0=0;
	  temperature=rd_temperature_f();		  //float
	  ET0=1;
	  zhengshu_part=(u8)temperature;
	  xiaoshu_part=(u8)((temperature-zhengshu_part)*100);         //0.23456...两位即可	   ,处理成两个整数,如23,45
	  temp_display[0]=0x39;	    //C
      temp_display[1]=0x00;
	  temp_display[2]=0x00;
	  temp_display[3]=0x00;
	  temp_display[4]=smg_duan[((u8)temperature)/10];
	  temp_display[5]=smg_duan[((u8)temperature)%10]|0x80;
	  temp_display[6]=smg_duan[((u8)(temperature*10))%10];	  //23.45C   ->  234
	  temp_display[7]=smg_duan[((u8)(temperature*100))%10];	
	}

	//回显
	if(huixian_flag)
	{
	    huixian_display[0]=0x76;
	    huixian_display[1]=0x39;
	    if(menu_index==1)  //volt
		{
		   huixian_display[2]=0x00;
		   huixian_display[3]=0x00;
		   huixian_display[4]=0x00;
		   huixian_display[5]=0x00;
		   huixian_display[6]=smg_duan[cunchu_volt/10]|0x80;
		   huixian_display[7]=smg_duan[cunchu_volt%10];
		}
		if(menu_index==2)   
		{
		   huixian_display[2]=0x00;
		   huixian_display[3]=smg_duan[cunchu_freq/10000];
		   huixian_display[4]=smg_duan[cunchu_freq%10000/1000];
		   huixian_display[5]=smg_duan[cunchu_freq%1000/100];
		   huixian_display[6]=smg_duan[cunchu_freq%100/10];
		   huixian_display[7]=smg_duan[cunchu_freq%10];
		}
		if(menu_index==3)
		{
		   huixian_display[2]=0x00;
		   huixian_display[3]=0x00;
		   huixian_display[4]=smg_duan[cunchu_zhengshu/10];
		   huixian_display[5]=smg_duan[cunchu_zhengshu%10]|0x80;
		   huixian_display[6]=smg_duan[cunchu_xiaoshu/10];	   
		   huixian_display[7]=smg_duan[cunchu_xiaoshu%10];	
		}
	}

	if(yuzhi_flag)
	{
	  	 yuzhi_display[0]=0x73;       //P
		 yuzhi_display[1]=0x00;
		 yuzhi_display[2]=0x00;
		 yuzhi_display[3]=0x00;
		 yuzhi_display[4]=0x00;
		 yuzhi_display[5]=0x00;
		 yuzhi_display[6]=smg_duan[volt_yuzhi/10]|0x80;
		 yuzhi_display[7]=smg_duan[volt_yuzhi%10];
	}

	//led control
	if(yuzhi_flag==0&&huixian_flag==0)
	{
	  if(menu_index==1)
	  {
	    led1_index=0x01;
		led2_index=0x00;
		led3_index=0x00;
	  }
	  if(menu_index==2)
	  {
	    led1_index=0x00;
		led2_index=0x02;
		led3_index=0x00;
	  }
	  if(menu_index==3)
	  {
	    led1_index=0x00;
		led2_index=0x00;
		led3_index=0x04;
	  }
	}
	else
	{
	   led1_index=0x00;
	   led2_index=0x00;
	   led3_index=0x00;
	}
	if(volt>volt_yuzhi)	     //同样扩大十倍
	{
	   led_blink_flag=1;
	   if(blink_flag)
	   {
	     led8_index=0x80;
	   }
	   else
	   {
	     led8_index=0x00;
	   }
	}
	else
	{
	   led8_index=0x00;
	}
	P0=~(led1_index|led2_index|led3_index|led8_index);P2=0x80;P2=0;
	P2=0x80;P0=~(led1_index|led2_index|led3_index|led8_index);P2=0;

    if(key_flag)
	{
	  key_flag=0;
	  keyvalue=key_long_short_click();
	  switch(keyvalue)
	  {
	    case 4:		    //menu切换
		       menu_index++;
			   if(menu_index==4)menu_index=1;         //1-2-3     
		       break;
		case 5:	         //存储到eeprom
		       ET0=0;
			   //电压部分存储---------------------------------
			   cunchu_volt=volt;
			   write_24c02(1,cunchu_volt);   //volt是AD值,读取时候需要处理过
			   Delay10ms();

			   //频率部分存储--------------------------------
			   cunchu_freq=freq;
			   copy=cunchu_freq;
			   while(copy)		 //200
			   {
			     count++;
				 copy/=10;
			   }
			   if(count==3)
			   {
			     freq_3=cunchu_freq/100;  //百位
				 freq_2=cunchu_freq%100/10;	  //十位
				 freq_1=cunchu_freq%10;				//个位
				 count=0;

				 write_24c02(2,freq_1);  //110~35000     
			     Delay10ms();
				 write_24c02(12,freq_2);  //    
			     Delay10ms();
				 write_24c02(22,freq_3);  //地址数值越大表示存的位数越高  
			     Delay10ms();
				 write_24c02(100,3);  //   100地址用来存储位数信息
			     Delay10ms();
			   }
			   if(count==4)
			   {
			     freq_4=cunchu_freq/1000;
				 freq_3=cunchu_freq%1000/100;
				 freq_2=cunchu_freq%100/10;
				 freq_1=cunchu_freq%10;	 
				 count=0;

				 write_24c02(2,freq_1);  //110~35000     
			     Delay10ms();
				 write_24c02(12,freq_2);  //    
			     Delay10ms();
				 write_24c02(22,freq_3);  //地址数值越大表示存的位数越高  
			     Delay10ms();
				 write_24c02(32,freq_4);  
			     Delay10ms();
				 write_24c02(100,4);  //   100地址用来存储位数信息
			     Delay10ms();
			   }
			   if(count==5)
			   {
			     freq_5=cunchu_freq/10000;
				 freq_4=cunchu_freq%10000/1000;
				 freq_3=cunchu_freq%1000/100;
				 freq_2=cunchu_freq%100/10;
				 freq_1=cunchu_freq%10;
				 count=0;

				 write_24c02(2,freq_1);  //110~35000     
			     Delay10ms();
				 write_24c02(12,freq_2);  //    
			     Delay10ms();
				 write_24c02(22,freq_3);  //地址数值越大表示存的位数越高  
			     Delay10ms();
				 write_24c02(32,freq_4);  
			     Delay10ms();
				 write_24c02(42,freq_5);  
			     Delay10ms();
				 write_24c02(100,5);  //   100地址用来存储位数信息
			     Delay10ms();
			   }
			  

		       //温度部分存储------------------------------------------
			   cunchu_zhengshu=zhengshu_part;
			   write_24c02(3,cunchu_zhengshu);    //把整数和小数部分分开存储,读取时再合并即可  
			   Delay10ms();
			   cunchu_xiaoshu=xiaoshu_part;
			   write_24c02(4,cunchu_xiaoshu);  
			   Delay10ms();
			   ET0=1;
		       break;
		case 6:			 //回显	
		       if(yuzhi_flag==0)
			   {
		         huixian_flag=~huixian_flag;	 //0->1
			   }
			   else if(yuzhi_flag==1)
			   {
			     volt_yuzhi+=1;
				 if(volt_yuzhi>50)volt_yuzhi=1;
			   }   
		       break; 
		case 7:	         //设置
		       yuzhi_flag=~yuzhi_flag;
			   if(yuzhi_flag==0)    //从 1->0
			   {
			     huixian_flag=0;
			     menu_index=1;
			   }
		       break;
	  }
	}
  }
}



void timer0() interrupt 3
{
  static unsigned int key_count=0,smg_count=0,i=0,volt_count=0,freq_count=0,temp_count=0,blink_count=0;
  key_count++;
  smg_count++;
  volt_count++;
  freq_count++;
  temp_count++;
  if(led_blink_flag)
  {
    blink_count++;
	if(blink_count==200)
	{
	  blink_count=0;
	  blink_flag=~blink_flag;
	}
  }
  else
  {
      blink_count=0;
  }
  if(temp_count==200)
  {
    temp_count=0;
	temp_flag=1;
  }
  if(freq_count==200)
  {
     freq_count=0;
	 freq_flag=1;
  }
  if(volt_count==200)
  {
    volt_count=0;
	volt_flag=1;
  }
  if(key_count==10)
  {
    key_count=0;
	key_flag=1;
  }
  if(smg_count==3)
  {
    smg_count=0;
	P2=0xc0;P0=0;P2=0;
	if(yuzhi_flag==0)
	{
		if(huixian_flag==0)
		{
			if(menu_index==1)    //volt
			{
			  P2=0xe0;P0=~volt_display[i];P2=0;
			}
			if(menu_index==2)    //freq
			{
			  P2=0xe0;P0=~freq_display[i];P2=0;
			}
			if(menu_index==3)    //temp
			{
			  P2=0xe0;P0=~temp_display[i];P2=0;
			}
		}
		else if(huixian_flag==1)    //回显
		{
		  P2=0xe0;P0=~huixian_display[i];P2=0;
		}
	}
	else
	{
	   P2=0xe0;P0=~yuzhi_display[i];P2=0;
	}

	P2=0xc0;P0=smg_wei[i];P2=0;
	i++;
	if(i==8)i=0;
  }
  
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值