STC89C52读写DS1302,采用lcd1602实时显示时间
时间: 2023-11-05 16:29:57 浏览: 115
以下是使用STC89C52读写DS1302并通过LCD1602显示时间的示例程序:
```c
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
// 定义DS1302的控制引脚
sbit SCK=P3^6;
sbit SDA=P3^5;
sbit RST=P3^4;
// 定义LCD1602的控制引脚
sbit RS=P1^0;
sbit RW=P1^1;
sbit EN=P1^2;
// 定义LCD1602的数据引脚
sbit LCD_D4=P2^4;
sbit LCD_D5=P2^5;
sbit LCD_D6=P2^6;
sbit LCD_D7=P2^7;
// 定义全局变量
uchar second,minute,hour,day,month,week,year;
// 函数声明
void Delay1ms(uint);
void InitDS1302(void);
uchar ReadDS1302(uchar);
void WriteDS1302(uchar,uchar);
void ReadTime(void);
void WriteTime(void);
void InitLCD1602(void);
void WriteCommand(uchar);
void WriteData(uchar);
void WriteString(uchar *);
void main()
{
InitLCD1602(); // 初始化LCD1602
InitDS1302(); // 初始化DS1302
while(1)
{
ReadTime(); // 读取时间
WriteTime(); // 在LCD1602上显示时间
Delay1ms(10); // 等待10ms
}
}
// 延时1ms
void Delay1ms(uint time)
{
uint i,j;
for(i=0;i<time;i++)
{
for(j=0;j<114;j++);
}
}
// 初始化DS1302
void InitDS1302(void)
{
RST=0; // 将RST引脚拉低
Delay1ms(1); // 等待1ms
RST=1; // 将RST引脚拉高
WriteDS1302(0x8e,0x00); // 允许写入DS1302寄存器
WriteDS1302(0x80,0x00); // 关闭写保护
}
// 读取DS1302寄存器
uchar ReadDS1302(uchar addr)
{
uchar i,temp=0;
SCK=0;
SDA=0;
SCK=1;
SDA=1;
_nop_();
_nop_();
SCK=0;
_nop_();
_nop_();
SDA=0;
SCK=0;
_nop_();
_nop_();
SCK=1;
_nop_();
_nop_();
SCK=0;
_nop_();
_nop_();
for(i=0;i<8;i++)
{
SDA=addr&0x01;
addr>>=1;
SCK=1;
_nop_();
_nop_();
SCK=0;
_nop_();
_nop_();
}
for(i=0;i<8;i++)
{
temp>>=1;
SCK=1;
_nop_();
_nop_();
if(SDA==1)
{
temp|=0x80;
}
SCK=0;
_nop_();
_nop_();
}
SDA=1;
return temp;
}
// 写入DS1302寄存器
void WriteDS1302(uchar addr,uchar dat)
{
uchar i;
SCK=0;
SDA=0;
SCK=1;
SDA=1;
_nop_();
_nop_();
SCK=0;
_nop_();
_nop_();
SDA=0;
SCK=0;
_nop_();
_nop_();
for(i=0;i<8;i++)
{
SDA=addr&0x01;
addr>>=1;
SCK=1;
_nop_();
_nop_();
SCK=0;
_nop_();
_nop_();
}
for(i=0;i<8;i++)
{
SDA=dat&0x01;
dat>>=1;
SCK=1;
_nop_();
_nop_();
SCK=0;
_nop_();
_nop_();
}
SDA=1;
}
// 读取时间
void ReadTime(void)
{
uchar i;
second=ReadDS1302(0x81); // 读取秒
minute=ReadDS1302(0x83); // 读取分
hour=ReadDS1302(0x85); // 读取时
day=ReadDS1302(0x87); // 读取日
month=ReadDS1302(0x89); // 读取月
week=ReadDS1302(0x8b); // 读取星期
year=ReadDS1302(0x8d); // 读取年
}
// 写入时间
void WriteTime(void)
{
uchar i;
uchar temp;
temp=hour&0x0f;
WriteCommand(0x80+0x04);
WriteData(temp+'0');
temp=hour>>4;
WriteCommand(0x80+0x03);
WriteData(temp+'0');
WriteCommand(0x80+0x05);
WriteData(':');
temp=minute&0x0f;
WriteCommand(0x80+0x07);
WriteData(temp+'0');
temp=minute>>4;
WriteCommand(0x80+0x06);
WriteData(temp+'0');
WriteCommand(0x80+0x08);
WriteData(':');
temp=second&0x0f;
WriteCommand(0x80+0x0a);
WriteData(temp+'0');
temp=second>>4;
WriteCommand(0x80+0x09);
WriteData(temp+'0');
}
// 初始化LCD1602
void InitLCD1602(void)
{
EN=0;
RW=0;
RS=0;
LCD_D4=1;
LCD_D5=1;
LCD_D6=1;
LCD_D7=1;
Delay1ms(15);
WriteCommand(0x02);
Delay1ms(5);
WriteCommand(0x28);
Delay1ms(5);
WriteCommand(0x0c);
Delay1ms(5);
WriteCommand(0x06);
Delay1ms(5);
}
// 发送LCD1602命令
void WriteCommand(uchar command)
{
RS=0;
RW=0;
EN=1;
LCD_D7=(command>>7)&0x01;
LCD_D6=(command>>6)&0x01;
LCD_D5=(command>>5)&0x01;
LCD_D4=(command>>4)&0x01;
EN=0;
Delay1ms(1);
EN=1;
LCD_D7=(command>>3)&0x01;
LCD_D6=(command>>2)&0x01;
LCD_D5=(command>>1)&0x01;
LCD_D4=(command>>0)&0x01;
EN=0;
Delay1ms(1);
}
// 发送LCD1602数据
void WriteData(uchar data)
{
RS=1;
RW=0;
EN=1;
LCD_D7=(data>>7)&0x01;
LCD_D6=(data>>6)&0x01;
LCD_D5=(data>>5)&0x01;
LCD_D4=(data>>4)&0x01;
EN=0;
Delay1ms(1);
EN=1;
LCD_D7=(data>>3)&0x01;
LCD_D6=(data>>2)&0x01;
LCD_D5=(data>>1)&0x01;
LCD_D4=(data>>0)&0x01;
EN=0;
Delay1ms(1);
}
// 在LCD1602上写入字符串
void WriteString(uchar *string)
{
while(*string)
{
WriteData(*string++);
}
}
```
此示例程序使用STC89C52单片机通过DS1302时钟芯片读取时间,并使用LCD1602显示时间。该程序使用了DS1302的RTC(实时时钟)功能,并且允许写入DS1302寄存器以设置时间。在主函数中,它使用`ReadTime()`函数读取时间,并使用`WriteTime()`函数将时间信息显示在LCD1602上。`InitDS1302()`函数用于初始化DS1302寄存器,并启用写入寄存器的权限。`InitLCD1602()`函数用于初始化LCD1602,以便能够在其上显示时间。
阅读全文