个人学习历程

**

51单片机DS1302实时时钟Proteus仿真显示

学习用51单片机显示实时时间。
用DS1302实时时钟芯片,用来练习很不错,我所编写的程序时间误差较大。刚开始和网络是时间存在微小差距,显示的时间越长,误差越来越大。
这里用LCD1602显示(显示样式参照了网上的历程)。下面有仿真图
如有大神路过,欢迎指导,指出不足。

DS1302.c

#include <reg52.h>
#include "DS1302.h"
#include <intrins.h>
sbit RST = P2^5;
sbit SCLK = P2^6;
sbit IO = P2^7;

void RTC_Initial()
{
	RST = 0;
	SCLK = 0;
}
/*
	写数据
*/
void RTC_Write_Data(uchar Addr,uchar dat)
{
	uchar i;
	RTC_Initial();
	RST = 1;
	for(i=0;i<8;i++)
	{
		SCLK = 0;
		if(Addr&0x01) IO = 1;
		else IO = 0;
		SCLK = 1;
		Addr>>=1;
	}
	for(i=0;i<8;i++)
	{
		SCLK = 0;
		if(dat&0x01) IO = 1;
		else IO = 0;
		SCLK = 1;
		dat>>=1;
	}
}
/*
	读数据
*/
uchar RTC_Read_Data(uchar Addr)
{
	uchar i;
	uchar dat;
	RTC_Initial();
	RST = 1;
	for(i=0;i<8;i++)
	{
		SCLK = 0;
		if(Addr&0x01) IO = 1;
		else IO = 0;
		SCLK = 1;
		Addr>>=1;
	}
	//SCLK = 1;
	IO = 1;					
/*
		上面读取了地址的有效信息
		经DS1302 IO发送数据,低-高
*/
	for(i=0;i<8;i++)
	{
		dat >>= 1;		//清0
		SCLK = 1;
		_nop_();
		SCLK = 0;
		if(IO) dat |= 0x80;//DS1302向C51发送数据
	}
	return dat;
}

LCD1602.c

#include <reg52.h>
#include <intrins.h>
#include "LCD1602.h"
#define uint unsigned int 
	#define uchar unsigned char
	
	sbit RS = P2^0;
	sbit RW = P2^1;
	sbit EN = P2^2;

void LCD_delayMs(uchar ms)
{
	int i=0;
	while(ms--)
		for(i=0;i<160;i++);
}	
void LCD1602_Initial()
{
	LCD_delayMs(80);
	LCD1602_WriteCMD(0x38);  //开显示
	LCD_delayMs(20);
	LCD1602_WriteCMD(0x38);
	LCD_delayMs(2);

	LCD1602_WriteCMD(0x01);  //清屏
	LCD_delayMs(10);
	LCD1602_WriteCMD(0x0c);  //开显示,不显示光标
	LCD1602_WriteCMD(0x06);  //写一个指针+1
}
void check_busy()			//忙检测
{
	uchar dt;
	do
	{
		dt=0xff;
		EN=0;		  
		RS=0;
		RW=1;
		EN=1;		 
		dt=P0;
 
	}while(dt&0x80);
		EN=0;
}
void LCD1602_WriteCMD(uchar Addr)
{
	check_busy();
	//LCD_delayMs(10);
	RS = 0;
	RW = 0;
	EN = 0;
	P0 = Addr;
	EN = 1;
	_nop_();
	EN = 0;
	//RS = 1;
}

void LCD1602_WriteDATA(uchar Data)
{
	LCD_delayMs(1);
	RS = 1;
	RW = 0;
	EN = 0;
	P0 = Data;
	EN = 1;
	_nop_();
	EN = 0;
	//RS = 0;
}
/********************************************
				0 1 2 3 4 ...    15
			----------------------------->x
		0 |																			
		1 |
		y V
********************************************/
void LCD1602_Display(uchar x,uchar y,uchar dat)
{
	uchar addr;
	addr = y?(0xC0+x):(0x80+x);
	LCD1602_WriteCMD(addr);
	LCD1602_WriteDATA(dat);
}
/*---------------显示字符串----------*/
void Show_String(char *temp)
{
	while((*temp)!='\0')
	{
		LCD1602_WriteDATA(*temp);
		temp++;
	}
}

Main文件

#include <reg52.h>
#include "LCD1602.h"
#include "DS1302.h"
#define uint unsigned int 
	#define uchar unsigned char
		#define u8 unsigned char
void RTC_setTime(u8 sec,u8 min,u8 hrs,u8 date,u8 month,u8 year);
void RTC_readTime();
void Save_read_Time();
void Display_Date();
		
	char code line1[16]={"Date:20__-__-__"};
	char code line2[16]={"Time: __:__:__"};
	uchar Div[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
		
struct Time {
	uchar secData;
	uchar minData;
	uchar hrsData;
	uchar dateData;
	uchar monthData;
	uchar yearData;
	//uchar dayData;
}Clock;
void main()
{
	LCD1602_Initial();
	RTC_Initial();
	RTC_setTime(0x55,0x59,0x23,0x30,0x06,0x18);
	LCD1602_WriteCMD(0x80);
	Show_String(line1);
	LCD1602_WriteCMD(0xc0);
	Show_String(line2);
	while(1)
	{
		RTC_readTime();
		Save_read_Time();
		Display_Date();
	}
	
}

/*向RTC寄存器写入数据
设置时间如:RTC_setTime(0x55,0x59,0x23,0x30,0x06,0x18,0x07)*/
void RTC_setTime(u8 sec,u8 min,u8 hrs,u8 date,u8 month,u8 year)//,u8 day)
{
	RTC_Write_Data(0x8e,0x00);
	RTC_Write_Data(RTC_Write_secAddr, sec);
	RTC_Write_Data(RTC_Write_minAddr, min);
	RTC_Write_Data(RTC_Write_hrsAddr, hrs);
	RTC_Write_Data(RTC_Write_dateAddr, date);
	RTC_Write_Data(RTC_Write_monthAddr, month);
	RTC_Write_Data(RTC_Write_yearAddr, year);
	//RTC_Write_Data(RTC_Write_dayAddr, day);
	RTC_Write_Data(0x8e,0x80);
}
/*读取RTC内部寄存器数据*/
void RTC_readTime()
{
	Clock.secData = RTC_Read_Data(RTC_Read_secAddr);
	Clock.minData = RTC_Read_Data(RTC_Read_minAddr);
	Clock.hrsData = RTC_Read_Data(RTC_Read_hrsAddr);
	Clock.dateData = RTC_Read_Data(RTC_Read_dateAddr);
	Clock.monthData = RTC_Read_Data(RTC_Read_monthAddr);
	Clock.yearData = RTC_Read_Data(RTC_Read_yearAddr);
	//Clock.dayData = RTC_Read_Data(RTC_Read_dayAddr);
}
void Save_read_Time()
{
	Div[1] = (Clock.secData&0x70)>>4;
	Div[0] = Clock.secData&0x0f;
	Div[3] = (Clock.minData&0x70)>>4;
	Div[2] = Clock.minData&0x0f;
	Div[5] = (Clock.hrsData&0x30)>>4;
	Div[4] = Clock.hrsData&0x0f;
	/*-----------------------------*/
	Div[7] = (Clock.dateData&0x30)>>4;
	Div[6] = Clock.dateData&0x0f;
	Div[9] = (Clock.monthData&0x10)>>4;
	Div[8] = Clock.monthData&0x0f;
	Div[11] = (Clock.yearData&0xf0)>>4;
	Div[10] = Clock.yearData&0x0f;
	
//	Div[13] = (Clock.dayData&0x00)>>4;
//	Div[12] = Clock.dayData&0x07;

}
void Display_Date()
{
	LCD1602_Display(7,0,Div[11]+'0');				//year
	LCD1602_Display(8,0,Div[10]+'0');
	LCD1602_Display(10,0,Div[9]+'0');				//month
	LCD1602_Display(11,0,Div[8]+'0');
	LCD1602_Display(13,0,Div[7]+'0');				//date
	LCD1602_Display(14,0,Div[6]+'0');
	/*----------------------------*/
	LCD1602_Display(6,1,Div[5]+'0');				//hrs
	LCD1602_Display(7,1,Div[4]+'0');
	LCD1602_Display(9,1,Div[3]+'0');				//minute
	LCD1602_Display(10,1,Div[2]+'0');
	LCD1602_Display(12,1,Div[1]+'0');				//second
	LCD1602_Display(13,1,Div[0]+'0');
}

仿真情况,显示的是参照了网上样例

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值