#include <reg51.H>
#define uchar unsigned char
#define uint unsigned int
#define SPEED 5 //移动数度快慢值
//#define num 10
uchar code HZ[];
//uchar code SHUZI[];
uchar code SHIJIAN[];
/**************基本变量的设置************************************/
sbit en=P2^7;
sbit lck=P2^6;
sbit skl=P2^5;
uchar col,disrow;
uchar BUFF[6];
/**************按键切换的变量************************************/
sbit qiehuan=P0^7;
sbit jia=P0^6;
sbit jian=P0^5;
sbit shijian=P0^4;
uchar flag_key;
uchar flag_hanzi=1,flag_shuzi=1,flag_shijian=1;
uchar moshi=0,hanzi[]={0,12,24},hanzi_num[]={10,10,19},hanzi_xiabiao;//shijian;
void jianche_key();
void qiehuan_done();
void qiehuan_key();
void Write1302(unsigned char ucAddr, unsigned char ucDa);
unsigned char Read1302(unsigned char ucAddr);
/********************按键调整时间的变量***********************************************/
char hide_sec,hide_min,hide_hour,hide_day,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数
char done=0,count,temp,flag,up_flag,down_flag;
sbit Set=P0^3;
sbit Up=P0^2;
sbit Down=P0^1;
sbit out=P0^0;
/**************显示汉字的变量************************************/
uint word=0;
uchar num=10;
/*******************************************************************/
/*******************************************************************/
/*********************显示数字的变量***********************************/
uchar shuzi_i=0,shuzi_b=0,shuzi_x=0;
uchar shuzi_xiabiao;
uchar a[]={0x0a,0x0a,0x0a,0x0a,0,1,2,3,4,5,6,7,8,9,0x0a,0x0a,0x0a,0x0a};
uchar code english[]={0x0a,0x0a,0x0a,0x0a,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,0x0a,0x0a,0x0a,0x0a};
uchar shuzi_num[]={14,21};
/*******************************************************************/
/******************显示时间的变量****************************************/
/*******************************************************************/
uchar shijian_i=0,shijian_b=0,shijian_x=0;
void show_time();
/*****************时钟变量*********************/
/********************************************/
sbit DS1302_CLK = P2^0; //实时时钟时钟线引脚
sbit DS1302_IO = P2^1; //实时时钟数据线引脚
sbit DS1302_RST = P2^2; //实时时钟复位线引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
/***********DS1302时钟部分子程序******************/
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[27];
unsigned char Time[]={0,9,0,7,2,6,0,9,5,8,4,0};
/********************************************/
#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
/*********************************************/
/******************基本的子程序,下面是发送一个字节*****************************************/
void txd_data(unsigned char d)
{
unsigned char h=8;
while(1)
{
skl= 0x01&d; //取出第零位数
lck=1; //发送时钟信号
lck=0;
d =d>>1; //右移一位
if(--h==0) break;
}
}
/*********************下面是两个字节数据的组合成新*****************************************/
uchar two_onebyte(uchar h1,uchar h2)
{
uchar temp,tempcol;
if(col<8) tempcol=col;
else tempcol=col-8;
temp=(h1<<tempcol)|(h2>>(8-tempcol));
temp=255-temp;
return temp;
}
/*******************************************************************/
/*********************显示汉字的程序***************************************/
/**************装载一线点阵数据****************/
void loadoneline_hanzi(void)
{
uchar s;
for(s=0;s<3;s++) //s为要显示的数字+1
{
BUFF[2*s]=HZ[word+32*s+2*disrow];
BUFF[2*s+1]=HZ[word+1+32*s+2*disrow];
}
}
/***************发送一线点阵数据*******************/
void sendoneline_hanzi(void)
{
char s;uchar inc,shuju;
if(col<8) inc=0;else inc=1;
for(s=5+inc;s>=0+inc;s--) //s*2为要显示的数字+1
{
shuju=two_onebyte(BUFF[s],BUFF[s+1]);
txd_data(shuju);
}
}
/****************************主函数***************************/
void display_hanzi(void)
{ uchar i;
while(flag_hanzi)
{
while(col<16)// 循环16次,点亮并移动一个汉字
{
for(i=0;i<SPEED;i++)//汉字在屏幕上的停留时间(即移动速度快慢)
{
for(disrow=0;disrow<16;disrow++)//扫描16行
{
loadoneline_hanzi();//装载一线点阵数据
sendoneline_hanzi();//发送一线点阵数据
en=1; //消影。 E接在P1_4=1;
en=0;
P1=0x10+disrow;// 点亮屏幕
P1=0x20+disrow;
}
}
col++; //列指针递增
}
col=0;
word=word+32; // 一个汉字移动后,指向下一个汉字
if(word>=(hanzi[hanzi_xiabiao]*32+hanzi_num[hanzi_xiabiao]*32)) word=hanzi[hanzi_xiabiao]*32; // 移动17个汉字后,重新开始
jianche_key();
if(flag_key) flag_hanzi=0;
}
qiehuan_done();
}
/****************************************************************************/
/****************************上面是显示汉字的程序*******************************************/
/****************************************************************************/
/*****************显示数字的程序*************************************************/
/*******************串口通信**************************/
void UARTSET()
{
TMOD=0X21; //定时器1方式1,8位自动重装模式(用于波特率产生)。定时器0为模式1,16位串接方式
SCON=0x50; //串口为模式1,一位起始位,8位数据位,一位停止位。启动串口。
TH1=0XFD; //波特率为9600
TH0=0X3C; //50ms定时器。
TL0=0XB0;
TR0=1; //启动定时器0
TR1=1; //启动定时器1
PS=1; //串口中断优先
ES=1; //开启串口中断
ET0=1; //开启定时器0中断
EA=1; //开启总中断
}
void UART()interrupt 4
{
EA=0;
if(moshi==1)
{if(RI)
{RI=0;
a[shuzi_x+4]=SBUF;
}
shuzi_x=shuzi_x+1;
if(shuzi_x==11) shuzi_x=0;
}
if(moshi==2)
{ if(RI)
{RI=0;
Time[shijian_x]=SBUF;
}
shijian_x=shijian_x+1;
if(shijian_x==12|SBUF==10) shijian_x=0;
Write1302(0x8e,0x00); //写入允许
Write1302(0x8c,(Time[0]<<4)+Time[1]); //以下写入初始化时间 日期:07/07/25.星期: 7. 时间: 23:59:55
Write1302(0x88,(Time[2]<<4)+Time[3]);
Write1302(0x86,(Time[4]<<4)+Time[5]);
Write1302(0x84,(Time[6]<<4)+Time[7]);
Write1302(0x82,(Time[8]<<4)+Time[9]);
Write1302(0x80,(Time[10]<<4)+Time[11]);
Write1302(0x8e,0x80); //禁止写入
}
EA=1;
} //读取串口数据
/***********************************************/
/**************装载一线点阵数据****************/
void loadoneline_shuzi(void)
{
uchar s,i=shuzi_b;
if(shuzi_xiabiao==0)
for(s=0;s<6;s++) //s为要显示的数字+1
{
BUFF[s]=SHIJIAN[16*a[i]+disrow];
i++;
}
if(shuzi_xiabiao==1)
for(s=0;s<6;s++) //s为要显示的数字+1
{
BUFF[s]=SHIJIAN[16*english[i]+disrow];
i++;
}
}
/***************发送一线点阵数据*******************/
void sendoneline_shuzi(void)
{
char s;uchar shuju;
for(s=5;s>=0;s--) //s*2为要显示的数字+1
{
shuju=two_onebyte(BUFF[s],BUFF[s+1]);
txd_data(shuju);
}
}
/****************************显示数字的主函数***************************/
void display_shuzi(void) //reentrant
{ uchar i;
col=0;
UARTSET();
while(flag_shuzi)
{
while(col<8)// 循环16次,点亮并移动一个汉字
{ for(i=0;i<SPEED;i++)//汉字在屏幕上的停留时间(即移动速度快慢)
{
for(disrow=0;disrow<16;disrow++)//扫描16行
{
loadoneline_shuzi();//装载一线点阵数据
sendoneline_shuzi