//晶振11.0592
#include<reg51.h>
#include<absacc.h>
sbit RESET=P3^2 //键盘
sbit OK=P3^4 //键盘
sbit INC=P2^1 //键盘
sbit DEC=P2^2 //键盘
sbit RS=P1^0 //指令和数据寄存器
sbit RW=P1^1 //读写控制
sbit E=P1^2 //片选
sbit FLAG=P0^7//忙信号
#define uchar unsigned char
#define time_a XBYTE[0x7f0a]//控制寄存器A
#define time_b XBYTE[0x7f0b] //控制寄存器B
/*#define YEAR XBYTE[0x7f09] //年地址
#define MONTH XBYTE[0x7f08] //月地址
#define DAY XBYTE[0x7f07] //日地址
#define HOUR XBYTE[0x7f04] //时地址
#define MINUTE XBYTE[0x7f03] //分地址
#define SECOND XBYTE[0x7f00]//秒地址
*/
#define data_IO P0
uchar time[12]={0}
uchar xdata *addr=0x7f00 //P2.7片选,低电平有效
uchar year,month,day,hour,minute,second
//声明函数
void get_time(void)
void intial(void)
intial_lcd()
void busy()
void w_com(uchar com)
void w_dat(uchar dat)
void display()
void delay(unsigned long N)
void displayD(uchar j)
void convert(void)
void INT0_ISR()
void get_time(void)
{
year=*(addr+9)
month=*(addr+8)
day=*(addr+7)
hour=*(addr+4)
minute=*(addr+2)
second=*addr
}
void intial(void)
{
time_a=0x70
time_b=0x8e //可以设置12、24小时制
*(addr+2)=0x00//分--初值--30
*(addr+4)=0x0C//时--初值--12
*(addr+7)=0x10//日--初值--16
*(addr+8)=0x07//月--初值--07
*(addr+9)=0x07//年--初值--07
time_a=0x27
time_b=0x1e //SET最高位为0,芯片更新,正常运行
}
//---------------------------液晶显示---------------
intial_lcd()
{
RS=0
RW=0
E=0
delay(100)
w_com(0x38)
w_com(0x38)
w_com(0x38)//显示为八位两行字符
w_com(0x08)
w_com(0x01)
w_com(0x0C) //开显示
}
void busy() // 忙检测
{
while(1)
{
data_IO=0xff
RS=0
RW=1
E=1
if(!FLAG)break
E=0
}
}
void w_com(uchar com)//写指令
{
busy()
data_IO=com
RS=0
RW=0
E=1
E=0
}
void w_dat(uchar dat) //写数据
{
busy()
data_IO=dat
RS=1
RW=0
E=1
E=0
return
}
/**********int0中断服务程序**********/
void INT0_ISR(void) interrupt 0
{ uchar k=1,m=0,n=0,j=0,h=0,num=9
while(k)
{
get_time()
displayD(num)
switch(m)
{
case 0x00:num=9break//年
case 0x02:num=8break//月
case 0x04:num=7break//日
case 0x06:num=4break//时
case 0x08:num=2break//分
}
if(INC==0 &&*(addr+num)<99 &&num==9 &&h++>93){ h=0*(addr+num)+=1}
if(INC==0 &&*(addr+num)<12 &&num==8 &&h++>93){ h=0*(addr+num)+=1}
if(INC==0 &&*(addr+num)<31 &&num==7 &&h++>93){ h=0*(addr+num)+=1}
if(INC==0 &&*(addr+num)<24 &&num==4 &&h++>93){ h=0*(addr+num)+=1}
if(INC==0 &&*(addr+num)<59 &&num==2 &&h++>93){ h=0*(addr+num)+=1}
if((DEC==0) &&*(addr+num)>0 &&j++>93){ j=0 *(addr+num)-=1}
if(OK==0 &&n++>93){n=0m+=2}
delay(10)
if(m==0x0A)k=0
}
}
void displayD(uchar j) //调整时间子程序
{
convert()
w_com(0x82) //显示数据存储器首地址
w_dat(0x32) //显示字母2
w_dat(0x30) //显示字母0
if(j==9)
{
w_com(0x84)w_dat(time[0])w_dat(time[1])
w_com(0x84)w_dat(0x20)w_dat(0x20)delay(2)
w_com(0x84)w_dat(time[0])w_dat(time[1])
w_dat(0x2D)}//年07
else if(j==8)
{w_com(0x87) w_dat(time[2])w_dat(time[3])
w_com(0x87)w_dat(0x20)w_dat(0x20)delay(2)
w_com(0x87) w_dat(time[2])w_dat(time[3])
w_dat(0x2D)}//月07
else if(j==7)
{w_com(0x8A)w_dat(time[4])w_dat(time[5])
w_com(0x8A)w_dat(0x20)w_dat(0x20)delay(2)
w_com(0x8A)w_dat(time[4])w_dat(time[5])}//日
else if(j==4)
{w_com(0xC4) w_dat(time[6])w_dat(time[7])
w_com(0xC4)w_dat(0x20)w_dat(0x20)delay(2)
w_com(0xC4) w_dat(time[6])w_dat(time[7])
w_dat(0x2D)}//时
else// if(j==2)
{w_com(0xC7)w_dat(time[8])w_dat(time[9])
w_com(0xC7)w_dat(0x20)w_dat(0x20)delay(2)
w_com(0xC7)w_dat(time[8])w_dat(time[9])
}//分
w_com(0xCA)w_dat(time[10])w_dat(time[11])//秒
}
void display()
{
convert()
w_com(0x82) //显示数据存储器首地址
w_dat(0x32) //显示字母2
w_dat(0x30) //显示字母0
w_dat(time[0])//年
w_dat(time[1])
w_dat(0x2D)
w_com(0x87) //显示数据存储器首地址
w_dat(time[2]) //月
w_dat(time[3])
w_dat(0x2D)
w_com(0x8A) //显示数据存储器首地址
w_dat(time[4])//日
w_dat(time[5])
w_com(0xC4) //显示数据存储器首地址
w_dat(time[6]) //时
w_dat(time[7])
w_dat(0x3A)
w_com(0xC7) //分
w_dat(time[8])
w_dat(time[9])
w_com(0xCA) //秒
w_dat(time[10])
w_dat(time[11])
w_dat(0x20)
w_dat(0x20)
w_dat(0x20)
w_dat(0x20)
}
void convert(void)
{
time[0]=year/10+0x30
time[1]=year%10+0x30
time[2]=month/10+0x30
time[3]=month%10+0x30
time[4]=day/10+0x30
time[5]=day%10+0x30
time[6]=hour/10+0x30
time[7]=hour%10+0x30
time[8]=minute/10+0x30
time[9]=minute%10+0x30
time[10]=second/10+0x30
time[11]=(second%10+0x30)
time[12]=0x20
time[13]=0x20
}
void delay(unsigned long N)
{
for(N>0N--)
}
void main(void)
{
IT0=1//下降延中断
EX0 = 1 //int0中断使能
EA = 1 //总中断使能
intial()
intial_lcd()
while(1)
{
get_time()
display()
}
}
//首次使用时下载该程序后,调节实验箱最下面的W1液晶对比度调节电位器,使液晶显示最佳。#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
/*12864端口定义*/
#define LCD_data P0 //数据口
sbit LCD_RS = P3^5 //寄存器选择输入
sbit LCD_RW = P3^6 //液晶读/写控制
sbit LCD_EN = P3^4 //液晶使能控制
sbit LCD_PSB = P3^7 //串/并方式控制
sbit wela= P2^6
sbit dula= P2^7
sbit beep=P2^3
sbit dscs=P1^4
sbit dsas=P1^5
sbit dsrw=P1^6
sbit dsds=P1^7
sbit dsirq=P3^3
bit flag1,flag_ri
uchar count,s1num,flag,t0_num,num,mm
char miao,shi,fen,year,month,day,week,amiao,afen,ashi
void write_ds(uchar,uchar)
void lcd_wdat(uchar)
void set_time()
#define delayNOP(){_nop_()_nop_()_nop_()_nop_()}
//uchar IRDIS[2]
//uchar IRCOM[4]
void delay0(uchar x) //x*0.14MS
//void beep()
void lcm_word(uchar *str)
void write_ds(uchar,uchar)
uchar read_ds(uchar)
void dataconv()
void lcd_pos(uchar X,uchar Y) //确定显示位置
/*******************************************************************/
/* */
/* 延时函数 */
/* */
/*******************************************************************/
void delay(int ms)
{
while(ms--)
{
uchar i
for(i=0i<250i++)
{
_nop_()
_nop_()
_nop_()
_nop_()
}
}
}
/*******************************************************************/
/* */
/*检查LCD忙状态*/
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/*******************************************************************/
bit lcd_busy()
{
bit result
LCD_RS = 0
LCD_RW = 1
LCD_EN = 1
delayNOP()
result = (bit)(P0&0x80)
LCD_EN = 0
return(result)
}
/*******************************************************************/
/* */
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/* */
/*******************************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy())
LCD_RS = 0
LCD_RW = 0
LCD_EN = 0
_nop_()
_nop_()
P0 = cmd
delayNOP()
LCD_EN = 1
delayNOP()
LCD_EN = 0
}
/***********************************************/
/*显示数字*/
/***********************************************/
void write_sfm(uchar add,uchar date)//时,分,秒
{
uchar shi,ge
shi=date/10
ge=date%10
lcd_wcmd(0x98+add)
lcd_wdat(0x30+shi)
lcd_wdat(0x30+ge)
}
void write_nyr(uchar add,uchar date) //年,月,日
{
uchar shi,ge
shi=date/10
ge=date%10
lcd_wcmd(0x89+add)
lcd_wdat(0x30+shi)
lcd_wdat(0x30+ge)
}
/***************************************************************/
/*转成汉字显示*/
/***************************************************************/
void lcm_word(unsigned char *str)
{
while(*str!='\0')
{
//lcd_wcmd(0x9f)
lcd_wdat(*str++)
}
*str=0
}
/*******************************************************************/
/*星期处理*/
/*******************************************************************/
void lcm_xingqi(void)
{
uchar sel
sel=read_ds(6) //将DS12C887星期数赋给sel
lcd_wcmd(0x9f) //星期显示位置
if(sel==7)
{
lcm_word("日")
//lcd_wdat(0xc8) //星期日
//lcd_wdat(0xd5)
}
if(sel==6)
{
lcm_word("六")
//lcd_wdat(0xc1) //星期六
//lcd_wdat(0xf9)
}
if(sel==5)
{
lcm_word("五")
//lcd_wdat(0xce) //星期五
//lcd_wdat(0xc4)
}
if(sel==4)
{
lcm_word("四")
//lcd_wdat(0xcb) //星期四
//lcd_wdat(0xd5)
}
if(sel==3)
{
//lcm_word("三")
lcd_wdat(0xc8) //星期三
lcd_wdat(0xfd)
}
if(sel==2)
{
lcm_word("二")
//lcd_wdat(0xb6) //星期二
//lcd_wdat(0xfe)
}
if(sel==1)
{
lcm_word("一")
//lcd_wdat(0xd2) //星期一
// lcd_wdat(0xbb)
}
}
/*******************************************************************/
/* */
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/* */
/*******************************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy())
LCD_RS = 1
LCD_RW = 0
LCD_EN = 0
P0 = dat
delayNOP()
LCD_EN = 1
delayNOP()
LCD_EN = 0
}
/*******************************************************************/
/* */
/* LCD初始化设定 */
/* */
/*******************************************************************/
void lcd_init()
{
//uchar i
LCD_PSB = 1//并口方式
write_ds(0x0a,0x20)//打开振荡器;
write_ds(0x0b,0x26)
//set_time() //在第一次设置12C887时打开
lcd_wcmd(0x34) //扩充指令 *** 作
delay(5)
lcd_wcmd(0x30) //基本指令 *** 作
delay(5)
lcd_wcmd(0x0C) //显示开,关光标
delay(5)
lcd_wcmd(0x01) //清除LCD的显示内容
delay(5)
/*lcd_wcmd(0x88)
for(i = 0i <10i++)
lcd_wdat(dis3[i])*/
}
/**************************************/
/* DS12C887时钟芯片写指令*/
/**************************************/
void write_ds(uchar add,uchar date)
{
dscs=0
dsas=1
dsds=1
dsrw=1
P0=add
dsas=0
dsrw=0
P0=date
dsrw=1
dsas=1
dscs=1
}
/************************************/
/* DS12C887读指令*/
/************************************/
uchar read_ds(uchar add)
{
uchar ds_date
dsas=1
dsds=1
dsrw=1
dscs=0
P0=add
dsas=0
dsds=0
P0=0xff
ds_date=P0
dsds=1
dsas=1
dscs=1
return ds_date
}
/****************************************/
/*向DS12c887内写数据*/
/****************************************/
void set_time()
{
write_ds(0,50)//秒
write_ds(1,0)//秒闹铃
write_ds(2,18)//分
write_ds(3,0)//分闹铃
write_ds(4,7)//时
write_ds(5,0)//时闹铃
write_ds(6,1)//星期
write_ds(7,11)//日
write_ds(8,10)//月
write_ds(9,10)//年
}
/*********************************************************/
/* */
/* 主程序 */
/* */
/*********************************************************/
main()
{
uchar i
delay(10)//延时
wela=0
dula=0
lcd_init() //初始化LCD
while(1)
{
//xs()
days()
lcd_pos(1,0)//设置显示位置为第二行的第1个字符
i = 0
while(dis2[i] != '\0')
{
lcd_wdat(dis2[i]) //显示字符
i++
}
//lcd_wcmd(0x89)//设置显示位置为第三行的第1个字符
year=read_ds(9)
month=read_ds(8)
day=read_ds(7)
week=read_ds(6)
shi=read_ds(4)
fen=read_ds(2)
miao=read_ds(0)
lcd_wcmd(0x88)
lcd_wdat(0x32)
lcd_wdat(0x30)
write_nyr(0,year)
lcd_wdat(0xc4)
lcd_wdat(0xea)
write_nyr(2,month)
lcd_wdat(0xd4)
lcd_wdat(0xc2)
write_nyr(4,day)
lcd_wdat(0xc8)
lcd_wdat(0xd5)
//lcd_wdat(0xc8)
//lcd_wdat(0xd5)
write_sfm(4,miao)
write_sfm(2,fen)
lcd_wdat(0x3a)
lcd_wdat(0x3a)
write_sfm(0,shi)
lcd_wdat(0x3a)
lcd_wdat(0x3a)
lcd_wcmd(0x9d)
lcd_wdat(0xd0)
lcd_wdat(0xc7)
lcd_wdat(0xc6)
lcd_wdat(0xda)
//write_sfm(7,week)
lcd_wcmd(0x9f)
lcm_xingqi()
}
}
/*********************************************************/
/* */
/* 延时x*0.14ms子程序 */
/* */
/*********************************************************/
void delay0(uchar x)//x*0.14MS
{
uchar i
while(x--)
{
for (i = 0i<13i++) {}
}
}
/*********************************************************/
/* */
/* 设定显示位置 */
/* */
/*********************************************************/
void lcd_pos(uchar X,uchar Y)
{
uchar pos
if (X==0)
{X=0x80}
else if (X==1)
{X=0x90}
else if (X==2)
{X=0x88}
else if (X==3)
{X=0x98}
pos = X+Y
lcd_wcmd(pos)//显示地址
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)