#include<reg52.h>
#include<intrins.h>
#define U8 unsigned char
#define U16 unsigned int
#define BOOL bit
U8 secondh,secondl,minuteh,minutel,hourh,hourl,second,minute,hour
U8 monthl,monthh,month,day,datel,dateh,date,year,yearl,yearh
/***********定义LCD功能管脚**************************************/
sbit LCDRS = P2^6 //控世空制LCD数据或命灶李令的读写
sbit LCDRW = P2^5//控制LCD读写信号
sbit LCDEN = P2^7 /搜辩瞎/使能LCD
/***************************************************************/
/***********定义DS1302功能管脚*********************************/
sbit DSRST = P3^5 //DS1302复位管脚
sbit DSIO = P3^4 //控制DS1302数据传输
sbit DSCLK = P3^6//DS1302时钟
/***************************************************************/
/*******************延时函数***********************************/
void delay(U16 time)
{
U16 time1,time2
for(time1=timetime1>0time1--)
for(time2=110time2>0time2--)
}
/**************************************************************/
/***********检测LCD忙碌状态***********************************/
BOOL judge_lcd()
{
BOOL flag
LCDEN = 0
LCDRS = 0
LCDRW = 1
LCDEN = 1
delay(1)
flag=(BOOL)(P0&0x80) //状态位第7位为1时禁止读写,为0时可读写
LCDEN = 0
return flag
}
/**************************************************************/
/***********实现LCD写指令**************************************/
void write_lcd_command(U16 command)
{
while(judge_lcd()) //检测LCD是否为忙碌状态
P0 = command
LCDRS = 0
LCDRW = 0
LCDEN = 1
delay(1)
LCDEN = 0
}
/***************************************************************/
/***********实现LCD写数据**************************************/
void write_lcd_date(U16 date)
{
while(judge_lcd()) //检测LCD是否为忙碌状态
P0 = date
LCDRS = 1
LCDRW = 0
LCDEN = 1
delay(1)
LCDEN = 0
}
/***************************************************************/
/***********实现LCD写指令及数据********************************/
void write_lcd_com_date(U16 addr,U16 date)
{
write_lcd_command(addr)
delay(1)
write_lcd_date(date)
}
/**************************************************************/
/******************初始化LCD***********************************/
void init_lcd()
{
write_lcd_command(0x38) //设置16x2显示,5x7点阵,8位数据口
delay(1)
write_lcd_command(0x0c) //开显示,不显示光标,光标不闪烁
delay(1)
write_lcd_command(0x06)//读写一个字符后,地址自动加1,不移动屏幕
delay(1)
write_lcd_command(0x01) //清屏
delay(1)
}
/**************************************************************/
/**********************读DS1302********************************/
U8 read_ds1302(U8 addr)
{
U8 i,temp=0x00
DSRST=0
DSIO=1
DSCLK=0
DSRST=1
for (i=0i<8i++) //循环8次 写入地址数据
{
DSCLK=0
DSIO=addr&0x01 //每次传输低字节
addr>>=1 //右移一位
DSCLK=1
}
delay(1)
if(DSIO)
temp|=0x80 //每次传输低字节
DSCLK=0
temp>>=1
for (i=0i<7i++) //循环8次 读取数据
{
DSCLK=0
if(DSIO)
temp|=0x80 //每次传输低字节
DSCLK=1
temp>>=1 //右移一位
}
DSCLK=1
DSRST=0
DSIO=0
return temp //返回
}
/************************************************************/
/******************写DS1302**********************************/
void write_ds1302(U8 addr, U8 date)
{
U8 i
DSRST=0
DSCLK=0
DSRST=1
for (i=0i<8i++) //循环8次 写入地址数据
{
DSCLK=0
_nop_()
DSIO=addr&0x01 //每次传输低字节
addr>>=1 //右移一位
DSCLK=1
_nop_()
}
for (i=0i<8i++) //循环8次 写入数据
{
DSCLK=0
_nop_()
DSIO=date&0x01 //每次传输低字节
date>>=1 //右移一位 DSCLK=1
DSCLK=1
_nop_()
}
DSRST=0
delay(1)
}
/**************************************************************/
/*****************初始化DS1302********************************/
void init_ds1302()
{
//读秒
if((((second=read_ds1302(0x81))>>7)&&0x01)==1)
{
write_ds1302(0x8e,0x00) //关闭写保护
write_ds1302(0x80,0x00) //00秒
write_ds1302(0x82,0x54) //54分
write_ds1302(0x84,0x17) //17点
write_ds1302(0x86,0x14) //14日
write_ds1302(0x88,0x10) //10月
write_ds1302(0x8a,0x05) //星期五
write_ds1302(0x8c,0x11) //2011年
write_ds1302(0x8e,0x80) //允许写保护
}
}
/********************************************************/
/*********************主函数****************************/
void main()
{
init_lcd()
delay(2)
write_lcd_com_date(0x81,'2')
write_lcd_com_date(0x82,'0')
delay(1)
init_ds1302()
delay(1)
while(1)
{
second=read_ds1302(0x81)
secondl=second&0x0f
secondh=second>>4
minute=read_ds1302(0x83)
minutel=minute&0x0f
minuteh=minute>>4
hour=read_ds1302(0x85)
hourl=hour&0x0f
hourh=hour>>4
month=read_ds1302(0x89)
monthl=month&0x0f
monthh=month>>4
year=read_ds1302(0x8d)
yearl=year&0x0f
yearh=year>>4
date=read_ds1302(0x87)
datel=date&0x0f
dateh=date>>4
day=read_ds1302(0x8b)
day=day&0x0f
delay(15)
write_lcd_com_date(0xca,0x30+secondl)
write_lcd_com_date(0xc9,0x30+secondh)
write_lcd_com_date(0xc8,':')
write_lcd_com_date(0xc7,0x30+minutel)
write_lcd_com_date(0xc6,0x30+minuteh)
write_lcd_com_date(0xc5,':')
write_lcd_com_date(0xc4,0x30+hourl)
write_lcd_com_date(0xc3,0x30+hourh)
write_lcd_com_date(0x84,0x30+yearl)
write_lcd_com_date(0x83,0x30+yearh)
write_lcd_com_date(0x85,'-')
write_lcd_com_date(0x87,0x30+monthl)
write_lcd_com_date(0x86,0x30+monthh)
write_lcd_com_date(0x88,'-')
write_lcd_com_date(0x8a,0x30+datel)
write_lcd_com_date(0x89,0x30+dateh)
write_lcd_com_date(0x8c,0x30+day)
}
}
这是一个时钟显示程序,里面有1602的 *** 作程序,比较完敏岩整绝对能运行RS=P2.0 RW=P2.1 E=P2.2 DB0---DB7接P0口
/*******************************************************************/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS = P2^0
sbit LCD_RW = P2^1
sbit LCD_EN = P2^2
sbit LCD_LED = P2^6
bitflag=1,hour=0,min=0,sec=0
bityear=0,month=0,day=0,week=0
bitalarm_flag=0
uchar timecount=0,count=0
uchar str1[]=" - - Week: "
uchar str2[]="Time: "
uchar str3[]="Alarm: "
uchar init [] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00} //
uchar init1[] ={0x00,0x00}
uchar init2[] ={0x00,0x59,0x23,0x01,0x05,0x01,0x06}//
//秒, 分, 时, 日, 月,星期,年
uchar bj_time[] ={0x00,0x00,0x00}
//秒,物拿运 分, 时
uchar code mytab[8] = {0x01,0x1b,0x1d,0x19,0x1d,0x1b,0x01,0x00}//小喇叭
#define delayNOP(){_nop_()_nop_()_nop_()_nop_()}
void Set_place(uchar row,uchar col)
void Play_nowtime()
void key_set(uchar num,uchar row,uchar col )
void alarm_time()
void Play_alarmtime()
void Time_compare()
/******************************************************************/罩梁
/******************************************************************/
void delay1(int ms)
{
unsigned char y
while(ms--)
{
for(y = 0y<250y++)
{
_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
}
/*********************************************************/
/* */
/*写显示数据到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 init_lcd()
{
delay1(15)
lcd_wcmd(0x01) //清除LCD的显示内容
lcd_wcmd(0x38) //16*2显示,5*7点阵,8位数据
delay1(5)
lcd_wcmd(0x38)
delay1(5)
lcd_wcmd(0x38)
delay1(5)
lcd_wcmd(0x0c) //显示开,关光标
delay1(5)
lcd_wcmd(0x06) //移动光标
delay1(5)
lcd_wcmd(0x01) //清除LCD的显示内容
delay1(5)
}
/*********************************************************/
//
/*********************************************************/
void delay()
{
uchar j
for(j=250j>0j--)
}
/*********************************************************/
/* */
/* 写字符串函数 */
/* */
/*********************************************************/
void write_str(uchar addr,uchar *p)
{
uchar i=0
lcd_wcmd(addr)
while(p[i]!='\0')
{
lcd_wdat(p[i])
i++
}
}
/*********************************************************/
/* */
/* 设定显示位置 */
/* */
/*********************************************************/
void write_position(uchar row,uchar col)
{
uchar place
if(row==1)
{
place=0x80+col-1
lcd_wcmd(place)
}
else
{
place=0xc0+col-1
lcd_wcmd(place)
}
}
/*********************************************************/
/* */
/*自定义字符写入CGRAM*/
/* */
/*********************************************************/
void writetab()
{
unsigned char i
lcd_wcmd(0x40) //写CGRAM
for (i = 0i<8i++)
lcd_wdat(mytab[i])
}
/**********************************************************/
//
/**********************************************************/
void write_byte(uchar inbyte)
{
uchar i
for(i=0i<8i++)
{
sclk=0//写的时候低电平改变数据
if(inbyte&0x01)
io=1
else
io=0
sclk=1 //写的时候高电平,把数据写入ds1302
_nop_()
inbyte=inbyte>>1
}
}
/**********************************************************/
/**********************************************************/
uchar read_byte()//sclk的下跳沿读数据
{
uchar i,temp=0
io=1 //设置为输入口
for(i=0i<7i++)
{
sclk=0
if(io==1)
temp=temp|0x80
else
temp=temp&0x7f
sclk=1//产生下跳沿
temp=temp>>1
}
return (temp)
}
/**********************************************************/
// 往ds1302的某个地址写入数据
/**********************************************************/
void write_ds1302(uchar cmd,uchar indata)
{
sclk=0
reset=1
write_byte(cmd)
write_byte(indata)
sclk=0
reset=0
}
/**********************************************************/
// 读ds1302某地址的的数据
/**********************************************************/
uchar read_ds1302(uchar addr)
{
uchar backdata
sclk=0
reset=1
write_byte(addr) //先写地址
backdata=read_byte() //然后读数据
sclk=0
reset=0
return (backdata)
}
/**********************************************************/
// 设置初始时间
/**********************************************************/
void set_ds1302(uchar addr,uchar *p,uchar n) //写入n个数据
{
write_ds1302(0x8e,0x00) //写控制字,允许写 *** 作
for(n>0n--)
{
write_ds1302(addr,*p)
p++
addr=addr+2
}
write_ds1302(0x8e,0x80) //写保护,不允许写
}
/**********************************************************/
// 读取当前时间
/**********************************************************/
void read_nowtime(uchar addr,uchar *p,uchar n)
{
for(n>0n--)
{
*p=read_ds1302(addr)
p++
addr=addr+2
}
}
/**********************************************************/
// 初始化DS1302
/**********************************************************/
void init_ds1302()
{
reset=0
sclk=0
write_ds1302(0x80,0x00)
write_ds1302(0x90,0xa6)//一个二极管+4K电阻充电
write_ds1302(0x8e,0x80)//写保护控制字,禁止写
}
/**********************************************************/
/**/
/* 蜂鸣器响一声 */
/**/
/**********************************************************/
void beep()
{
unsigned char y
for (y=0y<100y++)
{
delay()
BEEP=!BEEP //BEEP取反
}
BEEP=1 //关闭蜂鸣器
delay1(50)
}
/**********************************************************/
/**/
/* :闪动函数 */
/**/
/**********************************************************/
void flash()
{
if(flag)
{
write_position(2,9)
lcd_wdat(':')
write_position(2,12)
lcd_wdat(':')
}
else
{
write_position(2,9)
lcd_wdat(0x20)
write_position(2,12)
lcd_wdat(0x20)
}
}
/**********************************************************/
// 主函数
/**********************************************************/
void main()
{
LCD_LED=0
P1=0xff
TMOD=0x01
TH0=0x4c //50ms定时
TL0=0x00
EA=1
ET0=1
TR0=1
init_lcd()//初始化LCD
write_str(0x80,str1) //液晶显示提示信息
write_str(0xc0,str2) //液晶显示提示信息
init_ds1302() //初始化ds1302
writetab() //自定义字符写入CGRAM
// delay1(5)
// write_position(2,16)
// lcd_wdat(0x00) //显示自定义字符小喇叭
while(1)
{
//---------------------------------------------------------
if(!K1)
{
if(!K2)
{
set_ds1302(0x80,init2,7) //设置初始时间,日期,年月
beep()
}
if(!K3)
{
write_str(0xc0,str3) //显示报警信息
if(alarm_flag) //alarm_flag=1,开定时
{
write_position(2,16)
lcd_wdat(0x00) //显示自定义字符小喇叭
}
Play_alarmtime() //查看报警时间
beep()
delay1(700)
write_str(0xc0,str2) //显示时间信息
if(alarm_flag) //alarm_flag=1,开定时
{
write_position(2,16)
lcd_wdat(0x00) //显示自定义字符小喇叭
}
}
if(!K4)
{
alarm_time()//K4键设定报警时间
if(alarm_flag) //alarm_flag=1,开定时
{
write_position(2,16)
lcd_wdat(0x00) //显示自定义字符小喇叭
}
}
}
//---------------------------------------------------------
if(!K4)
{
beep()
alarm_flag=~alarm_flag
if(alarm_flag) //alarm_flag=1,开定时
{
write_position(2,16)
lcd_wdat(0x00) //显示自定义字符小喇叭
}
else
{
write_position(2,16)
lcd_wdat(0x20) //显示自定义字符小喇叭
}
}
//---------------------------------------------------------
if(!K3&flag) //开始设定时间
{
write_ds1302(0x8e,0x00) //写保护控制字,允许写
write_ds1302(0x80,0x80) //停止时钟运行
write_ds1302(0x8e,0x80) //写保护控制字,禁止写
beep()
year=1
count=((init[6]&0xf0)>>4)*10+(init[6]&0x0f) //读当前年数据
}
while(year) //设定年
{
key_set(99,1,1)
if(!K3)
{
Set_W1302(0x8c)
Set_place(1,1)
year=0
month=1
count=((init[4]&0xf0)>>4)*10+(init[4]&0x0f) //读当前月数据
}
}
while(month) //设定月
{
key_set(12,1,4)
if(!K3)
{
Set_W1302(0x88)
Set_place(1,4)
month=0
day=1
count=((init[3]&0xf0)>>4)*10+(init[3]&0x0f)//读当前日数据
}
}
while(day) //设定日
{
key_set(31,1,7)
if(!K3)
{
Set_W1302(0x86)
Set_place(1,7)
day=0
week=1
count=init[5]&0x0f //读当前星期数据
}
}
while(week) //设定星期
{
if(!K2)
{
beep()
if(count!=7)
count++
else count=1
}
if(!K1)
{
beep()
if(count!=1)
count--
else count=7
}
init1[1]=count%10
if(flag)
{
write_position(1,15)
lcd_wdat(init1[1]+0x30)
}
else
{
write_position(1,15)
lcd_wdat(0x20)
}
if(!K3)
{
Set_W1302(0x8a)
write_position(1,15)
lcd_wdat(init1[1]+0x30)
week=0
hour=1
count=((init[2]&0xf0)>>4)*10+(init[2]&0x0f)//读当前时数据
}
}
while(hour) //设定时
{
key_set(23,2,7)
if(!K3)
{
Set_W1302(0x84)
Set_place(2,7)
hour=0
min=1
count=((init[1]&0xf0)>>4)*10+(init[1]&0x0f)//读当前分数据
}
}
while(min)//设定分
{
key_set(59,2,10)
if(!K3)
{
Set_W1302(0x82)
Set_place(2,10)
min=0
sec=1
count=((init[0]&0xf0)>>4)*10+(init[0]&0x0f) //读当前秒数据
}
}
while(sec)//设定秒
{
key_set(59,2,13)
if(!K3)
{
Set_W1302(0x80)
Set_place(2,13)
sec=0
count=0
}
}
Play_nowtime()
Time_compare()
}
}
/**********************************************************/
// Time0中断函数
/**********************************************************/
void Time0(void) interrupt 1 using 0
{
TH0=0x4c//50ms定时
TL0=0x00
timecount++
if(timecount>9)
{
timecount=0
flag=~flag
}
}
/**********************************************************/
// 设定值写入DS1302
/**********************************************************/
void Set_W1302(uchar addr)
{
uchar temp
write_ds1302(0x8e,0x00)
temp=(init1[0]<<4)+init1[1]
write_ds1302(addr,temp)
write_ds1302(0x8e,0x80)
beep()
}
/**********************************************************/
// 被设置数据闪动
/**********************************************************/
void Set_Flash(uchar row,uchar col )
{
init1[0]=count/10
init1[1]=count%10
if(flag)
{//显示
write_position(row,col)
lcd_wdat(init1[0]+0x30)
write_position(row,col+1)
lcd_wdat(init1[1]+0x30)
}
else
{//清屏
write_position(row,col)
lcd_wdat(0x20)
write_position(row,col+1)
lcd_wdat(0x20)
}
}
/**********************************************************/
// 指定位置显示
/**********************************************************/
void Set_place(uchar row,uchar col)
{
write_position(row,col)
lcd_wdat(init1[0]+0x30)
write_position(row,col+1)
lcd_wdat(init1[1]+0x30)
}
/**********************************************************/
// 显示当前时间
/**********************************************************/
void Play_nowtime()
{
read_nowtime(0x81,init,7) //读出当前时间,读出7个字节
write_position(2,7)
lcd_wdat(((init[2]&0xf0)>>4)+0x30)
write_position(2,8)
lcd_wdat('0'+(init[2]&0x0f))//读小时
//write_position(2,9)
//lcd_wdat(':')
write_position(2,10)
lcd_wdat('0'+((init[1]&0xf0)>>4))
write_position(2,11)
lcd_wdat('0'+(init[1]&0x0f))//读分钟
//write_position(2,12)
//lcd_wdat(':')
write_position(2,13)
lcd_wdat('0'+((init[0]&0xf0)>>4))
write_position(2,14)
lcd_wdat('0'+(init[0]&0x0f))//读秒
write_position(1,1)
lcd_wdat('0'+((init[6]&0xf0)>>4))
write_position(1,2)
lcd_wdat('0'+(init[6]&0x0f))//读年
//write_position(1,3)
//lcd_wdat('/')
write_position(1,4)
lcd_wdat('0'+((init[4]&0xf0)>>4))
write_position(1,5)
lcd_wdat('0'+(init[4]&0x0f))//读月
//write_position(1,6)
//lcd_wdat('/')
write_position(1,7)
lcd_wdat('0'+((init[3]&0xf0)>>4))
write_position(1,8)
lcd_wdat('0'+(init[3]&0x0f))//读日
write_position(1,15)
lcd_wdat('0'+(init[5]&0x0f))//读周
flash()
}
/*********************************************************/
// 键设定函数
/*********************************************************/
void key_set(uchar num,uchar row,uchar col )
{
if(!K2)
{
beep()
if(count!=num)
count++
else count=0
}
if(!K1)
{
beep()
if(count!=0)
count--
else count=num
}
Set_Flash(row,col)
}
/*********************************************************/
// 报警时间设定
/*********************************************************/
void alarm_time()
{
// if(!K4&flag) //开始设定报警时间
{
write_str(0xc0,str3) //液晶显示提示信息
Play_alarmtime()
beep()
hour=1
count=((bj_time[2]&0xf0)>>4)*10+(bj_time[2]&0x0f) //读当前时报警数据
while(hour) //设定时
{
key_set(23,2,7)
if(!K4)
{
Set_place(2,7)
bj_time[2]=((init1[0]<<4)|init1[1])
beep()
hour=0
min=1
count=((bj_time[1]&0xf0)>>4)*10+(bj_time[1]&0x0f)//读当前分报警数据
}
}
while(min) //设定分
{
key_set(59,2,10)
if(!K4)
{
Set_place(2,10)
bj_time[1]=((init1[0]<<4)|init1[1])
beep()
min=0
sec=0
count=((bj_time[0]&0xf0)>>4)*10+(bj_time[0]&0x0f)//读当前秒报警数据
write_str(0xc0,str2) //液晶显示提示信息
}
}
/*
while(sec) //设定秒
{
key_set(59,2,13)
if(!K4)
{
Set_place(2,13)
bj_time[0]=((init1[0]<<4)|init1[1])
beep()
min=0
sec=0
count=0
write_str(0xc0,str2) //液晶显示提示信息
}
}*/
}
}
/*********************************************************/
// 报警时间显示
/*********************************************************/
void Play_alarmtime()
{
write_position(2,7)
lcd_wdat(((bj_time[2]&0xf0)>>4)+0x30)
write_position(2,8)
lcd_wdat('0'+(bj_time[2]&0x0f))//读小时
write_position(2,9)
lcd_wdat(':')
write_position(2,10)
lcd_wdat('0'+((bj_time[1]&0xf0)>>4))
write_position(2,11)
lcd_wdat('0'+(bj_time[1]&0x0f))//读分钟
write_position(2,12)
lcd_wdat(':')
write_position(2,13)
lcd_wdat('0'+((bj_time[0]&0xf0)>>4))
write_position(2,14)
lcd_wdat('0'+(bj_time[0]&0x0f))//读秒
}
/*********************************************************/
// 时间比较
/*********************************************************/
void Time_compare()
{
if(alarm_flag)
{
if(init[2]==bj_time[2])
{
if(init[1]==bj_time[1])
beep()
}
}
}
/*********************************************************/
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)