第三次任务
不包括附加任务,下周应该会补充
概述
除图中内容之外,模块化编程部分的知识也是不可或缺的
具体工作状态
可见整体所要呈现的有初始化、调节和计时三种形式
初始化:不涉及数据变化,只有闪烁值得注意
调节模式:在数据加减时要考虑每个变量所对应的范围,所幸只是用八位数码管显示时分秒,若再加上年月日or Date,还要考虑闰年、每个月的长短等,代码又得长一大截;另一难点为调节位的闪烁,第一闪烁周期与初始化中“-”的闪烁周期不同,第二闪烁位置要与所调节位置即按下的按键相对应
计时模式:要实现时间的流动,就须在循环中加入功能与“DS1302_ReadTime”相同的函数/模块来读出DS1302时钟内数据并赋给数组中相应位置的变量,最后得以显示;闪烁的位置和周期都与初始化中相同,故可直接CV
代码
整体内容
#include <REGX52.H>
#include "DS1302.h"
#include "Key.h"
#include "TubeShow.h"
#include "Delay.h"
void Timer0Init(void)
{
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = 0x9C;
TH0 = 0xFF;
TF0 = 0;
TR0 = 1;
ET0=1;
EA=1;
PT0=0;
}
extern unsigned char Time[];
unsigned char keynumber,mode=0,change=0,turn=0,decide=0;
unsigned int count=0,CNT=0;
void main()
{
Timer0Init();
DS1302_Init();
DS1302_SetTime();
while(1)
{
if(mode==0)
{
if(change==0){Locate(3);P0=0x40;Delay(1);P0=0x00;Locate(6);P0=0x40;Delay(1);P0=0x00;}
if(change==1){Locate(3);P0=0x00;Delay(1);Locate(6);P0=0x00;Delay(1);}
TubeShow(1,1);TubeShow(2,2);
TubeShow(4,0);TubeShow(5,0);
TubeShow(7,0);TubeShow(8,0);
}
keynumber=MetrixKey();
if(keynumber==1 || keynumber==5)
decide=1;
if(keynumber==2 || keynumber==6)
decide=2;
if(keynumber==3 || keynumber==7)
decide=3;
if(keynumber==4)
mode=1;
if(keynumber==8)
{
mode=2;
DS1302_SetTime();
}
switch(mode)
{
case 1:
count=0;
if(keynumber==1){
if(Time[3]==23)
Time[3]=0;
else
Time[3]+=1;
}
if(keynumber==2){
if(Time[4]==59)
{
Time[4]=0;
if(Time[3]==23)
Time[3]=0;
else
Time[3]+=1;
}
else
Time[4]+=1;
}
if(keynumber==3){
if(Time[5]==59)
{
Time[5]=0;
if(Time[4]==59)
{
Time[4]=0;
if(Time[3]==23)
Time[3]=0;
else
Time[3]+=1;
}
else
Time[4]+=1;
}
else
Time[5]+=1;
}
if(keynumber==5){
if(Time[3]==0)
Time[3]=23;
else
Time[3]-=1;
}
if(keynumber==6){
if(Time[4]==0)
{
Time[4]=59;
if(Time[3]==0)
Time[3]=23;
else
Time[3]-=1;
}
else
Time[4]-=1;
}
if(keynumber==7){
if(Time[5]==0)
{
Time[5]=59;
if(Time[4]==0)
{
Time[4]=59;
if(Time[3]==0)
Time[3]=23;
else
Time[3]-=1;
}
else
Time[4]-=1;
}
else
Time[5]-=1;
}
Locate(3);P0=0x40;Delay(1);P0=0x00;
Locate(6);P0=0x40;Delay(1);P0=0x00;
if(decide==1 && turn==1)
{Locate(1);P0=0x00;Locate(2);P0=0x00;}
else{TubeShow(1,Time[3]/10);TubeShow(2,Time[3]%10);}
if(decide==2 && turn==1)
{Locate(4);P0=0x00;Locate(5);P0=0x00;}
else{TubeShow(4,Time[4]/10);TubeShow(5,Time[4]%10);}
if(decide==3 && turn==1)
{Locate(7);P0=0x00;Locate(8);P0=0x00;}
else{TubeShow(7,Time[5]/10);TubeShow(8,Time[5]%10);}
break;
case 2:
DS1302_ReadTime();
if(change==0){Locate(3);P0=0x40;Delay(1);P0=0x00;Locate(6);P0=0x40;Delay(1);P0=0x00;}
if(change==1){Locate(3);P0=0x00;Delay(1);Locate(6);P0=0x00;Delay(1);}
TubeShow(1,Time[3]/10);TubeShow(2,Time[3]%10);
TubeShow(4,Time[4]/10);TubeShow(5,Time[4]%10);
TubeShow(7,Time[5]/10);TubeShow(8,Time[5]%10);
break;
}
}
}
void Timer0Routine() interrupt 1
{
TL0 = 0x9C;
TH0 = 0xFF;
count++;
CNT++;
if(count>=5000)
{
if(change==0)
change=1;
else
change=0;
count=0;
}
if(CNT==2500)
{
if(turn==0)
turn=1;
else
turn=0;
CNT=0;
}
}
DS1302模块
#include <REGX52.H>
sbit DS1302_SCLK=P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;
#define YEAR 0X8C
#define MONTH 0X88
#define DATE 0X86
#define HOUR 0X84
#define MINUTE 0X82
#define SECOND 0X80
#define DAY 0X8A
#define WP 0X8E
void DS1302_Init(void)
{
DS1302_CE=0;
DS1302_SCLK=0;
}
unsigned char Time[]={23,12,8,12,00,00};
void DS1302_WriteByte(unsigned char Command,Data)
{
unsigned char i;
DS1302_CE=1;
for(i=0;i<8;i++)
{
DS1302_IO=Command&(0x01<<i);
DS1302_SCLK=1;
//
DS1302_SCLK=0;
}
for(i=0;i<8;i++)
{
DS1302_IO=Data&(0x01<<i);
DS1302_SCLK=1;
DS1302_SCLK=0;
}
DS1302_CE=0;
}
unsigned char DS1302_ReadByte(unsigned char Command)
{
unsigned char i,Data=0x00;
DS1302_CE=1;
Command=Command|0x01;
for(i=0;i<8;i++)
{
DS1302_IO=Command&(0x01<<i);
DS1302_SCLK=0;
DS1302_SCLK=1;
}
for(i=0;i<8;i++)
{
DS1302_SCLK=1;
DS1302_SCLK=0;
if(DS1302_IO){Data|=(0x01<<i);}
}
DS1302_CE=0;
DS1302_IO=0;
return Data;
}
void DS1302_SetTime(void)
{
DS1302_WriteByte(WP,0x00);
DS1302_WriteByte(YEAR,Time[0]/10*16+Time[0]%10);
DS1302_WriteByte(MONTH,Time[1]/10*16+Time[1]%10);
DS1302_WriteByte(DATE,Time[2]/10*16+Time[2]%10);
DS1302_WriteByte(HOUR,Time[3]/10*16+Time[3]%10);
DS1302_WriteByte(MINUTE,Time[4]/10*16+Time[4]%10);
DS1302_WriteByte(SECOND,Time[5]/10*16+Time[5]%10);
DS1302_WriteByte(WP,0x80);
}
void DS1302_ReadTime(void)
{
unsigned char temp;
temp=DS1302_ReadByte(YEAR);
Time[0]=temp/16*10+temp%16;
temp=DS1302_ReadByte(MONTH);
Time[1]=temp/16*10+temp%16;
temp=DS1302_ReadByte(DATE);
Time[2]=temp/16*10+temp%16;
temp=DS1302_ReadByte(HOUR);
Time[3]=temp/16*10+temp%16;
temp=DS1302_ReadByte(MINUTE);
Time[4]=temp/16*10+temp%16;
temp=DS1302_ReadByte(SECOND);
Time[5]=temp/16*10+temp%16;
}
Key模块
#include <REGX52.H>
#include "Delay.h"
unsigned char MetrixKey()
{
unsigned char num=0;
P1=0xFF;
P1_3=0;
if(P1_7==0){Delay(20);while(P1_7==0)Delay(10);num=1;}
if(P1_6==0){Delay(20);while(P1_6==0)Delay(10);num=5;}
if(P1_5==0){Delay(20);while(P1_5==0)Delay(10);num=9;}
if(P1_4==0){Delay(20);while(P1_4==0)Delay(10);num=13;}
P1=0xFF;
P1_2=0;
if(P1_7==0){Delay(20);while(P1_7==0)Delay(10);num=2;}
if(P1_6==0){Delay(20);while(P1_6==0)Delay(10);num=6;}
if(P1_5==0){Delay(20);while(P1_5==0)Delay(10);num=10;}
if(P1_4==0){Delay(20);while(P1_4==0)Delay(10);num=14;}
P1=0xFF;
P1_1=0;
if(P1_7==0){Delay(20);while(P1_7==0)Delay(10);num=3;}
if(P1_6==0){Delay(20);while(P1_6==0)Delay(10);num=7;}
if(P1_5==0){Delay(20);while(P1_5==0)Delay(10);num=11;}
if(P1_4==0){Delay(20);while(P1_4==0)Delay(10);num=15;}
P1=0xFF;
P1_0=0;
if(P1_7==0){Delay(20);while(P1_7==0)Delay(10);num=4;}
if(P1_6==0){Delay(20);while(P1_6==0)Delay(10);num=8;}
if(P1_5==0){Delay(20);while(P1_5==0)Delay(10);num=12;}
if(P1_4==0){Delay(20);while(P1_4==0)Delay(10);num=16;}
return num;
}
Delay模块
void Delay(unsigned char xms)
{
unsigned char data i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
TubeShow数码管显示模块
#include <REGX52.H>
#include "Delay.h"
void TubeShow(unsigned char location,number)
{
switch(location){
case 1:P2_4=1;P2_3=1;P2_2=1; break;
case 2:P2_4=1;P2_3=1;P2_2=0; break;
case 3:P2_4=1;P2_3=0;P2_2=1; break;
case 4:P2_4=1;P2_3=0;P2_2=0; break;
case 5:P2_4=0;P2_3=1;P2_2=1; break;
case 6:P2_4=0;P2_3=1;P2_2=0; break;
case 7:P2_4=0;P2_3=0;P2_2=1; break;
case 8:P2_4=0;P2_3=0;P2_2=0; break;
}
switch (number){
case 0:P0=0x3f;break;
case 1:P0=0x06;break;
case 2:P0=0x5b;break;
case 3:P0=0x4f;break;
case 4:P0=0x66;break;
case 5:P0=0x6d;break;
case 6:P0=0x7d;break;
case 7:P0=0x07;break;
case 8:P0=0x7f;break;
case 9:P0=0x6f;break;
}
Delay(1);
P0=0x00;
}
void Num(unsigned char number){
switch (number){
case 0:P0=0x3f;break;
case 1:P0=0x06;break;
case 2:P0=0x5b;break;
case 3:P0=0x4f;break;
case 4:P0=0x66;break;
case 5:P0=0x6d;break;
case 6:P0=0x7d;break;
case 7:P0=0x07;break;
case 8:P0=0x7f;break;
case 9:P0=0x6f;break;
}
}
void Locate(unsigned char location){
switch(location){
case 1:P2_4=1;P2_3=1;P2_2=1; break;
case 2:P2_4=1;P2_3=1;P2_2=0; break;
case 3:P2_4=1;P2_3=0;P2_2=1; break;
case 4:P2_4=1;P2_3=0;P2_2=0; break;
case 5:P2_4=0;P2_3=1;P2_2=1; break;
case 6:P2_4=0;P2_3=1;P2_2=0; break;
case 7:P2_4=0;P2_3=0;P2_2=1; break;
case 8:P2_4=0;P2_3=0;P2_2=0; break;
}
}