数字时钟DS12887程序2.docx
- 文档编号:18392359
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:40
- 大小:25.84KB
数字时钟DS12887程序2.docx
《数字时钟DS12887程序2.docx》由会员分享,可在线阅读,更多相关《数字时钟DS12887程序2.docx(40页珍藏版)》请在冰点文库上搜索。
数字时钟DS12887程序2
用1602液晶来显示DS12C887的日历时钟信息
#include
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#defineda_sedXBYTE[0xfe00]
#defineda_mieXBYTE[0xfe02]
#defineda_horXBYTE[0xfe04]
#defineda_dayXBYTE[0xfe07]
#defineda_mohXBYTE[0xfe08]
#defineda_yearXBYTE[0xfe09]
#defineda_ceyXBYTE[0xfe32]
#definereg_aXBYTE[0xfe0a]
#definereg_bXBYTE[0xfe0b]
#definelcdP1
ucharlcd_flag,num0,num1;
ucharsed,mie,hor,day,moh,year,cey;
ucharcodetable0[]={" - - "};
ucharcodetable1[]={" :
:
"};
sbitlcd_rs=P3^4;
sbitlcd_rw=P3^3;
sbitlcd_en=P3^2;
sbitbusy=P1^7;
/*DS12C887函数声明部分*/
voidda_init();
voidda_read();
voidda_write();
voidda_check_bf();
/*液晶1602函数部分*/
voidlcd_init();
voidlcd_write_com(uchar);
voidlcd_write_data(uchar);
voidlcd_check_bf();
/*显示函数部分*/
voiddisplay_sed();
voiddisplay_mie();
voiddisplay_hor();
voiddisplay_day();
voiddisplay_moh();
voiddisplay_year();
voiddisplay_cey();
voiddelay(uint);
/**********************************************************
主函数
**********************************************************/
voidmain()
{lcd_init();
for(num0=0;num0<=9;num0++)
lcd_write_data(table0[num0]);
lcd_write_com(0x80+0x40);
for(num1=0;num1<=7;num1++)
lcd_write_data(table1[num1]);
lcd_write_com(0x80);
da_init();
da_write();
while
(1)
{da_read();
display_sed();
display_mie();
display_hor();
display_day();
display_moh();
display_year();
display_cey();
}
}
/**********************************************************
液晶1602初始化函数
**********************************************************/
voidlcd_init()
{lcd_en=0;
lcd_flag=0;
delay(15);
lcd_write_com(0x38);
delay(5);
lcd_write_com(0x38);
delay(5);
lcd_write_com(0x38);
lcd_flag=1;
lcd_write_com(0x38);
lcd_write_com(0x0e);
lcd_write_com(0x06);
lcd_write_com(0x01);
}
/**********************************************************
液晶1602写指令函数
**********************************************************/
voidlcd_write_com(ucharcom)
{if(lcd_flag==1)lcd_check_bf();
lcd_en=0;
lcd_rs=0;
lcd_rw=0;
lcd=com;
_nop_();
_nop_();
lcd_en=1;
_nop_();
_nop_();
_nop_();
_nop_();
lcd_en=0;
}
/**********************************************************
液晶1602写指令函数
**********************************************************/
voidlcd_write_data(uchardate)
{if(lcd_flag==1)lcd_check_bf();
lcd_en=0;
lcd_rs=1;
lcd_rw=0;
lcd=date;
_nop_();
_nop_();
lcd_en=1;
_nop_();
_nop_();
_nop_();
_nop_();
lcd_en=0;
}
/**********************************************************
液晶1602检测忙碌标志位函数
**********************************************************/
voidlcd_check_bf()
{do
{lcd=0xff;
lcd_en=0;
lcd_rs=0;
lcd_rw=1;
_nop_();
lcd_en=1;
_nop_();
}
while(busy);
lcd_en=0;
}
/**********************************************************
DS12C887初始化函数
**********************************************************/
voidda_init()
{reg_a=0x20;
}
/**********************************************************
DS12C887读函数
**********************************************************/
voidda_read()
{da_check_bf();
sed=da_sed;
da_check_bf();
mie=da_mie;
da_check_bf();
hor=da_hor;
da_check_bf();
day=da_day;
da_check_bf();
moh=da_moh;
da_check_bf();
year=da_year;
da_check_bf();
cey=da_cey;
}
/**********************************************************
DS12C887忙碌标志判断函数
**********************************************************/
voidda_check_bf()
{while(reg_a&0x80);
}
/**********************************************************
DS12C887写函数
**********************************************************/
voidda_write()
{reg_b=0x80;
da_sed=50;
da_mie=59;
da_hor=23;
da_day=31;
da_moh=12;
da_year=8;
da_cey=20;
reg_b=0x06;
}
/**********************************************************
显示秒函数
**********************************************************/
voiddisplay_sed()
{ucharwei1,wei0;
wei1=sed/10;
wei0=sed%10;
lcd_write_com(0x80+0x46);
lcd_write_data(0x30+wei1);
lcd_write_data(0x30+wei0);
}
/**********************************************************
显示分函数
**********************************************************/
voiddisplay_mie()
{ucharwei1,wei0;
wei1=mie/10;
wei0=mie%10;
lcd_write_com(0x80+0x43);
lcd_write_data(0x30+wei1);
lcd_write_data(0x30+wei0);
}
/**********************************************************
显示时函数
**********************************************************/
voiddisplay_hor()
{ucharwei1,wei0;
wei1=hor/10;
wei0=hor%10;
lcd_write_com(0x80+0x40);
lcd_write_data(0x30+wei1);
lcd_write_data(0x30+wei0);
}
/**********************************************************
显示日函数
**********************************************************/
voiddisplay_day()
{ucharwei1,wei0;
wei1=day/10;
wei0=day%10;
lcd_write_com(0x80+0x08);
lcd_write_data(0x30+wei1);
lcd_write_data(0x30+wei0);
}
/**********************************************************
显示月函数
**********************************************************/
voiddisplay_moh()
{ucharwei1,wei0;
wei1=moh/10;
wei0=moh%10;
lcd_write_com(0x80+0x05);
lcd_write_data(0x30+wei1);
lcd_write_data(0x30+wei0);
}
/**********************************************************
显示年函数
**********************************************************/
voiddisplay_year()
{ucharwei1,wei0;
wei1=year/10;
wei0=year%10;
lcd_write_com(0x80+0x02);
lcd_write_data(0x30+wei1);
lcd_write_data(0x30+wei0);
}
/**********************************************************
显示世纪函数
**********************************************************/
voiddisplay_cey()
{ucharwei1,wei0;
wei1=cey/10;
wei0=cey%10;
lcd_write_com(0x80);
lcd_write_data(0x30+wei1);
lcd_write_data(0x30+wei0);
}
/**********************************************************
延时1毫秒函数
**********************************************************/
voiddelay(uintz)
{uintx,y;
for(x=z;x>0;x--)
for(y=0;y<180;y++);
}
DS12C887的DS,RW,AS分别与P3.7,P3.6,ALE相连接,AD0与AD7分别与P0.0和P0.7
由P2口提供高地址,P0口提供低地址,P2.0与CS相连,由于P2.0与CS相连,CS是低电平有效,所以高地址是0xfe,(不明白的话再举一个例子,P2.1与CS相连,由于P2.7与CS相连,CS是低电平有效,所以高地址是0x7f),P0口是地址/数据口,要分清楚P0什么时候传输数据,什么时候传输地址,就由ALE,RW,RD来决定(可以参考DS12C887的时序)
如果有兴趣的话本人有详细的DS12C887资料QQ570804566
项目实现功能:
使用TX-1C实验板扩展时钟芯片DS12C887设计一个时钟(24小时制),要求如下:
(1)在1602液晶上显示年、月、日、星期、时、分、秒并且按秒实时更新显示。
(3)能够使用板上的按键随时调节各个参数,按键可设置个有效键,分别为功能选择键、数值增大键、数值减小键
(4)利用DS12C887自身掉电可继续走时的特性,设计实现断电时间不停、再次上电时时间仍然准确显示在液晶上的功能。
程序代码:
/*----------------------------------
这个程序实现:
时钟的24小时制显示
----------------------------------*/
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitlcden=P3^4; //液晶使能端
sbitrs=P3^5; //液晶数据命令选择端
sbitled=P2^5; //控制LED的锁存器
sbitdula=P2^6; //控制LCD的段锁存器
sbitwela=P2^7; //控制LCD的位锁存器
sbitdsirq=P3^2; //DS12C887的中断请求端
sbitdsds=P1^7; //DS12C887的读允许输入端
sbitdsrw=P1^6; //DS12C887的写允许输入端
sbitdsas=P1^5; //DS12C887的地址选通端
sbitdscs=P1^4; //DS12C887的芯片片选端
sbita=P3^0; //设置键盘用的
sbitb=P3^1; //设置键盘用的
sbitc=P3^6; //设置键盘用的
sbitd=P3^7; //设置键盘用的
ucharcodetable1[]="20 - - ";
ucharcodetable2[]=" :
:
00.0C";
/*
falg1标志位是用来判断是否执行从DS12C887中读取数据并送去液晶显示;
flag2标志位是用来判断LCD上显示的年数是否是闰年;
temp与temp1都时当月的天数值,用来判断DS12C887中的天数值是否大
于当月应有的天数,如大于则将天数值置1,如有需要请重新设置天数值。
*/
ucharflag1,flag2,temp,temp1;
charmiao,fen,nian,yue,ri,xingqi;
intshi; //小时的数值大于128,所以不能选择char型数据
/*------------
延时子程序
------------*/
voiddelayms(uchara)
{
ucharx,y;
for(x=a;x>0;x--)
for(y=110;y>0;y--);
}
/*----------------
往液晶中写指令
----------------*/
voidwrite_com(ucharcom)
{
rs=0; //选择写命令模式
lcden=0; //将lcden置为零
P0=com; //将要写的命令字送到数据总线上
delayms(5); //稍做延时以待数据稳定
lcden=1; //使能端给一个高脉冲
delayms(5); //稍做延时
lcden=0; //将使能端置0以完成高脉冲
}
/*----------------
往液晶中写数据
----------------*/
voidwrite_date(uchardate)
{
rs=1; //选择写数据模式
lcden=0; //将lcden置为零
P0=date; //将要写的数据送到数据总线上
delayms(5); //稍做延时以待数据稳定
lcden=1; //使能端给一个高脉冲
delayms(5); //稍做延时
lcden=0; //将使能端置0以完成高脉冲
}
/*--------------------
向DS12C887内写数据
--------------------*/
voidwrite_ds(ucharadd,uchardate)
{
dscs=0;
dsas=1;
dsds=1;
dsrw=1;
P0=add; //先写地址
dsas=0;
dsrw=0;
P0=date; //再写数据
dsrw=1;
dsas=1;
dscs=1;
}
/*--------------------
从DS12C887中读数据
--------------------*/
ucharread_ds(ucharadd)
{
uchartemp;
dscs=0;
dsas=1;
dsds=1;
dsrw=1;
P0=add; //先写地址
dsas=0;
dsds=0;
P0=0xff; //读数据之前先将P0口置一
temp=P0; //再读数据
dsds=1;
dsas=1;
dscs=1;
returntemp;
}
/*----------------------------------------
12小时制在液晶的指定位置写入小时的数值
----------------------------------------*/
voidwrite_shi(ucharadd,uchardate)
{
ucharshi,ge,hour;
if(date>0&&date<13) //当小时的数值在0到13之间时,液晶上显示为上午(液晶第二排第一位显示A)
{
hour=date;
write_com(0x80+0x40);
write_date('A');
}
if(date>128) //当小时的数值大于128时,液晶上显示为下午(液晶第二排第一位显示P)
{
hour=date-128; //小时在液晶上显示的范围为1到12
write_com(0x80+0x40);
write_date('P');
}
shi=hour/10; //分解一个2位数的十位和个位
ge=hour%10;
write_com(0x80+0x40+add); //设置显示位置
write_date(shi+0x30); //送去液晶显示十位
write_date(ge+0x30); //送去液晶显示个位
}
/*----------------------------------------------------------------------
24小时制在液晶的指定位置写入时分秒,12小时制在液晶的指定位置写入分秒
----------------------------------------------------------------------*/
voidwrite_sfm(ucharadd,uchardate)
{
uchar
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数字 时钟 DS12887 程序