天天看点

蓝桥杯国赛第五届——多功能事件记录器

main.c

#include "STC15F2K60S2.h"         //采用btn
#include "onewire.h"             //按照视频
#include "iic.h"
#include "ds1302.h"
#include "uart.h"


#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

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()
{
  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;
}


u8 judge_data(u8 a[],u8 b[])
{ 
  u8 i;
  for(i=0;i<6;i++)
  {
    if(a[i]!=b[i])
		return 0;
  }
  return 1;
}


bit key_flag;
bit temp_read_flag;
bit volt_read_flag;

bit time_blink_flag;
bit light_read_flag;
u8 close_flag;        //1—有物体接近     0-没有
u8 last_close_flag;

bit work_mode=0; //0--自动传输模式      1--自动记录模式

bit tx1_send_flag=0;     
bit tx1_sec_flag;   

bit tx2_send_flag;         //自动记录模式的串口发送标志位

bit close_time_flag;           //用于开启接近时间计数的标志位
bit close_add_flag;

//温湿度读取部分
u8 temp_humi_display[8];
u8 temperature;          //   温度
u8 humidity;             //湿度

//时间部分
u8 time_display[8];
u8 shi,fen,miao;
u8 last_miao;            //用于1s的判断
//---
u8 light_yuzhi=150;
u8 light_volt;           //读取到的光敏电阻AD值

u8 true_data[]={'A','A','A','S','S','S'};

//显示界面切换
u8 menu_index=0;

//串口发送数组
u8 tx1_buffer[23];    //结尾为\r\n
u8 tx1_send_index=0;

u8 xdata tx2_buffer[5][30];
u8 tx2_send_index=0;

//物体接近停留时间显示
u8 close_time_display[8];
unsigned int xdata close_time[5]={0,0,0,0,0};           //物体接近时间
u8 close_time_index=0;

unsigned int close_sec_time=0;

u8 eeprom_i;
u8 eeprom_j;
u8 eeprom_add;



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;
  Timer0Init();
  UartInit();
  set_sfm(23,59,55);
//  for(eeprom_i=0;eeprom_i<5;eeprom_i++)
//  {
	write_24c02(eeprom_i*10+0,temperature);    //0~5, 10~15, 20~25 ,30~35, 40~45
    write_24c02(eeprom_i*10+1,humidity);
	write_24c02(eeprom_i*10+2,shi);
	write_24c02(eeprom_i*10+3,fen);
	write_24c02(eeprom_i*10+4,miao);
	write_24c02(eeprom_i*10+5,close_time[eeprom_i]);     //0~4
//    temperature=read_24c02();
//  }
  while(1)
  { 
    last_miao=miao;
    miao=Read_Ds1302_Byte(0x81);         //new miao
	fen=Read_Ds1302_Byte(0x83);
	shi=Read_Ds1302_Byte(0x85);
	//----
	time_display[0]=smg_duan[shi/16];
	time_display[1]=smg_duan[shi%16];

	time_display[3]=smg_duan[fen/16];
	time_display[4]=smg_duan[fen%16];

	time_display[6]=smg_duan[miao/16];
	time_display[7]=smg_duan[miao%16];
	if(time_blink_flag)
	{
	  	time_display[2]=0x40;
		time_display[5]=0x40;
	}
	else
	{
	    time_display[2]=0x00;
		time_display[5]=0x00;
	}
	
	//温湿度处理--------------------------------------
    if(temp_read_flag)
	{
	  temp_read_flag=0;
	  //ET0=0;
	  temperature=(u8)rd_temperature_f();
	  //ET0=1;
	  temp_humi_display[0]=smg_duan[temperature/10];
	  temp_humi_display[1]=smg_duan[temperature%10];
	}
	if(volt_read_flag)
	{
	  volt_read_flag=0;
	  //ET0=0;
	  humidity=read_adc(0x01)/256.f*100;
	  //ET0=1;
	  temp_humi_display[5]=smg_duan[humidity/10];
	  temp_humi_display[6]=smg_duan[humidity%10];;
	}
	temp_humi_display[2]=0x39;   //C
	temp_humi_display[3]=0x00;
	temp_humi_display[4]=0x00;
	temp_humi_display[7]=0x76;         //H	
    // -------------------------------------------
	//光敏电阻检测是否有物体靠近-------------------
	if(light_read_flag)               //200m更新一次
	{
	  light_read_flag=0;
	  last_close_flag=close_flag;          //****
	  light_volt=read_adc(0x03);
	}
    if(light_volt<light_yuzhi)      //light_volt越小,表明有物体接近  light_yuzhi=100
    {
      close_flag=1;                //1表示有物体靠近,0表示没有物体靠近
    }
    else
    {
      close_flag=0;
    }
	
	
	
	//自动记录模式     work_mode=1             //遮挡计时*************************
	if(work_mode==1)
	{
	  if(close_flag==1&&last_close_flag==0)    //有物体接近,要开始计时      这个条件在200ms后会消失,所以不能广泛使用
	  {
	    close_time_flag=1;                 //用于去定时器中判断1s时间
	  }
	  if(close_add_flag==1&&close_flag==1)                   //每隔1s在中断中变成1(物体处于接近状态)
	  {
	    close_add_flag=0;
	    close_time[close_time_index]++;
 	  }	  
	  if(close_flag==0&&last_close_flag==1)      //物体离开      (离开的时候存入eeprom)
	  {
	    //close_time[close_time_index]=0;             //*****先不能清零
		close_time_flag=0;                           //停止加数
		close_sec_time=0;
	    close_time_index++;
		if(close_time_index==5)close_time_index=0;     //0~4  共5组数据存储
		
		  tx2_buffer[close_time_index][0]='{';
		  tx2_buffer[close_time_index][1]=temperature/10+'0';
		  tx2_buffer[close_time_index][2]=temperature%10+'0';
		  tx2_buffer[close_time_index][3]='-';
		  tx2_buffer[close_time_index][4]=humidity/10+'0';
		  tx2_buffer[close_time_index][5]=humidity%10+'0';
		  tx2_buffer[close_time_index][6]='%';
		  tx2_buffer[close_time_index][7]='}';
		  tx2_buffer[close_time_index][8]='{';
		  tx2_buffer[close_time_index][9]=shi/16+'0';
		  tx2_buffer[close_time_index][10]=shi%16+'0';
		  tx2_buffer[close_time_index][11]='-';
		  tx2_buffer[close_time_index][12]=fen/16+'0';
		  tx2_buffer[close_time_index][13]=fen%16+'0';
		  tx2_buffer[close_time_index][14]='-';
		  tx2_buffer[close_time_index][15]=miao/16+'0';
		  tx2_buffer[close_time_index][16]=miao%16+'0';
		  tx2_buffer[close_time_index][17]='}';
		  tx2_buffer[close_time_index][18]='{';
		  tx2_buffer[close_time_index][19]=close_time[close_time_index]+'0';     //停留的时间
		  tx2_buffer[close_time_index][20]='}';
		  tx2_buffer[close_time_index][21]='\r';
		  tx2_buffer[close_time_index][22]='\n';
		
		for(eeprom_i=0;eeprom_i<5;eeprom_i++)
		{
		    write_24c02(eeprom_i*10+0,temperature);    //0~5, 10~15, 20~25 ,30~35, 40~45
			Delay10ms();
		    write_24c02(eeprom_i*10+1,humidity);
			Delay10ms();
			write_24c02(eeprom_i*10+2,shi);
			Delay10ms();
			write_24c02(eeprom_i*10+3,fen);
			Delay10ms();
			write_24c02(eeprom_i*10+4,miao);
			Delay10ms();
			write_24c02(eeprom_i*10+5,close_time[eeprom_i]);     //0~4
			Delay10ms();
		  }
		}		
	  }
	}
	  //更新数组
	  close_time_display[3]=0x40;
	  close_time_display[4]=smg_duan[close_time[close_time_index]/1000];
	  close_time_display[5]=smg_duan[close_time[close_time_index]%1000/100];
	  close_time_display[6]=smg_duan[close_time[close_time_index]%100/10];
	  close_time_display[7]=smg_duan[close_time[close_time_index]%10];
	
	
	
	//串口部分------------------------------
	if(rec_index>5)
	{
	  /*for(rec_index=0;rec_index<6;rec_index++)
	  {
	    SendData(rec_table[rec_index]);
	  }*/
	  rec_index=0;
	  if(judge_data(true_data,rec_table))
	  {
	    if(work_mode==0)        //自动传输模式
		{
	      tx1_send_flag=1;
		}
		if(work_mode==1)
		{
		  tx2_send_flag=1;
		}
	  }
	}
	//---
	if(work_mode==0)       //自动传输模式的数据发送
	{
		if((tx1_send_flag)&&(tx1_sec_flag))
		{
		  //tx1_send_flag=0; 
		  tx1_sec_flag=0;
		  
		  tx1_buffer[0]='{';
		  tx1_buffer[1]=temperature/10+'0';
		  tx1_buffer[2]=temperature%10+'0';
		  tx1_buffer[3]='-';
		  tx1_buffer[4]=humidity/10+'0';
		  tx1_buffer[5]=humidity%10+'0';
		  tx1_buffer[6]='%';
		  tx1_buffer[7]='}';
		  tx1_buffer[8]='{';
		  tx1_buffer[9]=shi/16+'0';
		  tx1_buffer[10]=shi%16+'0';
		  tx1_buffer[11]='-';
		  tx1_buffer[12]=fen/16+'0';
		  tx1_buffer[13]=fen%16+'0';
		  tx1_buffer[14]='-';
		  tx1_buffer[15]=miao/16+'0';
		  tx1_buffer[16]=miao%16+'0';
		  tx1_buffer[17]='}';
		  tx1_buffer[18]='{';
		  tx1_buffer[19]=close_flag+'0';
		  tx1_buffer[20]='}';
		  tx1_buffer[21]='\r';
		  tx1_buffer[22]='\n';
		  
		  for(tx1_send_index=0;tx1_send_index<23;tx1_send_index++)
		  {
		    SendData(tx1_buffer[tx1_send_index]);
		  }
		}
	}
	
	//自动记录模式的串口数据发送
	if(work_mode==1)                //发送一次‘AAASSS’,返回5个值
	{
       if(tx2_send_flag==1)                                                                                                                                                                                                                                                                                                                                                                                                                                                 
	   {
	     tx2_send_flag=0;
		  
		 for(close_time_index=0;close_time_index<5;close_time_index++)
		 {
		   for(tx2_send_index=0;tx2_send_index<23;tx2_send_index++)
		   {			  
		      SendData(tx2_buffer[close_time_index][tx2_send_index]);
		   }
		 }
	   }
	}
	 	
	
	//-------------------------------------------
    if(key_flag)
	{
	  key_flag=0;
	  keyvalue=key_scan();
	  switch(keyvalue)
	  {
	    case 4:work_mode=~work_mode;
		       break;     //切换工作模式
		
		case 5:menu_index++;
			  if(menu_index==3)menu_index=0;
			  break;
	  }
	}
	//-------------------------------------------
	if(work_mode==0)
	{
	  P2=0x80;P0=~0x01;P2=0;
	}
	else
	{
	  P2=0x80;P0=~0x02;P2=0;
	}
}



void timer0() interrupt 1
{
  static unsigned int key_count=0,smg_count=0,i=0,temp_read_count=0,volt_read_count=0,time_blink_count=0,
                      light_read_count=0,tx1_sec_count=0;
  key_count++;
  smg_count++;
  temp_read_count++;
  volt_read_count++;
  time_blink_count++;
  light_read_count++;
  
  if(close_time_flag)
  {
    close_sec_time++;
	if(close_sec_time==1000)
	{
	  close_sec_time=0;
	  close_add_flag=1;      //用于标识加1
	}
  }
  
  
  if(tx1_send_flag)
  {
    tx1_sec_count++;
	if(tx1_sec_count==1000)
	{
	  tx1_sec_count=0;
	  tx1_sec_flag=1;
	}
  }
  if(light_read_count==200)      //光敏电阻RD1  -- 检测物体靠近
  {
    light_read_count=0;
	light_read_flag=1;
  }
  if(time_blink_count==1000)   //'-'  1s为间隔闪烁
  {
    time_blink_count=0;
	time_blink_flag=~time_blink_flag;
  }
  if(volt_read_count==200)        //humidity
  {
    volt_read_count=0;
	volt_read_flag=1;
  }
  if(temp_read_count==200)        //temp
  {
    temp_read_count=0;
	temp_read_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(menu_index==0)
	{
	  P2=0xe0;P0=~temp_humi_display[i];P2=0;       //温湿度显示
	}
	if(menu_index==1)
	{
	  P2=0xe0;P0=~time_display[i];P2=0;           //时间显示
	}
	if(menu_index==2)
	{
	  P2=0xe0;P0=~close_time_display[i];P2=0;
	}
	P2=0xc0;P0=smg_wei[i];P2=0;
	i++;
	if(i==8)i=0;
  }
}

           
uart.c


#include "uart.h"

bit busy;

unsigned char rec_table[6];
unsigned char rec_index=0;

void UartInit(void)		//[email protected]
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器1时钟为Fosc,即1T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设定定时器1为16位自动重装方式
	TL1 = 0x00;		//设定定时初值
	TH1 = 0xF7;		//设定定时初值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	ES  = 1;
	EA = 1;
	SendString("STC15F2K60S2\r\nUart Test !\r\n");
}


/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4 using 1
{
    if (RI)
    {
        RI = 0;                 //清除RI位
        rec_table[rec_index] = SBUF;              //P0显示串口数据
		rec_index++;
    }
    if (TI)
    {
        TI = 0;                 //清除TI位
        busy = 0;               //清忙标志
    }
}

/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
    while (busy);               //等待前面的数据发送完成
    busy = 1;
    SBUF = dat;                 //写数据到UART数据寄存器
}

/*----------------------------
发送字符串
----------------------------*/
void SendString(char *s)
{
    while (*s)                  //检测字符串结束标志
    {
        SendData(*s++);         //发送当前字符
    }
}

           

继续阅读