📄 lcd_clock_ds1302.c
字号:
#include <reg51.h>
#include<intrins.h>
#define u8 unsigned char
#define u16 unsigned int
#ifndef lcd_char_1602_2008_3_3
#define lcd_char_1602_2008_3_3
//Port Definitions**********************************************************
sbit lcdrs = P0^2;
sbit lcdrw = P0^1;
sbit lcden = P0^0;
sfr dbport = 0xa0; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
//内部等待函数**************************************************************************
u8 lcd_wait(void)
{
lcdrs=0;
lcdrw=1; _nop_();
lcden=1; _nop_();
//while(dbport&0x80);//在用Proteus仿真时,注意用屏蔽此语句,在调用gotoxy()时,会进入死循环,
//可能在写该控制字时,该模块没有返回写入完备命令,即dbport&0x80==0x80
//实际硬件时打开此语句
lcden=0;
return dbport;
}
//向LCD写入命令或数据************************************************************
#define lcd_command 0 // Command
#define lcd_data 1 // Data
#define lcd_clear_screen 0x01 // 清屏
#define lcd_homing 0x02 // 光标返回原点
void lcd_write(bit style, u8 input)
{
lcden=0;
lcdrs=style;
lcdrw=0; _nop_();
dbport=input; _nop_();//注意顺序
lcden=1; _nop_();//注意顺序
lcden=0; _nop_();
lcd_wait();
}
//设置显示模式************************************************************
#define lcd_show 0x04 //显示开
#define lcd_hide 0x00 //显示关
#define lcd_cursor 0x02 //显示光标
#define lcd_no_cursor 0x00 //无光标
#define lcd_flash 0x01 //光标闪动
#define lcd_no_flash 0x00 //光标不闪动
void lcd_setdisplay(u8 DisplayMode)
{
lcd_write(lcd_command, 0x08|DisplayMode);
}
//设置输入模式************************************************************
#define lcd_ac_up 0x02
#define lcd_ac_down 0x00 // default
#define lcd_move 0x01 // 画面可平移
#define lcd_no_move 0x00 //default
void lcd_setinput(u8 inputmode)
{
lcd_write(lcd_command, 0x04|inputmode);
}
//移动光标或屏幕************************************************************
/*
#define lcd_cursor 0x02
#define LCD_SCREEN 0x08
#define LCD_LEFT 0x00
#define LCD_RIGHT 0x04
void lcd_move(u8 object, u8 direction)
{
if(object==lcd_cursor)
lcd_write(lcd_command,0x10|direction);
if(object==LCD_SCREEN)
lcd_write(lcd_command,0x18|direction);
}
*/
//初始化LCD************************************************************
void lcd_initial()
{
lcden=0;
lcd_write(lcd_command,0x38); //8位数据端口,2行显示,5*7点阵
lcd_write(lcd_command,0x38);
lcd_setdisplay(lcd_show|lcd_no_cursor); //开启显示, 无光标
lcd_write(lcd_command,lcd_clear_screen); //清屏
lcd_setinput(lcd_ac_up|lcd_no_move); //AC递增, 画面不动
}
//************************************************************************
void gotoxy(u8 x, u8 y)
{
if(y==0)
lcd_write(lcd_command,0x80|x);
if(y==1)
lcd_write(lcd_command,0x80|(x-0x40));
}
/*void print(u8 *str)
{
while(*str!='\0')
{
lcd_write(lcd_data,*str);
str++;
}
}*/
void print(u8 *str)
{
while(*str!='\0')
{
lcd_write(lcd_data,*str);
str++;
}
}
/*
void LCD_LoadChar(u8 user[8], u8 place)
{
u8 i;
lcd_write(lcd_command,0x40|(place*8));
for(i=0; i<8; i++)
lcd_write(lcd_data,user[i]);
}
*/
//************************************************************************
#endif
/**************************************************************************
THE REAL timeR DS1302 DRIVER LIB
COPYRIGHT (c) 2005 BY JJJ.
-- ALL RIGHTS RESERVED --
File Name: DS1302.h
Author: Jiang Jian Jun
Created: 2003/7/21
Modified: NO
Revision: 1.0
***************************************************************************/
#ifndef _REAL_timeR_DS1302_2003_7_21_
#define _REAL_timeR_DS1302_2003_7_21_
sbit ds1302_clk = P1^1; //实时时钟时钟线引脚
sbit ds1302_io = P1^0; //实时时钟数据线引脚
sbit ds1302_rst = P1^2; //实时时钟复位线引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
typedef struct __systemtime__
{
u8 second;
u8 minute;
u8 hour;
u8 week;
u8 day;
u8 month;
u8 year;
u8 datestring[9];
u8 timestring[9];
}systemtime; //定义的时间类型
#define AM(X) X
#define PM(X) (X+12) // 转成24小时制
#define ds1302_second 0x80
#define ds1302_minute 0x82
#define ds1302_hour 0x84
#define ds1302_week 0x8A
#define ds1302_day 0x86
#define ds1302_month 0x88
#define ds1302_year 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2) //用于计算 DS1302_RAM 地址的宏
void ds1302inputbyte(u8 d) //实时时钟写入一字节(内部函数)
{
u8 i;
ACC = d;
for(i=8; i>0; i--)
{
ds1302_io = ACC0; //相当于汇编中的 RRC
ds1302_clk = 1;
ds1302_clk = 0;
ACC = ACC >> 1;
}
}
u8 ds1302ouputbyte(void) //实时时钟读取一字节(内部函数)
{
u8 i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = ds1302_io;
ds1302_clk = 1;
ds1302_clk = 0;
}
return(ACC);
}
void write1302(u8 ucAddr, u8 ucDa) //ucAddr: DS1302地址, ucdata: 要写的数据
{
ds1302_rst = 0;
ds1302_clk = 0;
ds1302_rst = 1;
ds1302inputbyte(ucAddr); // 地址,命令
ds1302inputbyte(ucDa); // 写1Byte数据
ds1302_clk = 1;
ds1302_rst = 0;
}
u8 read1302(u8 ucAddr) //读取DS1302某地址的数据
{
u8 ucdata;
ds1302_rst = 0;
ds1302_clk = 0;
ds1302_rst = 1;
ds1302inputbyte(ucAddr|0x01); // 地址,命令
ucdata = ds1302ouputbyte(); // 读1Byte数据
ds1302_clk = 1;
ds1302_rst = 0;
return(ucdata);
}
void ds1302_setprotect(bit flag) //是否写保护
{
if(flag)
write1302(0x8E,0x10);
else
write1302(0x8E,0x00);
}
void ds1302_settime(u8 address, u8 Value) // 设置时间函数
{
ds1302_setprotect(0);
write1302(address, ((Value/10)<<4 | (Value%10)));
}
void ds1302_gettime(systemtime *time)
{
u8 readvalue;
readvalue = read1302(ds1302_second);
time->second = ((readvalue&0x70)>>4)*10+readvalue&0x0f;
readvalue = read1302(ds1302_minute);
time->minute = ((readvalue&0x70)>>4)*10 + (readvalue&0x0F);
readvalue = read1302(ds1302_hour);
time->hour = ((readvalue&0x70)>>4)*10 + (readvalue&0x0F);
readvalue = read1302(ds1302_day);
time->day = ((readvalue&0x70)>>4)*10 + (readvalue&0x0F);
readvalue = read1302(ds1302_week);
time->week = ((readvalue&0x70)>>4)*10 + (readvalue&0x0F);
readvalue = read1302(ds1302_month);
time->month = ((readvalue&0x70)>>4)*10 + (readvalue&0x0F);
readvalue = read1302(ds1302_year);
time->year = ((readvalue&0x70)>>4)*10 + (readvalue&0x0F);
}
void datatostr(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->datestring[8] = '\0';
}
void initial_ds1302(void)
{
u8 second=read1302(ds1302_second);
if(second&0x80)
ds1302_settime(ds1302_second,0);
}
/********************************************************************************
void Burstwrite1302(u8 *pWClock) //往DS1302写入时钟数据(多字节方式)
{
u8 i;
write1302(0x8e,0x00); // 控制命令,WP=0,写操作?
ds1302_rst = 0;
ds1302_clk = 0;
ds1302_rst = 1;
ds1302inputbyte(0xbe); // 0xbe:时钟多字节写命令
for (i = 8; i>0; i--) //8Byte = 7Byte 时钟数据 + 1Byte 控制
{
ds1302inputbyte(*pWClock); // 写1Byte数据
pWClock++;
}
ds1302_clk = 1;
ds1302_rst = 0;
}
void Burstread1302(u8 *pRClock) //读取DS1302时钟数据(时钟多字节方式)
{
u8 i;
ds1302_rst = 0;
ds1302_clk = 0;
ds1302_rst = 1;
ds1302inputbyte(0xbf); // 0xbf:时钟多字节读命令
for (i=8; i>0; i--)
{
*pRClock = ds1302ouputbyte(); // 读1Byte数据
pRClock++;
}
ds1302_clk = 1;
ds1302_rst = 0;
}
void DS1302_timeStop(bit flag) // 是否将时钟停止
{
u8 Data;
Data=read1302(ds1302_second);
ds1302_setprotect(0);
if(flag)
write1302(ds1302_second, Data|0x80);
else
write1302(ds1302_second, Data&0x7F);
}
********************************************************************************/
#endif
void delay(u16 count)
{
u16 i,j;
for(i=0;i<count;i++)
for(j=0;j<120;j++);
}
main()
{
systemtime currenttime;
lcd_initial();
initial_ds1302();
gotoxy(0,0);
print("Date: ");
gotoxy(0,1);
print("time: ");
while(1)
{
ds1302_gettime(¤ttime);
datatostr(¤ttime);
timetostr(¤ttime);
gotoxy(6,0);
print(currenttime.datestring);
gotoxy(6,1);
print(currenttime.timestring);
delay(300);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -