📄 texiandclock.c
字号:
#include<reg51.h>
#include <math.h>
#include <intrins.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
/* DS12887实时时钟时间地址设置 */
#define second XBYTE [0x6000] /* 秒寄存器地址 */
#define sec_alarm XBYTE [0x6001]
#define minute XBYTE [0x6002] /* 分寄存器地址 */
#define min_alarm XBYTE [0x6003]
#define hour XBYTE [0x6004] /* 小时寄存器地址 */
#define week XBYTE [0x6006] /* 星期寄存器地址 */
#define date XBYTE [0x6007] /* 日期寄存器地址 */
#define month XBYTE [0x6008] /* 月寄存器地址 */
#define year XBYTE [0x6009] /* 年寄存器地址 */
#define rega XBYTE [0x600A] /* A寄存器地址 */
#define regb XBYTE [0x600B] /* B寄存器地址 */
#define regc XBYTE [0x600C] /* C寄存器地址 */
#define regd XBYTE [0x600D] /* D寄存器地址 */
/* RT12864HZ汉字图形点阵液晶地址设置 */
#define w_c_add XBYTE[0x2070] /* 写命令字地址 */
#define w_d_add XBYTE[0x2071] /* 写数据地址 */
#define r_s_add XBYTE[0x2072] /* 读状态字地址 */
#define r_d_add XBYTE[0x2073] /* 读数据地址 */
#define COM XBYTE[0x2021] /*8279命令口 */
#define DAT XBYTE[0x2020] /*8279数据口 */
#define L 1 /*长度系数 */
#define TI 50 /*分度数*/
#define HN 30 /*孔个数 */
#define LOW 30 /*最低速度 */
uchar xdata key; /*键值 */
uint idata num=0; /*计数值 */
uint xdata a=1,b=0;
uint idata len,fa,m,n,o,p,q,r,s,t,COUT,CLO;
uint idata h1,h2,m1,m2,s1,s2; /*时钟参数*/
uint idata price=10,fate=00,length=0,leng;
uint idata state=0,clear=1,begin=0,pri,tim,tt=0,cc=0;nn=0;/*几个状态标志位*/
/*设置,清除,开始计价,单价修改,时间修改,两位数监视,六位数监视,数字标志*/
unsigned char bdata status; /* lcd可位寻址片内数据存储器,允许位与字节混合访问 */
sbit busy=status^7; /*lcd“忙”线的第7位*/
uchar bdata sta_8279; /*8279*/
sbit du=sta_8279^7; /* 8279方式设置命令字 */
unsigned char rflag;
unsigned char bdata sta_ds;
sbit uip=sta_ds^7;
uchar ds_h,ds_m,ds_s,ds_t;
unsigned char bdata ds_time;
unsigned char code NO[10]={0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9};
uchar code tab[16]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,
0x71,0x7C,0x39,0x73,0x31,0x71};/* 0~F的字型编码*/
uchar xdata hz2[16]={0xB5,0xA5,0xBC,0xDB,0xA3,0xBA,0x20,0x20,0x20,0x20,
/* 单 价 : 空 空 */
0xA3,0xB0,0xA3,0xB0,0xD4,0xAA};
/* N N 元 */
uchar xdata hz3[16]={0xBE,0xE0,0xC0,0xEB,0xA3,0xBA,0xA3,0xB0,0xA3,0xB0,
/* 距 离 : 空 N */
0xA3,0xB0,0xA3,0xB0,0x4B,0x4D};
/* N N k m */
uchar xdata hz4[16]={0xBC,0xDB,0xC7,0xAE,0xA3,0xBA,0xA3,0xB0,0xA3,0xB0,
/* 价 格 : N N */
0xA3,0xB0,0xA3,0xB0,0xD4,0xAA};
/* N N 元 */
uchar xdata hz5[16]={0x20,0x20,0xCA,0xE4,0xC8,0xEB,0xC1,0xBD,0xCE,0xBB,
/* 空 输 入 两 位 */
0xB5,0xA5,0xBC,0xDB,0x20,0x20};
/* 单 价 空 */
uchar xdata hz6[16]={0x20,0x20,0x20,0x20,0xA3,0xBA,0xA3,0xB0,0xA3,0xB0,
/* 空 空 : N N */
0xD4,0xAA,0xA3,0xAF,0x4B,0x4D};
/* 元 / k m */
void initial (void);
void delay(void);
void check_lcd(void);
void show_lcd(uchar *,uchar *,uchar *);
void lcd_busy(void); /*LCD忙状态检测函数 */
void compute(void);
void change_pri(void);
void change_time(void);
void clock(void);
void check_ds12887(void);
main()
{
uint inf=0;
initial();
show_lcd(hz2,hz3,hz4);
while(1)
{
clock();
if(begin==1)
{
if(inf==0)
{
fate=20;
inf=1;
}
if(state==0)
{
if(num>=LOW)
{
COUT=0;
price=a*10+b;
len+=num*L/HN;
if(len/TI>=0)
{
leng=len/TI;
len%=TI;
}
fa=leng*price;
length+=leng;
leng=0;
fate+=fa;
}
else
{
if(COUT>=60)
{
length++;
fate+=(10*a+b);
COUT=0;
}
}
compute();
show_lcd(hz2,hz3,hz4);
}
else
{
if(pri==1)
change_pri();
if(tim==1)
change_time();
}
}
if(clear==1)
{
length=0;
fate=0;
inf=0;
// COM=0xd1; /* 清除显示*/
compute();
show_lcd(hz2,hz3,hz4);
if(pri==1)
change_pri();
if(tim==1)
change_time();
}
}//while(1)
}//main
/********************以下是程序(包括中断)********************************/
void keybord(void) interrupt 0 using 1
{
uchar keyboard=0;
EX0=0;
COM=0x50;
keyboard=DAT;
keyboard &=0x0f; /* 保留低四位 */
switch(keyboard)
{ case 0x0: key=0; tt++;nn=1;cc++; break;
case 0x1: key=1; tt++;nn=1;cc++; break;
case 0x2: key=2; tt++;nn=1;cc++; break;
case 0x3: key=3; tt++;nn=1;cc++; break;
case 0x4: key=4; tt++;nn=1;cc++; break;
case 0x5: key=5; tt++;nn=1;cc++; break;
case 0x6: key=6; tt++;nn=1;cc++; break;
case 0x7: key=7; tt++;nn=1;cc++; break;
case 0x8: key=8; tt++;nn=1;cc++; break;
case 0x9: key=9; tt++;nn=1;cc++; break;
case 0x0B: key=11; begin=1;clear=0;nn=0;break; /*B begin*/
case 0x0C: key=12; clear=1;begin=0;nn=0;break; /*C clear*/
case 0X0D: key=13; state=1;pri=1;tim=0;nn=0;break; /*D set price*/
case 0x0E: key=14; state=1;tim=1;pri=0;nn=0;break; /*E set time*/
default: key=15; nn=0;break; /*F finish*/
}
keyboard=tab[keyboard];
if(pri==1)
if(nn==0)
COM=0x80+8;
else
COM=0x80+4+tt;
if(tim==1)
if(nn==0)
COM=0x80+8;
else
COM=0x80+1+cc;
DAT=keyboard;
EX0=1;
}
void int1serve() interrupt 2 using 2
{
unsigned char temp2;
COUT++;
EX1=0;
rflag=1;
sta_ds=rega;
while(uip);
ds_h=hour;
ds_m=minute;
ds_s=second;
temp2=regc;
rflag=0;
EX1=1;
}
void timer(void) interrupt 3 using 3
{
TR1=0;
TR0=0;
num=TH0*256+TL0;
TH0=0;
TL0=0;
TH1=-(50000/256);
TL1=-(50000%256);
CLO++;
TR1=1;
TR0=1;
}
void initial(void)
{
COM=0xd1; /* 清除显示*/
ACC=DAT;
if(ACC^1); /* P奇偶标志。若值为1的位数为奇数,则P置位,否则清除 */
COM=0x00; /* 8字符显示左入口 */
COM=0x34; /* 34次分频*/
TMOD=0X15;
TH0=0;
TL0=0;
TH1=-(50000/256);
TL1=-(50000%256);
TR0=1;
TR1=1;
EA=1;
EX0=1;
EX1=1;
ET1=1;
check_ds12887();
}
void delay(void)
{
unsigned char i,j;
for(i=0;i<100;i++)
{
for(j=0;j<150;j++)
{
;
;
}
}
}
void check_lcd(void)
{
uint i;
lcd_busy();
w_c_add=0x30;/* 功能设置:8位数据 */
for(i=0;i<255;i++)
lcd_busy();
w_c_add=0x0c; /* 显示状态:整体显示,游标位置无效*/
lcd_busy();
w_c_add=0x01;/* 清除显示:将DDRAM填满“20H”,并且设定DDRAM的地址计数器到“00”*/
lcd_busy();
w_c_add=0x02;/* 地址归位:设定DDRAM的地址计数器到“00”,将游标移到开头原点位置 */
}
void show_lcd (uchar *b1,uchar *c1,uchar *d1)
{
unsigned char add;
unsigned char i;
check_lcd();
lcd_busy();
add=0x90; /* 设置显示坐标,90H对应字符的第二行第一列 */
lcd_busy();
w_c_add=add; /* 送命令 */
for(i=0;i<8;i++)
{
lcd_busy();
w_d_add=b1[2*i];
lcd_busy();
w_d_add=b1[2*i+1];
}
add=0x88; /* 设置显示坐标,88H对应字符的第三行第一列 */
lcd_busy();
w_c_add=add; /* 送命令 */
for(i=0;i<8;i++)
{
lcd_busy();
w_d_add=c1[2*i];
lcd_busy();
w_d_add=c1[2*i+1];
}
add=0x98; /* 设置显示坐标,98H对应字符的第四行第一列 */
lcd_busy();
w_c_add=add; /* 送命令 */
for(i=0;i<8;i++)
{
lcd_busy();
w_d_add=d1[2*i];
lcd_busy();
w_d_add=d1[2*i+1];
}
delay();
clock();
}
void lcd_busy(void) /*LCD忙状态检测函数 */
{
do
{
status=r_s_add; /* 读状态字地址的第7位 */
}
while(busy);
}
void compute(void)
{
uint f1,l1;
f1=fate;
l1=length;
p=l1%10; /*数字位拆分**路程*/
l1/=10;
o=l1%10;
l1/=10;
n=l1%10;
l1/=10;
m=l1%10;
t=f1%10; /*数字位拆分**价钱*/
f1/=10;
s=f1%10;
f1/=10;
r=f1%10;
f1/=10;
q=f1%10;
hz2[11]=hz2[13]=0xB0; /*清零*/
hz3[9]=hz3[11]=hz3[13]=0xB0;
hz4[9]=hz4[11]=hz4[13]=0xB0;
hz2[11]+=a; /*赋值*/
hz2[13]+=b;
hz3[7]+=m;
hz3[9]+=n;
hz3[11]+=o;
hz3[13]+=p;
hz4[7]+=q;
hz4[9]+=r;
hz4[11]+=s;
hz4[13]+=t;
if(COUT%500==0)
{
show_lcd(hz2,hz3,hz4); /*显示*/
}
}
void change_pri()
{
show_lcd(hz2,hz5,hz6);
if(key==15) //15 -> Finish
{
COM=0xd1; /* 清除显示*/
pri=0;
state=0;
tt=0;
hz2[11]=hz6[7];
hz2[13]=hz6[9];
show_lcd(hz2,hz3,hz4);
}
else
{
if(nn)
{
if(tt==1) a=key;
if(tt==2){b=key;tt=0;}
hz6[7]=0xB0;
hz6[7]+=a;
hz6[9]=0xB0;
hz6[9]+=b;
}
show_lcd(hz2,hz5,hz6);
}
}
void change_time(void)
{
uint hh,mm,ss,temper;
if(key==15)
{
tim=0;
state=0;
cc=0;
COM=0xd1; /* 清除显示*/
}
else
{ if(nn)
{
if(cc==1) h1=key;
if(cc==2) h2=key;
if(cc==3) m1=key;
if(cc==4) m2=key;
if(cc==5) s1=key;
if(cc==6) {s2=key;cc=0;}
temper=h1*16;
hh=temper|h2;
temper=m1*16;
mm=temper|m2;
temper=s1*16;
ss=temper|s2;
hour=hh;
minute=mm;
second=ss;
}
clock();
show_lcd(hz2,hz3,hz4);
}
}
void clock()
{
unsigned char temp1;
if (rflag==0)
{
w_c_add=0x80; /* 写命令字:设定DDRAM地址到地址计数器(AC) */
delay();
temp1=ds_h & 0xf0; /* 小时保留高四位 */
ds_t=_cror_(temp1,4); /* 将变量temp1循环右移4位 */
lcd_busy();
w_d_add=0xA3;
lcd_busy();
w_d_add=NO[ds_t]; /* 写数据*/
ds_t=ds_h & 0x0f; /* 小时保留低四位 */
lcd_busy();
w_d_add=0xA3;
lcd_busy();
w_d_add=NO[ds_t]; /* 写数据**小时*/
lcd_busy();
w_d_add=0xA3; /* : */
lcd_busy();
w_d_add=0xBA;
temp1=ds_m & 0xf0;
ds_t=_cror_(temp1,4);
lcd_busy();
w_d_add=0xA3;
lcd_busy();
w_d_add=NO[ds_t]; /* 写数据**分*/
ds_t=ds_m & 0x0f;
lcd_busy();
w_d_add=0xA3;
lcd_busy();
w_d_add=NO[ds_t];
lcd_busy();
w_d_add=0xA3; /* : */
lcd_busy();
w_d_add=0xBA;
temp1=ds_s & 0xf0;
ds_t=_cror_(temp1,4);
lcd_busy();
w_d_add=0xA3;
lcd_busy();
w_d_add=NO[ds_t]; /* 写数据**秒*/
ds_t=ds_s & 0x0f;
lcd_busy();
w_d_add=0xA3;
lcd_busy();
w_d_add=NO[ds_t];
for(temp1=0;temp1<255;temp1++);
delay();
delay();
}
}
void check_ds12887(void)
{
unsigned char temp;
rega=0x2f; /* 开启震荡器,允许计时 */
delay();
regb=0x80;
temp=regc;
temp=regd;
//write time
second=0x00;
minute=0x00;
hour=0x12;
week=0x01;
year=0x03;
month=0x12;
regb=0x42;
//open ex1
EX1=1;
}
/***********************以上是代码**************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -