文档库 最新最全的文档下载
当前位置:文档库 › 1602液晶显示DS1302实时时间程序

1602液晶显示DS1302实时时间程序

/////////////////////////
///////////main.c///////
////////////////////////
#include
#include
#include
#include "ds1302.h"
#include "lcd.h"

#define Key_Port P1^0 //定义按键端口
#define Duan_Port P0 //定义数码管数据端口
#define Wei_Port P2 //定义数码管位选端口


bit Read_TimeFlag;//定义读时间标志
bit SetFlag; //更新时间标志位
unsigned char time_buf2[16];


void Delay_2Us (uchar t); // 微秒级延时函数
void Delay_Ms (uchar t); // 毫秒级延时函数

void Init_Timer0 (); // 定时器初始化
void UART_Init(void); //串口初始化
/*------------------------------------------------
主函数
------------------------------------------------*/

void main()
{
uchar i;
LCD_Init();
Delay_Ms(20);
LCD_Clear();
Init_Timer0();
Ds1302_Init();
UART_Init();
Ds1302_Read_Time() ;
if((Time_Data[2]+Time_Data[7])==0)
Ds1302_Write_Time();
while(1) //主循环
{

if(SetFlag) //如果接收到串口信息则更新时钟
{
for(i=0;i<8;i++)
{
Time_Data[i]=time_buf2[2*i]*10+time_buf2[2*i+1];
}//数据整合,如2个数 1和5整合成15
Ds1302_Write_Time();
SetFlag=0; //时钟信息更新后标志位清零
}



if(Read_TimeFlag==1)
{
Read_TimeFlag = 0;
Ds1302_Read_Time();


LCD_Write_Com (0x80+0x40); //在第二行显示
LCD_Write_Data(0x8d);
LCD_Write_Data(0x8d);
LCD_Write_Data(0x8d);
LCD_Write_Data('0'+Time_Data[4]/10); //时
LCD_Write_Data('0'+Time_Data[4]%10);
LCD_Write_Data(':');
LCD_Write_Data('0'+Time_Data[5]/10); //分
LCD_Write_Data('0'+Time_Data[5]%10);
LCD_Write_Data(':');
LCD_Write_Data('0'+Time_Data[6]/10); //秒
LCD_Write_Data('0'+Time_Data[6]%10);


LCD_Write_Com (0x80); //在第一行显示
LCD_Write_Data(0x8d);
LCD_Write_Data(0x8d);//添加空格
LCD_Write_Data('0'+Time_Data[0]/10);
LCD_Write_Data('0'+Time_Data[0]%10); //显示年的前两位。。即 2 0
LCD_Write_Data('0'+Time_Data[1]/10);
LCD_Write_Data('0'+Time_Data[1]%10); //以上四行显示完整年份
LCD_Write_Data('-');
LCD_Write_Data('0'+Time_Data[2]/10); //月
LCD_Write_Data('0'+Time_Data[2]%10);
LCD_Write_Data('-');
LCD_Write_Data('0'+Time_Data[3]/10); //日
LCD_Write_Data('0'+Time_Data[3]%10);
LCD_Write_Data(0x8d);
LCD_Write_Data(0x8d);
LCD_Write_Data('0'+Time_Data[7]%10); //星期
}
}
}
/*------------------------------------------------
延时函数
------------------------------------------------*/
void Delay_2Us(uchar t)
{
while(t--);
}
void Delay_Ms(uchar t)
{
while (t--)
{
Delay_2Us(245);
Delay_2Us(245);
}
}



/*------------------------------------------------
初始化定时器函数
----------------

-------------------------------- */

void Init_Timer0 ()
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
// TH0 = (65536-2000)/256; //给定初值
// TL0 = (65536-2000)%256;
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 1; //定时器开关打开
}

/*------------------------------------------------
定时器中断函数
------------------------------------------------ */
void Timer0_int () interrupt 1
{
static uint num; //静态变量
TH0 = (65536-2000)/256; //给定初值
TL0 = (65536-2000)%256;

num++;
if (num==10) //延时100MS
{
num = 0;
Read_TimeFlag=1; //读标志位1
}
}


/*------------------------------------------------
串口通讯初始化
------------------------------------------------*/
void UART_Init(void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 1; //打开串口中断
}

/*------------------------------------------------
串口中断程序
------------------------------------------------*/
void UART_SER (void) interrupt 4 //串行中断服务程序
{
unsigned char Temp; //定义临时变量
unsigned char i;
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
Temp=SBUF; //读入缓冲区的值
time_buf2[i]=Temp&0x0F;
i++;
if(i==16) //连续接收16个字符信息
{
i=0;
SetFlag=1; //接收完成标志位置1
}
SBUF=Temp; //把接收到的值再发回电脑端
}
if(TI) //如果是发送标志位,清零
TI=0;
}



//////////////////////////////
///////////////lcd.c//////////
//////////////////////////////
#include
#include
#include"lcd.h"
#include "ds1302.h"

// #define uint unsigned int
// #define uchar unsigned char
//
// sbit RW = P2^5;
// sbit RS = P2^6;
// sbit EN = P2^7;
//
// #define RS_L RS=0
// #define RS_H RS=1
//
// #define RW_L RW=0
// #define RW_H RW=1
//
// #define EN_L EN=0
// #define EN_H EN=1
//
// #define GPIO_Port P0

void Delay2Us(uchar t) //微妙延时 大致延时长度如下 T=tx2+5 uS
{
while(--t);
}

void DelayMs(uint t) //毫秒延时 延时t毫秒
{
while(t--)
{
Delay2Us(245);
Delay2Us(245); //大致延时1毫秒
}
}


/*------------------------------------------
写入命

令函数 //写命令:RS=0,RW=0,EN=1
-------------------------------------------*/
void LCD_Write_Com(uchar com)
{
DelayMs(5);
RS_L;
RW_L;
EN_H;
GPIO_Port = com;
_nop_();
EN_L;
}

/*------------------------------------------
写入数据函数 //写数据:RS=1,RW=0,EN=1
-------------------------------------------*/
void LCD_Write_Data(uchar dat)
{
DelayMs(5);
RS_H;
RW_L;
EN_H;
GPIO_Port = dat;
_nop_();
EN_L;
}
/*------------------------------------------------
清屏函数
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01); //固定格式
DelayMs(5);
}
/*------------------------------------------------
写入字符函数
------------------------------------------------
void LCD_Write_Char(uchar x,uchar y,uchar dat)
{
if(y == 0)
{
LCD_Write_Com(0x80 + x); //从第一行显示
}
else
{
LCD_Write_Com(0xc0 + x); //否则从第二行显示
}
LCD_Write_Data( dat );
} */
/*------------------------------------------------
写入字符串函数
------------------------------------------------
void LCD_Write_String(uchar x, uchar y,uchar *s)
{
if(y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xc0 + x);
}
while ( *s )
{
LCD_Write_Data(*s);
s++;
}
} */
/*------------------------------------------------
初始化函数
--------------------------------------------------*/
void LCD_Init()
{
LCD_Write_Com(0x38); //显示模式设置
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*显示关闭*/
LCD_Write_Com(0x01); /*显示清屏*/
LCD_Write_Com(0x06); /*显示光标移动设置*/
DelayMs(5);
LCD_Write_Com(0x0C); /*显示开及光标设置*/
}



/////////////////////////////
//////////////lcd.h////////
////////////////////////
#ifndef __LCD_H_
#define __LCD_H_
///**********************************
//当使用的是4位数据传输的时候定义,
//使用8位取消这个定义
//**********************************/
//#define void LCD_Write_Data(uchar dat)

/**********************************
包含头文件
**********************************/
#include

//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif

/**********************************
PIN口定义
**********************************/
#define GPIO_Port P0

sbit RW=P2^5; //定义读/写选择端
sbit RS=P2^6; //定义数据/命令选择发送端
sbit EN=P2^7; //定义使能信号端

#define RS_L RS=0
#define RS_H RS=1

//写命令:RS=0,RW=0,EN=1
#define RW_L RW=0 //写数据:RS=1,RW=0,EN=1
#define RW_H RW=1

#define EN_L EN=0
#define EN_H EN=1

/**********************************
函数声明
**********************************/
//
///*在51单片机12MHZ时钟下的延时函数*/
//void Delay2Us(uchar t);
//void DelayMs (uint t);

/*LCD1602写入8位命令子函数*/
void LCD_Write_Com(uchar com);

/*LCD1602写入8位数据子函数*/
void LCD_Write_Data(uchar dat) ;

/*LCD1602写入字符子函数*/
void LCD_Write_Char(uchar x,uchar y,uchar dat);

/*LCD1602写入字符串子函数*/
void LCD_Write_String(uchar x, uchar y,uchar *s);

/*LCD1602初始化子程序*/
void LCD_Init();

/*LCD1602清屏子程序*/
void LCD_Clear(void);

#endif




///////////////////////////////
/////////////ds1302.c/////////
////////////////////////////


#include"ds1302.h"

uchar Time_Buf[8] ;
uchar Time_Data[8] ={20,10,6,5,12,55,00,6};//空年月日时分秒周
/*------------------------------------------------
向DS1302写入一字节数据
------------------------------------------------*/
void Ds1302_Write_Byte(uchar addr,uchar dat)
{
uchar i;
RST = 0;
_nop_();
SCLK = 0;//先将SCLK置零
_nop_();
RST = 1; //然后将RST置一
_nop_();
//写入目标地址;addr
addr = addr & 0xfe; //最低位置0
for(i=0;i<8;i++)
{

IO = addr & 0x01 ;//数据从低位开始传送
addr >>= 1;
SCLK = 1; //数据在上升沿时,DS1302读取数据
//_nop_() ;
SCLK = 0;
// _nop_() ;
}

//写入8位数据;dat
for(i=0;i<8;i++)
{
IO = dat & 0x01 ;//数据从低位开始传送
dat >>= 1;
SCLK = 1; //数据在上升沿时,DS1302读取数据
//_nop_() ;
SCLK = 0;
//_nop_() ;
}
RST = 0; // 停止DS1302数据传送
_nop_() ;
}

/*------------------------------------------------
从DS1302读出一字节数据
------------------------------------------------*/

uchar Ds1302_Read_Byte(uchar addr)
{
uchar i;
uchar Temp,dat;
RST = 0;
_nop_();
SCLK = 0;//先将SCLK置零
_nop_();
RST = 1; //然后将RST置一
_nop_();
//写入目标地址;addr
addr = addr | 0x01; //最低位置高
for(i=0;i<8;i++) //开始传送八位地址命令
{
IO = addr & 0x01;//数据从低位开始传送
addr >>= 1;
SCLK = 1; //数据在上升沿时。。DS1302读取数据
// _nop_() ;
SCLK = 0; //DS1302在下降沿时,放置数据
// _nop_();
}
_nop_();
//输出数据;dat
for(i=0; i<8; i++)
{
Temp = IO; //从最低位开始接收
dat = (dat >> 1) | (Temp<<7);
SCLK = 1;
// _nop_();
SCLK = 0; //DS1302在下降沿时,放置数据
// _nop_();
}
RST = 0; // 停止DS1302数据传送
_nop_(); //以下为DS1302复位的稳定时间,必须的。
SCLK = 1;
_nop_();
IO = 0;
_nop_();
I

O = 1;
_nop_();
return dat;
}


/*------------------------------------------------
向DS1302写入时钟数据
------------------------------------------------ */

void Ds1302_Write_Time()
{
uchar i,tmp;
for (i=0 ;i<8 ;i++)
{
tmp = Time_Data[i]/10;
Time_Buf[i] = Time_Data[i]%10;
Time_Buf[i] = Time_Buf[i] + tmp*16;
}
//BCD码处理,,,将十六进制数据转化为十进制

Ds1302_Write_Byte( 0x8e , 0x00 ) ;//关闭写保护,可以可以写入数据
Ds1302_Write_Byte( 0x80 , 0x80 ); //暂停
Ds1302_Write_Byte( 0x8a , Time_Buf[7] ) ; // 星期
Ds1302_Write_Byte( 0x80 , Time_Buf[6] ) ; // 秒
Ds1302_Write_Byte( 0x82 , Time_Buf[5] ) ; // 分
Ds1302_Write_Byte( 0x84 , Time_Buf[4] ) ; // 时
Ds1302_Write_Byte( 0x8a , Time_Buf[7] ) ; // 星期
Ds1302_Write_Byte( 0x86 , Time_Buf[3] ) ; // 日
Ds1302_Write_Byte( 0x88 , Time_Buf[2] ) ; // 月
Ds1302_Write_Byte( 0x8c , Time_Buf[1] ) ; // 年
Ds1302_Write_Byte( 0x8e , 0x80 ) ; //打开写保护,不能写入数据

}

/*------------------------------------------------
读出DS1302时钟数据
------------------------------------------------*/

void Ds1302_Read_Time( )
{
uchar i,tmp;

Time_Buf[1] = Ds1302_Read_Byte(0x8d) ; // 年
Time_Buf[2] = Ds1302_Read_Byte(0x89) ; // 月
Time_Buf[3] = Ds1302_Read_Byte(0x87) ; // 日
Time_Buf[4] = Ds1302_Read_Byte(0x85) ; // 时
Time_Buf[5] = Ds1302_Read_Byte(0x83) ; // 分
Time_Buf[6] = (Ds1302_Read_Byte(0x81))&0x7f ; // 秒
Time_Buf[7] = Ds1302_Read_Byte(0x8b) ; // 周


for (i=0 ;i<8 ;i++)
{
tmp = Time_Buf[i]/16;
Time_Data[i] = Time_Buf[i]%16;
Time_Data[i] = Time_Data[i] + tmp*10;
}
//BCD码处理,,,将十进制数据转化为十六进制
}
/*------------------------------------------------
初始化DS1302
------------------------------------------------*/
void Ds1302_Init(void)
{

RST=0; //RST脚置低
SCLK=0; //SCK脚置低
Ds1302_Write_Byte(0x80,0x00);
}



///////////////////////////////////
///////////ds1302.h//////////////
//////////////////////////////////
#ifndef __DS1302_H__
#define __DS1302_H__

#include
#include


//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif

//---定义ds1302使用的IO口---//
sbit IO =P3^4;
sbit RST=P3^5;
sbit SCLK=P3^6;



extern uchar Time_Data[8];//空年月日时分秒周
extern uchar Time_Buf[8] ;//空年月日时分秒周
/*------------------------------------------------
向DS1302写入一字节数据
------------------------------------------------*/
void Ds1302_Write_Byte(uchar addr, uchar dat);
/*------------------------------------------------
从DS1302读出一字节数据
--------------------

----------------------------*/
unsigned char Ds1302_Read_Byte(uchar addr) ;
/*------------------------------------------------
向DS1302写入时钟数据
------------------------------------------------*/
void Ds1302_Write_Time(void) ;
/*------------------------------------------------
从DS1302读出时钟数据
------------------------------------------------*/
void Ds1302_Read_Time(void) ;
/*------------------------------------------------
DS1302初始化
------------------------------------------------*/
void Ds1302_Init(void);

#endif





相关文档
相关文档 最新文档