//===============LCD12887_1.C 主文件
/*--------------------------------------------------------------*/
//包含头文件
#include<AT89X52.H>
#include"LCD1602_8.H"
#include"DS12887_1.H"
/*--------------------------------------------------------------*/
unsigned char k//键值
unsigned char Set//调整值
/*--------------------------------------------------------------*/
//延时200ms 函数定义
void delay200ms(void)
{
unsigned char i,j,k
for(i=201i>0i--)
for(j=32j>正伍0j--)
for(k=14k>0k--)
}
/*--------------------------------------------------------------*/
//延时5000+0us 函数定义
void delay5ms(void)
{
unsigned char i,j
for(i=185i>0i--)
for(j=12j>0j--)
}
/*--------------------------------------------------------------*/
//键盘扫描
void Keysan(void) //P0_0切换键,P0_1数值加,P0_1数值减
{
if(P0_0 == 0)
{
delay5ms()
if(P0_0 == 0) k++
if(k == 7) k = 0
}
if(P0_1 == 0) {delay5ms()if(P0_1 == 0) Set++}
if(P0_2 == 0) {delay5ms()if(P0_2 == 0) Set--}
switch(k)
{
case 0: DS12887_SetTime(DS12887_Second, Set)if(Set >59 || Set <0) Set = 0break
case 1: DS12887_SetTime(DS12887_Minute, Set)if(Set >59 || Set <0) Set = 0break
case 2: DS12887_SetTime(DS12887_Hour , Set)if(Set >24 || Set <0) Set = 0break
case 3: DS12887_SetTime(DS12887_Day , Set)if(Set >31 || Set <0) Set = 0break
case 4: DS12887_SetTime(DS12887_Month , Set)if(Set >12 || Set <0) Set = 0break
case 5: DS12887_SetTime(DS12887_Year , Set)break
default: break
}
}
/*--------------------------------------------------------------*/
//主函衫败数
void main(void)
{
SYSTEMTIME CurrentTime
lcd_init()
DS12887_Init()
lcd_pos(0,0)
prints("Date:")
lcd_pos(0,1)
prints("Time:")
k = 6//不改变时间
while(1)
{
DS12887_GetTime(&CurrentTime)
DateToStr(&CurrentTime)
TimeToStr(&CurrentTime)
lcd_pos(6,0)
prints(CurrentTime.DateString)
lcd_pos(6,1)
prints(CurrentTime.TimeString)
delay200ms()
Keysan()
}
}
//=======================包含文件1 LCD1602_8.H
/*--------------------------------------------------------------*/
//包含头文件
#include<AT89X52.H>
#include"LCD1602_8.H"
#include"DS12887_1.H"
/*--------------------------------------------------------------*/
unsigned char k//键值
unsigned char Set//调整值
/*--------------------------------------------------------------*/
//延时200ms 函数定义
void delay200ms(void)
{
unsigned char i,j,k
for(i=201i>0i--)
for(j=32j>0j--)
for(k=14k>0k--)
}
/*--------------------------------------------------------------*/
//延时5000+0us 函数定义
void delay5ms(void)
{
unsigned char i,j
for(i=185i>0i--)
for(j=12j>0j--)
}
/*--------------------------------------------------------------*/
//键盘扫描
void Keysan(void) //P0_0切换键,P0_1数值加,P0_1数值减
{
if(P0_0 == 0)
{
delay5ms()
if(P0_0 == 0) k++
if(k == 7) k = 0
}
if(P0_1 == 0) {delay5ms()if(P0_1 == 0) Set++}
if(P0_2 == 0) {delay5ms()if(P0_2 == 0) Set--}
switch(k)
{
case 0: DS12887_SetTime(DS12887_Second, Set)if(Set >59 || Set <0) Set = 0break
case 1: DS12887_SetTime(DS12887_Minute, Set)if(Set >59 || Set <0) Set = 0break
case 2: DS12887_SetTime(DS12887_Hour , Set)if(Set >24 || Set <0) Set = 0break
case 3: DS12887_SetTime(DS12887_Day , Set)if(Set >31 || Set <0) Set = 0break
case 4: DS12887_SetTime(DS12887_Month , Set)if(Set >12 || Set <0) Set = 0break
case 5: DS12887_SetTime(DS12887_Year , Set)break
default: break
}
}
/*--------------------------------------------------------------*/
//主函数
void main(void)
{
SYSTEMTIME CurrentTime
lcd_init()
DS12887_Init()
lcd_pos(0,0)
prints("Date:")
lcd_pos(0,1)
prints("Time:")
k = 6//不改变时间
while(1)
{
DS12887_GetTime(&CurrentTime)
DateToStr(&CurrentTime)
TimeToStr(&CurrentTime)
lcd_pos(6,0)
prints(CurrentTime.DateString)
lcd_pos(6,1)
prints(CurrentTime.TimeString)
delay200ms()
Keysan()
}
}
//================================ 包含文件2 DS12887_1.H
/*--------------------------------------------------------------*/
//File: DS12887驱动程序
//Date: 08-10-20 ~ 10-23
//Time: 21:20 ~ 16:53
//Source: Web
/*--------------------------------------------------------------*/
#ifndef __DS12887_1_H__
#define __DS12887_1_H__
/*--------------------------------------------------------------*/
//接口定义
sbit DS_AS = P3^0//地址选择
sbit DS_RW = P3^1//读写选择
sbit DS_DS = P3^2//数据选择
sbit DS_IRQ = P3^3//中断,低电平有效,通过读出0x0c来清除信号
sfr DS_DAT = 0x90//8位数据线P1口
/*--------------------------------------------------------------*/
//数据地址定义
#define DS12887_Second 0x00 //秒
#define DS12887_Minute 0x02 //分
#define DS12887_Hour 0x04 //时
#define DS12887_Week 0x06 //星期
#define DS12887_Day 0x07 //日
#define DS12887_Month 0x08 //月
#define DS12887_Year 0x09 //年
/*--------------------------------------------------------------*/
//定义时间类型
typedef struct _SYSTEMTIME_
{
unsigned char Second
unsigned char Minute
unsigned char Hour
unsigned char Week
unsigned char Day
unsigned char Month
unsigned char Year
unsigned char DateString[9]
unsigned char TimeString[9]
}SYSTEMTIME
/*--------------------------------------------------------------*/
//函数声明
void DS12887_Init(void)//DS12887初始化
void DS12887_Write(unsigned char Address, unsigned char Value)//DS12887指定地址写入数据
unsigned char DS12887_Read(unsigned char Address)//DS12887指定地址中读出数据
void DS12887_SetTime(unsigned char Address, unsigned char Value)//设置时间函数
void DS12887_GetTime(SYSTEMTIME *Time)//读出时间
void DateToStr(SYSTEMTIME *Time)//日期转化成字符
void TimeToStr(SYSTEMTIME *Time)//时间转化成字符
/*--------------------------------------------------------------*/
//DS12887指定地址写入数据
void DS12887_Write(unsigned char Address, unsigned char Value)
{
DS_AS = 0
DS_DS = 1
DS_RW = 1
DS_AS = 1
DS_DAT= Address
DS_AS = 0
DS_RW = 0
DS_DAT= Value
DS_RW = 1
DS_AS = 1
}
/*--------------------------------------------------------------*/
//DS12887指定地址中读出数据
unsigned char DS12887_Read(unsigned char Address)
{
unsigned char DS_RDAT
DS_AS = 0
DS_DS = 1
DS_RW = 1
DS_AS = 1
DS_DAT= Address
DS_AS = 0
DS_DS = 0
DS_DAT=0xff
DS_RDAT = DS_DAT
DS_DS = 1
DS_AS = 1
return (DS_RDAT)
}
/*--------------------------------------------------------------*/
//DS12887初始化
void DS12887_Init(void)
{
DS12887_Write(0x0a, 0x20)//启动DS12887
DS12887_Write(0x0b, 0x86)//禁止更新,接下来初始化数据,即写入时间,日期等
DS12887_Write(0x0b, 0x06)//正常更新,二进制格式,24进制小时
}
/*--------------------------------------------------------------*/
//设置时间函数
void DS12887_SetTime(unsigned char Address, unsigned char Value)
{
DS12887_Write(0x0b, 0x86)//禁止更新,接下来初始化数据,即写入时间,日期等
DS12887_Write(Address,Value)
DS12887_Write(0x0b, 0x06)//正常更新,二进制格式,24进制小时
}
/*--------------------------------------------------------------*/
//读出时间
void DS12887_GetTime(SYSTEMTIME *Time)
{
Time->Second = DS12887_Read(DS12887_Second)
Time->Minute = DS12887_Read(DS12887_Minute)
Time->Hour = DS12887_Read(DS12887_Hour )
Time->Day = DS12887_Read(DS12887_Day )
Time->Week = DS12887_Read(DS12887_Week )
Time->Month = DS12887_Read(DS12887_Month )
Time->Year = DS12887_Read(DS12887_Year )
}
/*--------------------------------------------------------------*/
//日期转化成字符
void DateToStr(SYSTEMTIME *Time)
{
Time->DateString[0] = Time->Year/10 + '0'
Time->DateString[1] = Time->Year%10 + '0'
Time->DateString[2] = '-'
Time->DateString[3] = Time->Month/10 + '0'
Time->DateString[4] = Time->Month%10 + '0'
Time->DateString[5] = '-'
Time->DateString[6] = Time->Day/10 + '0'
Time->DateString[7] = Time->Day%10 + '0'
Time->DateString[8] = '\0'
}
/*--------------------------------------------------------------*/
//时间转化成字符
void TimeToStr(SYSTEMTIME *Time)
{
Time->TimeString[0] = Time->Hour/10 + '0'
Time->TimeString[1] = Time->Hour%10 + '0'
Time->TimeString[2] = ':'
Time->TimeString[3] = Time->Minute/10 + '0'
Time->TimeString[4] = Time->Minute%10 + '0'
Time->TimeString[5] = ':'
Time->TimeString[6] = Time->Second/10 + '0'
Time->TimeString[7] = Time->Second%10 + '0'
Time->TimeString[8] = '\0'
}
/*--------------------------------------------------------------*/
#endif
/*--------------------------------------------------------------*/
//File: LCD1602_8.H
//Date: 08-7-29
//Time: 16:09
//Note: LCD1602 Mini Driver.
/*--------------------------------------------------------------*/
#ifndef __LCD1602_8_H__
#define __LCD1602_8_H__
#include <intrins.h>
/*--------------------------------------------------------------*/
//LCD接口定义
sfr io = 0xA0 //P0-0x80,P1-0x90,P2-0xA0,P3-0xB0
sbit rs = P3^4 //LCD数据/命令选择端(H/L)
sbit rw = P3^5 //LCD读/写选择端(H/L)
sbit ep = P3^6 //LCD使能控制
sbit bz = io^7 //LCD忙标志位
/*--------------------------------------------------------------*/
//函数声明
void lcd_busy(void)//测试LCD忙碌状态程序
void lcd_wcmd(unsigned char cmd) //写入指令到LCD程序
void lcd_wdat(unsigned char dat) //写入数据到LCD程序
void lcd_pos (unsigned char x, bit y)//LCD数据指针位置程序
//void printc(unsigned char CHAR) //显示字符
void prints(unsigned char *string) //显示字符串
void lcd_init(void)//LCD初始化设定程序
/*--------------------------------------------------------------*/
//测试LCD忙碌状态
void lcd_busy(void)
{
do{
ep = 0
rs = 0 //指令
rw = 1 //读出
io = 0xff
ep = 1
_nop_()//高电平读出 1us
}while(bz) //bz=1表示忙,bz=0表示空闲
ep = 0
}
/*--------------------------------------------------------------*/
//写入指令到LCD
void lcd_wcmd(unsigned char cmd)
{
lcd_busy()//检测忙
rs = 0 //指令
rw = 0 //写入
ep = 1
io = cmd//指令
ep = 0 //下降沿有效
}
/*--------------------------------------------------------------*/
//写入数据函数
void lcd_wdat(unsigned char Data)
{
lcd_busy() //检测忙
rs = 1 //数据
rw = 0 //写入
ep = 1
io = Data //数据
ep = 0 //下降沿有效
}
/*--------------------------------------------------------------*/
//LCD数据指针位置程序
void lcd_pos(unsigned char x, bit y)
{
if(y)lcd_wcmd(x|0xc0)//y=1,第二行显示y=0,第一行显示 0<=x<16
else lcd_wcmd(x|0x80)//数据指针=80+地址码(00H~27H,40H~67H)
}
/*--------------------------------------------------------------*/
//显示字符
/*
void printc(unsigned char CHAR)
{
lcd_wdat(CHAR)
}
*/
/*--------------------------------------------------------------*/
//显示字符串
void prints(unsigned char *string)
{
while(*string) {lcd_wdat(*string)string++}
}
/*--------------------------------------------------------------*/
//LCD初始化设定
void lcd_init()
{
lcd_wcmd(0x38) //设置LCD为16X2显示,5X7点阵,八位数据接口
lcd_wcmd(0x06) //LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)
lcd_wcmd(0x0c) //LCD开显示及光标设置(光标不闪烁,不显示"_")
lcd_wcmd(0x01) //清除LCD的显示内容
}
/*--------------------------------------------------------------*/
#endif
以下是相应的说明:
8根并行数据线+三根控制信号线~就可以咯~
按键接法(按键的另一条腿接到GND上):
P0_0切换键,
P0_1数值加,
P0_1数值减
时钟日历管脚接法:
sbit DS_AS = P3^0//地址选择
sbit DS_RW = P3^1//读写选择
sbit DS_DS = P3^2//数据选择
sbit DS_IRQ = P3^3//中断,低电平有效,通过读出0x0c来清除信号
sfr DS_DAT = 0x90//8位数据线P1口
液晶管脚接法:
sfr io = 0xA0 //液晶数据口 P2-0xA0--D0-D7
sbit rs = P3^4 //LCD数据/命令选择端(H/L) --RS / DI
sbit rw = P3^5 //LCD读/写选择端(H/L) --RW
sbit ep = P3^6 //LCD使能控制 --EN
sbit bz = io^7 //LCD忙标志位(不用再接)
DS12887的RST接在VCC, CS接在GND, IRQ不用管, MOT悬空即可~也即选择默认的Intel 工作方式。
为什么不能用MOVX A,@DPTR哦,原来,你的RW,没有接在P3口上啊...
这样别人会很有难度的...
我的意思同楼上...
看楼主的意思是不是P3口坏了吗...
应该不会辩谨埋的吧...你位选还用P3.0-P3.5
你晌陪看一下,连线是否有错:下面网站上有它的连接方法..
http://www.guangdongdz.com/special_column/techarticle/jszl30041.html
读取程序
ORG 0000H
T_SEC: save seccond
T_MIN: save minute
T_HOUR: save hour
T_DAY: save day
T_MON: save month
T_YE: SAVE YEAR
T_CE: SAVE CENTURY
R0: THE FIRST DISPLAY ADDRESS
R1: THE START ADDRESS
R2: FLAG
R3: THE NUMBER OF DISPLAYED
DN: 循环次数
T_SEC EQU 40H
T_MIN EQU 41H
T_HOUR EQU 42H
T_DAY EQU 43H
T_MON EQU 44H
T_YE EQU 45H
T_CE EQU 46H
SHUH EQU 47H
SHUL EQU 48H
DN EQU 49H
SJ EQU 50H
MAIN:
MOV R2,#00H
LCALL INITDS 初始化时钟
START: MOV R2,#25
XH: LCALL RD12 读ds12c887
MOV SJ,T_HOUR
LCALL DISP
MOV SJ,T_MIN
LCALL DISP
MOV SJ,T_SEC
LCALL DISP
MOV R7,#5 延时0.4S
LCALL DELAY1S
DJNZ R2,XH
MOV R2,#20
MOV SJ,T_YE
LCALL DISP
MOV SJ,T_MON
LCALL DISP
MOV SJ,T_DAY
LCALL DISP
MOV R7,#50 延时4S
LCALL DELAY1S
LCALL BENDI 分号后为设置时间时用的
LCALL WDDS
AJMP START
DISP:
LCALL SJQL
MOV SCON,#00H
MOV DPTR,#SHU
MOV A,SHUH
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
MOV A,SHUL
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
RET
SJQL:
MOV A,SJ
MOV B,#10H
DIV AB
MOV SHUH,A
MOV SHUL,B
RET
RD12: 读12887
CLR P2.7
NOP
NOP
MOV DPTR,#200AH
MOVX A,@DPTR
ANL A,#80H
JNZ NEXT0
MOV DPTR,#2000H
MOVX A,@DPTR
MOV T_SEC,A
MOV DPTR,#2002H
MOVX A,@DPTR
MOV T_MIN,A
MOV DPTR,#2004H
MOVX A,@DPTR
MOV T_HOUR,A
MOV DPTR,#2007H
MOVX A,@DPTR
MOV T_DAY,A
MOV DPTR,#2008H
MOVX A,@DPTR
MOV T_MON,A
MOV DPTR,#2009H
MOVX A,@DPTR
MOV T_YE,A
MOV DPTR,#2032H
MOVX A,@DPTR
MOV T_CE,A
NEXT0: RET
INITDS:
MOV A,#20H 开启时钟
MOV DPTR,#200AH
MOVX @DPTR,A
MOV A,#02H BCD码携蚂模式,24小时制
MOV DPTR,#200BH
MOVX @DPTR,A
RET
WDDS:写入时间
MOV A,#70H
MOV DPTR,#200AH
MOVX @DPTR,A
MOV R7,#1
LCALL DELAY1S
MOV DPTR,#2000H
MOV A,T_SEC
MOVX @DPTR,A
MOV DPTR,#2002H
MOV A,T_MIN
MOVX @DPTR,A
MOV DPTR,#2004H
MOV A,T_HOUR
MOVX @DPTR,A
MOV DPTR,#2007H
MOV A,T_DAY
MOVX @DPTR,A
MOV DPTR,#2008H
MOV A,T_MON
MOVX @DPTR,A
MOV DPTR,#2009H
MOV A,T_YE
MOVX @DPTR,A
MOV DPTR,#2032H
MOV A,T_CE
MOVX @DPTR,A
MOV A,#20H
MOV DPTR,#200AH
MOVX @DPTR,A
RET
BENDI:设置时间
MOV T_SEC,#00H
MOV T_MIN,#17H
MOV T_HOUR,#19H
MOV T_DAY,#11H
MOV T_MON,#08H
MOV T_YE,#07H
MOV T_CE,#21H
RET
DELAY1S: 延时80MS
D1: MOV R6,#200
D2: MOV R5,#200
DJNZ R5,$
DJNZ R6,D2
DJNZ R7,D1
RET
SHU: DB FCH,60H,DAH,F2H,66H,B6H,BEH,E0H,FEH,F6H,EEH,3EH,9CH,7AH,9EH,8EH
END
#include<reg52.h>#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6
sbit wela=P2^7
sbit lcden=P2^2
sbit lcdrw=P2^1
sbit lcdrs=P2^0
sbit keymode=P3^0
sbit keyup=P3^1
sbit keydown=P3^2
sbit keyrd=P3^7
sbit dscs=P2^3
sbit dsds=P2^4
sbit dsrw=P2^5
sbit dsas=P3^6
sbit dsirq=P3^3
uint add,num,miao=10,fen=13,shi=10,count,mode,flag
uchar code table1[]=" 2012-03-11 STA "
uchar code table2[]="time is 00:00:00"
void delay(uint z)
{ uint x,y
for(x=zx>0x--)
for(y=110y>0y--)
}
void write_ds(uchar add,uchar date)
{
dscs=1
dsds=1
dsrw=1
dsas=1
P0=add
dscs=0
dsas=0
dsrw=0
P0=date
dsrw=1
dsas=1
dscs=1
/* dscs=0
dsas=1
dsds=1
dsrw=1
P1=add
dsas=0
dsrw=0
P1=date
dsrw=1
dsas=1
dscs=1*/
}
uchar read_ds(uchar add)
{
uchar ds_date
dscs=1
dsas=0
dsds=1
dsrw=1
dsas=1
P0=add
dscs=0
dsas=0
P0=0xff
dsds=0
ds_date=P0
dsds=1
dsas=1
dscs=1
/*dscs=0
dsas=1
dsds=1
dsrw=1
P1=add
dsas=0
dsds=0
P1=0xff
ds_date=P1
dsds=1
dsas=1
dscs=1*/
return ds_date
}
void set_time()
{
write_ds(4,7)
write_ds(2,59)
write_ds(0,45)
}
void write_com(uchar com)
{
lcdrw=0
lcdrs=0
lcden=0
P0=com
delay(5)
lcden=1
delay(5)
lcden=0
}
void write_data(uchar dat)
{
lcdrw=0
lcden=0
lcdrs=1
P0=dat
delay(5)
lcden=1
delay(5)
lcden=0
}
void init()
{
dula=0
wela=0
set_time()
lcden=0
write_com(0x38)
delay(5)
write_com(0x0c)
write_com(0x06)
write_com(0x01)
write_com(0x80)
for(num=0num<16num++)
{
write_data(table1[num])
delay(20)
}
write_com(0x80+0x40)
for(num=0num<16num++)
{
write_data(table2[num])
delay(20)
}
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge
write_com(0x80+0x40+add)
shi=date/10
ge=date%10
write_data(0x30+shi)
write_data(0x30+ge)
}
void keyscan()
{
keyrd=0
if(keymode==0)
{
delay(5)
if(keymode==0)
{
mode++
while(!keymode)
if(mode==1)
{
flag=1
write_com(0x80+0x40+15)
write_com(0x0f)
}
if(mode==2)
{
write_com(0x80+0x40+12)
write_com(0x0f)
}
if(mode==3)
{
write_com(0x80+0x40+9)
write_com(0x0f)
}
if(mode==4)
{
write_com(0x0c)
mode=0
flag=0
}
}
}
if(keymode!=0)
{
if(keyup==0)
{
delay(5)
if(keyup==0)
{
while(!keyup)
if(mode==1)
{
miao++
if(miao==60)
{
miao=0
}
write_sfm(14,miao)
write_com(0x80+0x40+15)
}
if(mode==2)
{
fen++
if(fen==60)
{
fen=0
}
write_sfm(11,fen)
write_com(0x80+0x40+12)
}
if(mode==3)
{
shi++
if(shi==24)
{
shi=0
}
write_sfm(8,shi)
write_com(0x80+0x40+9)
}
}
}
}
if(keydown==0)
{
while(!keydown)
if(mode==1)
{
miao--
if(miao==-1)
{
miao=59
}
write_sfm(14,miao)
write_com(0x80+0x40+15)
}
if(mode==2)
{
fen--
if(fen==-1)
{
fen=59
}
write_sfm(11,fen)
write_com(0x80+0x40+12)
}
if(mode==3)
{
shi--
if(shi==-1)
{
shi=23
}
write_sfm(8,shi)
write_com(0x80+0x40+9)
}
}
}
void main()
{
init()
while(1)
{
miao=read_ds(0)
fen=read_ds(2)
shi=read_ds(4)
write_sfm(14,miao)
write_sfm(11,fen)
write_sfm(8,shi)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)