时钟DS1302LCD

/********************************************************************

* 描述 : 该文件实现用DS1302来实现日历和时钟功能,液晶1602上显示出来。

***********************************************************************/

#include<reg52.h>

#include<intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit ACC0 = ACC^0;

sbit ACC7 = ACC^7;

sbit T_CLK = P1^6; /*实时时钟时钟线引脚 */

sbit T_IO = P3^5; /*实时时钟数据线引脚 */

sbit T_RST = P1^7; /*实时时钟复位线引脚 */

//这三个引脚参考资料

sbit E=P2^7; //1602使能引脚

sbit RW=P2^6; //1602读写引脚

sbit RS=P2^5; //1602数据/命令选择引脚

/********************************************************************

* 名称 : delay()

* 功能 : 延时,延时时间大概为140US。

* 输入 : 无

* 输出 : 无

***********************************************************************/

void delay()

{

int i,j;

for(i=0; i<=10; i++)

for(j=0; j<=2; j++)

;

}

/********************************************************************

* 名称 : enable(uchar del)

* 功能 : 1602命令函数

* 输入 : 输入的命令值

* 输出 : 无

***********************************************************************/

void enable(uchar del)

{

P0 = del;

RS = 0;

RW = 0;

E = 0;

delay();

E = 1;

delay();

}

/********************************************************************

* 名称 : write(uchar del)

* 功能 : 1602写数据函数

* 输入 : 需要写入1602的数据

* 输出 : 无

***********************************************************************/

void write(uchar del)

{

P0 = del;

RS = 1;

RW = 0;

E = 0;

delay();

E = 1;

delay();

}

/********************************************************************

* 名称 : L1602_init()

* 功能 : 1602初始化,请参考1602的资料

* 输入 : 无

* 输出 : 无

***********************************************************************/

void L1602_init(void)

{

enable(0x01);

enable(0x38);

enable(0x0c);

enable(0x06);

enable(0xd0);

}

/********************************************************************

* 名称 : L1602_char(uchar hang,uchar lie,char sign)

* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下

L1602_char(1,5,'b')

* 输入 : 行,列,需要输入1602的数据

* 输出 : 无

***********************************************************************/

void L1602_char(uchar hang,uchar lie,char sign)

{

uchar a;

if(hang == 1) a = 0x80;

if(hang == 2) a = 0xc0;

a = a + lie - 1;

enable(a);

write(sign);

}

/********************************************************************

* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)

* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下

L1602_string(1,5,"ab cd ef;")

* 输入 : 行,列,需要输入1602的数据

* 输出 : 无

***********************************************************************/

void L1602_string(uchar hang,uchar lie,uchar *p)

{

uchar a;

if(hang == 1) a = 0x80;

if(hang == 2) a = 0xc0;

a = a + lie - 1;

enable(a);

while(1)

{

if(*p == '\0') break;

write(*p);

p++;

}

}

/********************************************************************

* 名称 : v_RTInputByte()

* 功能 : 往DS1302写入1Byte数据

* 输入 : ucDa 写入的数据

* 输出 : 无

***********************************************************************/

void v_RTInputByte(uchar ucDa)

{

uchar i;

ACC = ucDa;

T_RST = 1;

for(i=8; i>0; i--)

{

T_IO = ACC0;

T_CLK = 1;

T_CLK = 0;

ACC = ACC >> 1;

}

}

/********************************************************************

* 名称 : uc_RTOutputByte()

* 功能 : 从DS1302读取1Byte数据

* 输入 : 无

* 返回值: ACC

***********************************************************************/

uchar uc_RTOutputByte(void)

{

uchar i;

T_RST = 1;

for(i=8; i>0; i--)

{

ACC = ACC >>1;

T_IO=1;

ACC7 = T_IO;

T_CLK = 1;

T_CLK = 0;

}

return(ACC);

}

/********************************************************************

* 名称 : v_W1302(uchar ucAddr, uchar ucDa)

* 功能 : 往DS1302写入数据

* 输入 : ucAddr: DS1302地址, ucDa: 要写的数据

* 返回值 : 无

***********************************************************************/

void v_W1302(uchar ucAddr, uchar ucDa)

{

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(ucAddr); // 写地址

nop();

nop();

v_RTInputByte(ucDa); // 写1Byte数据

T_CLK = 1;

T_RST = 0;

}

/********************************************************************

* 名称 : uc_R1302(uchar ucAddr)

* 功能 : 读取DS1302某地址的数据

* 输入 : ucAddr: DS1302地址

* 返回值 : ucDa :读取的数据

***********************************************************************/

uchar uc_R1302(uchar ucAddr)

{

uchar ucDa;

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(ucAddr); //写地址,命令

nop();

nop();

ucDa = uc_RTOutputByte(); //读1Byte数据

T_CLK = 1;

T_RST = 0;

return(ucDa);

}

/********************************************************************

* 名称 : v_BurstW1302T

* 功能 : 往DS1302写入时钟数据(多字节方式)

* 输入 : pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制

* 8Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 1B

* 返回值 : 无

***********************************************************************/

void v_BurstW1302T(uchar *pSecDa)

{

uchar i;

v_W1302(0x8e, 0x00); //控制命令,WP=0,写操作

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(0xbe); //0xbe:时钟多字节写命令

for(i=8; i>0; i--) //8Byte = 7Byte 时钟数据 + 1Byte 控制

{

v_RTInputByte(*pSecDa); //写1Byte数据

pSecDa++;

}

T_CLK = 1;

T_RST = 0;

}

/********************************************************************

* 名称 : v_BurstR1302T(uchar *pSecDa)

* 功能 : 读取DS1302时钟数据

* 输入 : pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年

* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B

* 返回值 : ucDa :读取的数据

***********************************************************************/

void v_BurstR1302T(uchar *pSecDa)

{

uchar i;

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(0xbf); //0xbf:时钟多字节读命令

for(i=8; i>0; i--)

{

*pSecDa = uc_RTOutputByte(); //读1Byte数据

pSecDa++;

}

T_CLK = 1;

T_RST = 0;

}

/********************************************************************

* 名称 : v_BurstW1302R(uchar *pReDa)

* 功能 : 往DS1302寄存器数写入数据(多字节方式)

* 输入 : pReDa: 寄存器数据地址

* 返回值 : 无

***********************************************************************/

void v_BurstW1302R(uchar *pReDa)

{

uchar i;

v_W1302(0x8e,0x00); //控制命令,WP=0,写操作

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(0xfe); //0xbe:时钟多字节写命令

for(i=31; i>0; i--) //31Byte 寄存器数据

{

v_RTInputByte(*pReDa); //写1Byte数据

pReDa++;

}

T_CLK = 1;

T_RST = 0;

}

/********************************************************************

* 名称 : v_BurstR1302R(uchar *pReDa)

* 功能 : 读取DS1302寄存器数据

* 输入 : pReDa: 寄存器数据地址

* 返回值 : 无

***********************************************************************/

void v_BurstR1302R(uchar *pReDa)

{

uchar i;

T_RST = 0;

T_CLK = 0;

T_RST = 1;

v_RTInputByte(0xff); //0xbf:时钟多字节读命令

for(i=31; i>0; i--) //31Byte 寄存器数据

{

*pReDa = uc_RTOutputByte(); //读1Byte数据

pReDa++;

}

T_CLK = 1;

T_RST = 0;

}

/********************************************************************

* 名称 : v_Set1302(uchar *pSecDa)

* 功能 : 设置初始时间

* 输入 : pSecDa: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年

* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B

* 返回值: 无

***********************************************************************/

void v_Set1302(uchar *pSecDa)

{

uchar i;

uchar ucAddr = 0x80;

v_W1302(0x8e, 0x00); //控制命令,WP=0,写操作

for(i=7; i>0; i--)

{

v_W1302(ucAddr, *pSecDa); // 秒 分 时 日 月 星期 年

pSecDa++;

ucAddr += 2;

}

v_W1302(0x8e, 0x80); //控制命令,WP=1,写保护

}

/********************************************************************

* 名称 : v_Get1302(uchar ucCurtime[])

* 功能 : 读取DS1302当前时间

* 输入 : ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年

* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B

* 返回值 : 无

***********************************************************************/

void v_Get1302(uchar ucCurtime[])

{

uchar i;

uchar ucAddr = 0x81;

for(i=0; i<7; i++)

{

ucCurtime[i] = uc_R1302(ucAddr); //格式为: 秒 分 时 日 月 星期 年

ucAddr += 2;

}

}

/********************************************************************

* 名称 : dectobcd(uchar dec)

* 功能 : DEC码转换为BCD码

* 输入 : dec码

* 输出 : bcd码

***********************************************************************/

uchar dectobcd(uchar dec)

{

uchar bcd;

bcd = 0;

while(dec >= 10)

{

dec -= 10;

bcd++;

}

bcd <<= 4;

bcd |= dec;

return bcd;

}

/********************************************************************

* 名称 : bcdtodec(uchar bcd)

* 功能 : BCD码转换为DEC码

* 输入 : bcd码

* 输出 : dec码

***********************************************************************/

uchar bcdtodec(uchar bcd)

{

uchar data1;

data1 = bcd & 0x0f; //取BCD低4位

bcd = bcd & 0x70; //剔除BCD的最高位和低4位。

data1 += bcd >> 1;

data1 += bcd >> 3; //用位移代替乘法运算

return data1;

}

/********************************************************************

* 名称 : Write_DS1302Init()

* 功能 : 往DS1302中写入数据。最开始显示的数据就是在这里设置的。

* 输入 : 无

* 输出 : 无

***********************************************************************/

void Write_DS1302Init(void)

{

v_W1302(0x8e,0);

v_W1302(0x80,0x50); //写入秒

v_W1302(0x8e,0);

v_W1302(0x82,0x59); //写入分

v_W1302(0x8e,0);

v_W1302(0x84,0x07); //写入小时

v_W1302(0x8e,0);

v_W1302(0x86,0x08); //写入日

v_W1302(0x8e,0);

v_W1302(0x88,0x08); //写入月

v_W1302(0x8e,0);

v_W1302(0x8a,0x05); //写入星期

v_W1302(0x8e,0);

v_W1302(0x8c,0x08); //写入年

}

/********************************************************************

* 名称 : Run_DS1302(void)

* 功能 : 读出DS1302中的数据,并在液晶1602上进行显示

* 输入 : 无

* 输出 : 无

***********************************************************************/

void Run_DS1302(void)

{

uchar sec, min, hour, day, month, year;

while(1)

{

v_W1302(0x8f, 0);

sec = bcdtodec(uc_R1302(0x81)); //读出DS1302中的秒

v_W1302(0x8f, 0);

min = bcdtodec(uc_R1302(0x83)); //读出DS1302中的分

v_W1302(0x8f, 0);

hour = bcdtodec(uc_R1302(0x85)); //读出DS1302中的小时

v_W1302(0x8f, 0);

day = bcdtodec(uc_R1302(0x87)); //读出DS1302中的日

v_W1302(0x8f, 0);

month = bcdtodec(uc_R1302(0x89)); //读出DS1302中的月

v_W1302(0x8f, 0);

year = bcdtodec(uc_R1302(0x8d)); //读出DS1302中的年

L1602_char(2, 6, hour / 10 % 10 + 48);

L1602_char(2, 7, hour % 10 + 48);

L1602_char(2, 8, '-');

L1602_char(2, 9, min / 10 % 10 + 48);

L1602_char(2, 10, min % 10 + 48);

L1602_char(2, 11, '-');

L1602_char(2, 12, sec / 10 % 10 + 48);

L1602_char(2, 13, sec % 10 + 48);

L1602_char(1, 8, year / 10 % 10 + 48);

L1602_char(1, 9, year % 10 + 48);

L1602_char(1, 10, '-');

L1602_char(1, 11, month / 10 % 10 + 48);

L1602_char(1, 12, month % 10 + 48);

L1602_char(1, 13, '-');

L1602_char(1, 14, day / 10 % 10 + 48);

L1602_char(1, 15, day % 10 + 48);

}

}

/********************************************************************

* 名称 : Main(void)

* 功能 : 主函数

* 输入 : 无

* 输出 : 无

***********************************************************************/

void Main(void)

{

L1602_init();

L1602_string(1,1,"DAYS 20");

L1602_string(2,1,"TIME");

Write_DS1302Init();

Run_DS1302();

}

相关推荐
scan117 分钟前
单片机串口接收状态机STM32
stm32·单片机·串口·51·串口接收
Qingniu011 小时前
【青牛科技】应用方案 | RTC实时时钟芯片D8563和D1302
科技·单片机·嵌入式硬件·实时音视频·安防·工控·储能
深圳市青牛科技实业有限公司2 小时前
【青牛科技】应用方案|D2587A高压大电流DC-DC
人工智能·科技·单片机·嵌入式硬件·机器人·安防监控
Mr.谢尔比3 小时前
电赛入门之软件stm32keil+cubemx
stm32·单片机·嵌入式硬件·mcu·信息与通信·信号处理
LightningJie3 小时前
STM32中ARR(自动重装寄存器)为什么要减1
stm32·单片机·嵌入式硬件
西瓜籽@4 小时前
STM32——毕设基于单片机的多功能节能窗控制系统
stm32·单片机·课程设计
远翔调光芯片^138287988726 小时前
远翔升压恒流芯片FP7209X与FP7209M什么区别?做以下应用市场摄影补光灯、便携灯、智能家居(调光)市场、太阳能、车灯、洗墙灯、舞台灯必看!
科技·单片机·智能家居·能源
极客小张7 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩
m0_7393128710 小时前
【STM32】项目实战——OV7725/OV2604摄像头颜色识别检测(开源)
stm32·单片机·嵌入式硬件
嵌入式小章10 小时前
基于STM32的实时时钟(RTC)教学
stm32·嵌入式硬件·实时音视频