at89c52单片机和ds12c887时钟c语言程序

at89c52单片机和ds12c887时钟c语言程序,第1张

//说明:6位数码管显示时,分,秒键盘可调时间

//晶振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)//显示地址

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11102053.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存