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) //1200bps@11.0592MHz
{
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++); //发送当前字符
}
}