题目
这道题也是十分简单,我们把大模板敲好,写入ds18b20和ds1302底层,再来读题目。
题目很短
按键功能
题目要求的是独立按键,从s4到s7,s4是常规的界面切换功能,s5s6s7都是在时钟界面有效,对时间数据的修改,对于时间数据的修改,我们需要注意,ds1302存储的数据是bcd码16进制的。我们在判断取值范围的时候,得对bcd码进行特殊判断
比如说时钟,0~9正常加一,9~10的时候,bcd码是a,我们就得把这部分特殊判断,让bcd码的高四位加一,低四位清零,得到10。修改完时间数组后,我们记得要把修改完的值写入ds1302里面。
/*按键函数区域*/
void Key_Proc(){
unsigned char t1;
if(Key_Slow) return;
else Key_Slow = 1;
Key_Val = Key_Read();
Key_Down = Key_Val & (Key_Val ^ Key_Old);
Key_Up = ~Key_Val & (Key_Val ^ Key_Old);
Key_Old = Key_Val;
if(Key_Down == 4) Seg_Mode ^= 1;
if(Seg_Mode == 0){//时间界面
if(Key_Down == 5){//时钟加一
t1 = Time[0]/16;
if(Time[0]%16 == 9){//逢九进一
t1++;
Time[0] = t1*16;
}
else if(Time[0] == 0x23) Time[0] = 0x00;
else Time[0]++;
Time_Write(Time);
}
if(Key_Down == 6){//分钟加一
t1 = Time[1]/16;
if(Time[1]%16 == 9){
t1++;
if(t1==0x06) t1 = 0x00;
Time[1] = t1*16;
}
else Time[1]++;
Time_Write(Time);
}
if(Key_Down == 7){//秒钟清零
Time[2] = 0;
Time_Write(Time);
}
}
}
显示功能
这套题就两个界面,都是很基础的显示功能,也就不再赘述了
switch(Seg_Mode){
case 0://时间界面
Point[6] = 0;
Seg_Buf[0] = Time[0]/16;
Seg_Buf[1] = Time[0]%16;
Seg_Buf[2] = 11;//-
Seg_Buf[3] = Time[1]/16;
Seg_Buf[4] = Time[1]%16;
Seg_Buf[5] = 11;//-
Seg_Buf[6] = Time[2]/16;
Seg_Buf[7] = Time[2]%16;
break;
case 1://温度界面
Seg_Buf[0] = 12;//C
Seg_Buf[1] = 10;
Seg_Buf[2] = 10;
Seg_Buf[3] = 10;
Seg_Buf[4] = 10;
Seg_Buf[5] = (unsigned char)tempature/10;
Point[6] = 1;
Seg_Buf[6] = (unsigned char)tempature%10;
Seg_Buf[7] = (unsigned int)(tempature*10)%10;
break;
}
报警功能
整点继电器吸合报警,我们在读取时间之后对时间进行判断即可,定义一个3s计时标志位来判断,也可以用ds1302的数据来判断,但我本人更倾向于定义一个标志位来判断,不容易出错。
Time_Read(Time);
if(Time[1] == 0x00 && Time[2] == 0x00){
Relay_flash = 1;
}
//定时器0中断服务函数里面
if(Relay_flash){
if(++Time_3s == 3000){
Relay_flash = 0;
Time_3s = 0;
}
}
else Time_3s = 0;
指示灯功能
两个Led灯和显示界面有关,很简单,不多说
/*Led函数区域*/
void Led_Proc(){
Led_Buf[0] = (Seg_Mode==0);
Led_Buf[1] = (Seg_Mode==1);
Relay(Relay_flash);//继电器
}
完整主函数
/*头文件区域*/
#include <STC15F2K60S2.H>
#include <Key.h>
#include <Seg.h>
#include <Init.h>
#include <Led.h>
#include <onewire.h>
#include <ds1302.h>
#include <intrins.h>
/*参数变量区域*/
unsigned char Key_Slow,Seg_Slow;
unsigned char Seg_Pos;
unsigned char Key_Down,Key_Up,Key_Old,Key_Val;
//数组
unsigned char Seg_Buf[] = {10,10,10,10,10,10,10,10};
unsigned char Led_Buf[] = {0,0,0,0,0,0,0,0};
unsigned char Point[] = {0,0,0,0,0,0,0,0};
unsigned char Time[3] = {0x00,0x59,0x50};
//标志位
bit Relay_flash;
unsigned int Time_3s;
unsigned char Seg_Mode;//0时间界面,1温度界面
unsigned char hour;//时钟
unsigned char minite;//分钟
float tempature;
/*按键函数区域*/
void Key_Proc(){
unsigned char t1;
if(Key_Slow) return;
else Key_Slow = 1;
Key_Val = Key_Read();
Key_Down = Key_Val & (Key_Val ^ Key_Old);
Key_Up = ~Key_Val & (Key_Val ^ Key_Old);
Key_Old = Key_Val;
if(Key_Down == 4) Seg_Mode ^= 1;
if(Seg_Mode == 0){//时间界面
if(Key_Down == 5){
t1 = Time[0]/16;
if(Time[0]%16 == 9){//逢九进一
t1++;
Time[0] = t1*16;
}
else if(Time[0] == 0x23) Time[0] = 0x00;
else Time[0]++;
Time_Write(Time);
}
if(Key_Down == 6){
t1 = Time[1]/16;
if(Time[1]%16 == 9){
t1++;
if(t1==0x06) t1 = 0x00;
Time[1] = t1*16;
}
else Time[1]++;
Time_Write(Time);
}
if(Key_Down == 7){
Time[2] = 0;
Time_Write(Time);
}
}
}
/*数码管函数区域*/
void Seg_Proc(){
if(Seg_Slow ) return;
Seg_Slow = 1;
tempature = re_tempature();
Time_Read(Time);
if(Time[1] == 0x00 && Time[2] == 0x00){
Relay_flash = 1;
}
switch(Seg_Mode){
case 0://时间界面
Point[6] = 0;
Seg_Buf[0] = Time[0]/16;
Seg_Buf[1] = Time[0]%16;
Seg_Buf[2] = 11;//-
Seg_Buf[3] = Time[1]/16;
Seg_Buf[4] = Time[1]%16;
Seg_Buf[5] = 11;//-
Seg_Buf[6] = Time[2]/16;
Seg_Buf[7] = Time[2]%16;
break;
case 1://温度界面
Seg_Buf[0] = 12;//C
Seg_Buf[1] = 10;
Seg_Buf[2] = 10;
Seg_Buf[3] = 10;
Seg_Buf[4] = 10;
Seg_Buf[5] = (unsigned char)tempature/10;
Point[6] = 1;
Seg_Buf[6] = (unsigned char)tempature%10;
Seg_Buf[7] = (unsigned int)(tempature*10)%10;
break;
}
}
/*Led函数区域*/
void Led_Proc(){
Led_Buf[0] = (Seg_Mode==0);
Led_Buf[1] = (Seg_Mode==1);
Relay(Relay_flash);//继电器
}
/*定时器0初始化函数区域*/
void Timer0_Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x20; //设置定时初始值
TH0 = 0xD1; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
EA = 1;
}
/*定时器0中断服务函数区域*/
void Timer0_Service() interrupt 1
{
if(++Seg_Slow == 200) Seg_Slow = 0;
if(++Key_Slow == 50) Key_Slow = 0;
if(++Seg_Pos == 8) Seg_Pos = 0;
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Point[Seg_Pos]);
Led_Disp(Seg_Pos,Led_Buf[Seg_Pos]);
if(Relay_flash){
if(++Time_3s == 3000){
Relay_flash = 0;
Time_3s = 0;
}
}
else Time_3s = 0;
}
void Delay750ms(void) //@12.000MHz
{
unsigned char data i, j, k;
_nop_();
_nop_();
i = 35;
j = 51;
k = 182;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/*主函数区域*/
void main(){
Sys_Init();
Timer0_Init();
Time_Write(Time);
re_tempature();
Delay750ms();
while(1){
Led_Proc();
Key_Proc();
Seg_Proc();
}
}
这道题也是很简单的,一次过