题目
源码
#include <STC15F2K60S2.H>
#include <intrins.h>
#include "iic.h"
#include "ds1302.h"
#include "onewire.h"
#define KEYPORT P3
#define u8 unsigned char
#define u16 unsigned int
u8 code t_display[]={ //标准字库
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码
u8 key_table[] = {0x88,0x84,0x48,0x44};
u8 screen_table[] = {16,16,16,16,16,16,16,16};
sbit buzzer = P0^6;
sbit relay = P0^4;
u8 readdata,keypress;
u8 Cont,Trg;
u8 shi,fen,miao;
u8 shi_BCD,fen_BCD,miao_BCD;
u8 mode_flag;//模式切换标志位
u8 adc_val;//电压值0-255
u8 LED;
//默认参数
char time_set = 17;
char temperature_set = 25;
char led_set = 4;
//变化参数中间值
char time_temp = 17;
char temperature_temp = 25;
char led_temp = 4;
float temperature;//温度值
float volt;//电压值0-5V
bit key_flag;
bit read_flag;
bit set_flag;//数据和参数界面切换标志位
bit light_flag;//亮暗等级
bit change_flag;//切换界面标志位
void Init()//初始化
{
P2=0x80;P0=0xff;P2=0x00;
P2=0xe0;P0=0xff;P2=0x00;
P2=0xa0;buzzer = 0; relay = 0;P2=0x00;
}
void key_read()//矩阵键盘
{
KEYPORT = 0xf0;
P44 = 1;
P42 = 1;
P36 = P42;
P37 = P44;
keypress = KEYPORT;
KEYPORT = 0x0f;
P44 = 0;
P42 = 0;
readdata = (KEYPORT | keypress) ^ 0xff;
Trg = readdata & (readdata ^ Cont);
Cont = readdata ;
}
//T0初始化
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x20; //设置定时初值
TH0 = 0xD1; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
EA = 1;
}
/* Timer0 interrupt routine */
void tm0_isr() interrupt 1
{
static int smg_count = 0, key_count = 0,read_count = 0,light_count = 0,i = 0;
smg_count++;key_count++;read_count++;
if(smg_count == 1)
{
smg_count = 0;
P2=0xe0;P0=~t_display[screen_table[i]];P2=0x00;
P2=0xc0;P0=T_COM[i];P2=0x00;
i++;
if(i==8)i=0;
}
if(key_count == 10)
{
key_count = 0;
key_flag =1;
}
if(read_count == 200)
{
read_count =0 ;
read_flag = 1;
}
if(light_flag)
{
if(++light_count == 3000)
{
light_count =0;
LED |= 4;
}
}
else
{
if(++light_count == 3000)
{
light_count = 0;
LED &= ~4;
}
}
}
void main()
{
Init();
Timer0Init();
set_sfm(16,59,50);//RTC时钟上电默认时间
while(1)
{
EA = 0;//读取时钟数据
shi_BCD = Read_Ds1302_Byte ( 0x85 );
fen_BCD = Read_Ds1302_Byte ( 0x83 );
miao_BCD = Read_Ds1302_Byte ( 0x81 );
EA = 1;
shi = (((shi_BCD >> 4) & 0x07) * 10 ) + (shi_BCD & 0x0f);
fen = (((fen_BCD >> 4) & 0x07) * 10 ) + (fen_BCD & 0x0f);
miao = (((miao_BCD >> 4) & 0x07) * 10 ) + (miao_BCD & 0x0f);
if(read_flag)
{
read_flag = 0;
temperature = rd_temperature();
EA = 0;
adc_val = read_adc(0x01);
EA = 1;
if(adc_val < 255 / 2)//暗
{
light_flag = 1;
}
else//亮
light_flag = 0;
volt = adc_val / 255.0 * 5;
}
if(key_flag)
{
key_flag = 0;
key_read();
if(Trg == key_table[0])//s4
{
if(set_flag == 1)//当前处于参数界面
{
change_flag = 1;
}
set_flag = ~set_flag;//数据和参数界面切换
if(change_flag == 1 && set_flag == 0)//参数界面->数据界面:变化后的参数生效
{
time_set = time_temp;
temperature_set = temperature_temp;
led_set = led_temp;
}
mode_flag = 0;
}
if(Trg == key_table[1])//s5
{
mode_flag++;
if(mode_flag == 3)
mode_flag = 0;
}
if(Trg == key_table[2])//s8:-
{
if(set_flag == 1)
{
if(mode_flag == 0)
{
time_temp--;
if(time_temp < 0)
{
time_temp = 23;
}
}
else if(mode_flag == 1)
{
temperature_temp--;
if(temperature_temp < 0)
{
temperature_temp = 99;
}
}
else if(mode_flag == 2)
{
led_temp--;
if(led_temp < 4)
{
led_temp = 8;
}
}
}
}
if(Trg == key_table[3])//s9:+
{
if(mode_flag == 0)
{
time_temp++;
if(time_temp > 23)
{
time_temp = 0;
}
}
else if(mode_flag == 1)
{
temperature_temp++;
if(temperature_temp > 99)
{
temperature_temp = 0;
}
}
else if(mode_flag == 2)
{
led_temp++;
if(led_temp > 8)
{
led_temp = 4;
}
}
}
}
if(set_flag == 0)//数据界面
{
if(mode_flag == 0)//时钟显示
{
screen_table[0] = shi / 10;
screen_table[1] = shi % 10;
screen_table[2] = 17;
screen_table[3] = fen / 10;
screen_table[4] = fen % 10;
screen_table[5] = 17;
screen_table[6] = miao / 10;
screen_table[7] = miao % 10;
}
else if(mode_flag == 1)//温度显示
{
screen_table[0] = 12;
screen_table[1] = 16;
screen_table[2] = 16;
screen_table[3] = 16;
screen_table[4] = 16;
screen_table[5] = ((u8)temperature) / 10;
screen_table[6] = (((u8)temperature) % 10) + 32;
screen_table[7] = ((u8)(temperature * 10)) % 10;
}
else if(mode_flag == 2)//LED显示
{
screen_table[0] = 14;
screen_table[1] = 16;
screen_table[2] = (u8)volt + 32;
screen_table[3] = ((u8)(volt * 10)) % 10 ;
screen_table[4] = ((u16)(volt * 100)) % 10;
screen_table[5] = 16;
screen_table[6] = 16;
screen_table[7] = light_flag;
}
}
else//参数界面
{
if(mode_flag == 0)//时钟参数
{
screen_table[0] = 24;
screen_table[1] = 1;
screen_table[2] = 16;
screen_table[3] = 16;
screen_table[4] = 16;
screen_table[5] = 16;
screen_table[6] = time_temp / 10;
screen_table[7] = time_temp % 10;
}
else if(mode_flag == 1)//温度参数
{
screen_table[0] = 24;
screen_table[1] = 2;
screen_table[2] = 16;
screen_table[3] = 16;
screen_table[4] = 16;
screen_table[5] = 16;
screen_table[6] = temperature_temp / 10;
screen_table[7] = temperature_temp % 10;
}
else if(mode_flag == 2)//LED参数
{
screen_table[0] = 24;
screen_table[1] = 3;
screen_table[2] = 16;
screen_table[3] = 16;
screen_table[4] = 16;
screen_table[5] = 16;
screen_table[6] = 16;
screen_table[7] = led_temp;
}
}
/*************************LED显示**************************/
if(shi >= 8)
{
if(shi >= time_set && shi <= 23)
{
LED |= 1;
}
else
{
LED &= ~1;
}
}
else
{
if(shi >= time_set && shi < 8)
{
LED |= 1;
}
else
{
LED &= ~1;
}
}
if(temperature < temperature_set)
{
LED |= 2;
}
else
{
LED &= ~2;
}
if(light_flag == 1)
{
if(led_set == 4)
{
LED |= 8;
LED &= ~0x10;
LED &= ~0x20;
LED &= ~0x40;
LED &= ~0x80;
}
else if(led_set == 5)
{
LED &= ~8;
LED |= 0x10;
LED &= ~0x20;
LED &= ~0x40;
LED &= ~0x80;
}
else if(led_set == 6)
{
LED &= ~8;
LED &= ~0x10;
LED |= 0x20;
LED &= ~0x40;
LED &= ~0x80;
}
else if(led_set == 7)
{
LED &= ~8;
LED &= ~0x10;
LED &= ~0x20;
LED |= 0x40;
LED &= ~0x80;
}
else if(led_set == 8)
{
LED &= ~8;
LED &= ~0x10;
LED &= ~0x20;
LED &= ~0x40;
LED |= 0x80;
}
}
else
{
LED &= ~8;
LED &= ~0x10;
LED &= ~0x20;
LED &= ~0x40;
LED &= ~0x80;
}
P2=0x80;P0 = ~LED ; P2=0x00;//点亮LED
}
}
赛题总结
1.界面切换
解法代码
if(Trg == key_table[0])//s4
{
set_flag = ~set_flag;//数据和参数界面切换
mode_flag = 0;//切换后默认为时间界面
}
2.参数生效
解法代码
if(Trg == key_table[0])//s4
{
if(set_flag == 1)//当前处于参数界面
{
change_flag = 1;
}
set_flag = ~set_flag;//数据和参数界面切换
if(change_flag == 1 && set_flag == 0)//参数界面->数据界面:变化后的参数生效
{
time_set = time_temp;
temperature_set = temperature_temp;
led_set = led_temp;
}
mode_flag = 0;
}
关键在于记录从参数界面到数据界面切换的标志位,按下s4时当前处于参数界面,按下后切换为数据界面
3.LED显示
代码接法
if(shi >= 8)
{
if(shi >= time_set && shi <= 23)
{
LED |= 1;
}
else
{
LED &= ~1;
}
}
else
{
if(shi >= time_set && shi < 8)
{
LED |= 1;
}
else
{
LED &= ~1;
}
}
分为两种情况:
(1)当前时间大于8:00,即就是处于8:00-23:59之间,需要判断(shi >= time_set && shi <= 23);
(2)当前时间小于8:00,即就是处于0:00-8:00之间,则判断(shi >= time_set && shi < 8);
特殊情况
当shi_set和shi相等时,简单理解可以这样说:从今天的8:00到下一天的8:00,全天L1都是点亮的。