基于DS1302写的12864LCD时钟程序(word文档良心出品)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

以下是我写的12864LCD并行口时钟显示程序,时钟用按键可调
/***************12864.h头文件******************************/
#ifndef _12864_h
#define _12864_h
/*****包含头文件**************/
#include<reg51.h>
#include"string.h"
#include"DS1302.h"
/********定义I/0口**********/
#define LCD12864_DATA P0
sbit LCD12864_E = P2^7;
sbit LCD12864_RW = P2^5;
sbit LCD12864_RS = P2^6;
sbit LCD12864_RET= P2^0;
sbit LCD12864_PSB =P2^2;
/******声明全局函数*********/
void Delay1ms(unsigned int); //声明延时函数
void BusyChk_12864(void); //声明忙检测函数
void WrCom(unsigned char); //声明写入命令函数
//unsigned char ReDat(void); //声明读数据函数
void WrDat(unsigned char); //声明写数据函数
void LcdInit(void); //12864初始化函数
void SetAddress(unsigned char ,unsigned char); //设置地址转换
void DisplayString(unsigned char ,unsigned char,unsigned char *p);//行显示字符
void DisplayTime();
void DisplayDay();
void DisplayWeek();
#endif
/*****************************12864.c***********************************/
#include"12864.h"
/****************************************************************************** *
* 函数名: Delay1ms
* 函数功能: 延时函数,延时1ms
* 输入: c
* 输出 e : 无
* 说名: 该函数是在12MHZ晶振下,12分频单片机的延时。

******************************************************************************* /
void Delay1ms(unsigned int i) //误差0us
{
unsigned char a;
for (i; i>0; i--)
{
for (a=199;a>0;a--)
;
}
}
/**************************************************************************** 函数名字:void BusyChk()
函数功能:12864LCD忙检测
* 输入: 无
* 输出: 无
******************************************************************************* /
void BusyChk(void)
{
unsigned int timeout=0;
LCD12864_E=0; //E=0 使能关闭
LCD12864_RS=0; //0 指令;1 数据
LCD12864_RW=1; //1 读数据;0写数据
Delay1ms(50); //延时100ms
LCD12864_E=1; //1 开使能,读数据
while(((LCD12864_DATA & 0x80) && ++timeout));//判断1表示内部在工作;0表示正常
LCD12864_E=0; //E=0 使能关闭
}
/**************************************************************************** 函数名字:void WrDat(usnigned char data)
函数功能:写入数据
* 输入: data
* 输出: 无
******************************************************************************* /
void WrDat(unsigned char bTemp)
{
BusyChk(); //忙检测
LCD12864_E=0; //E=0 使能关闭
LCD12864_RS=1; //0 指令;1 数据
LCD12864_RW=0; //1 读数据;0写数据
LCD12864_E=1; //E=1 使能打开
LCD12864_DATA=bTemp;//写入数据
Delay1ms(10); //延时100ms
LCD12864_E=0; //E=0 使能关闭
}
/**************************************************************************** 函数名字:void WrCom(usnigned char com)
函数功能:写入命令
* 输入: com
* 输出: 无
******************************************************************************* /
void WrCom(unsigned char com)
{
BusyChk();
LCD12864_E=0; //E=0 使能关闭
LCD12864_RS=0; //0 指令;1 数据
LCD12864_RW=0; //1 读数据;0写数据
LCD12864_E=1; //E=0 使能打开
LCD12864_DATA=com;//写入数据
Delay1ms(10); //延时100ms
LCD12864_E=0; //E=0 使能关闭
}
/**************************************************************************** 函数名字:unsigned char ReData(void)
函数功能:读数据
* 输入: 无
* 输出: data
******************************************************************************* /
//unsigned char ReData(void)
//{
// unsigned char bTempt;
// BusyChk();
// LCD12864_DATA=0xFF;
// LCD12864_E=0; //E=0 使能关闭
// LCD12864_RS=1; //0 指令;1 数据
// LCD12864_RW=1; //1 读数据;0写数据
// LCD12864_E=1; //E=0 使能打开
// bTempt=LCD12864_DA TA;//读出数据
// Delay1ms(100); //延时100ms
// LCD12864_E=0; //E=0 使能关闭
// return bTempt;
//}
/**************************************************************************** 函数名字:void LcdInit(void)
函数功能:初始化
* 输入: 无
* 输出: 无
******************************************************************************* /
void LcdInit()
{
LCD12864_RS=0; //0 指令;1 数据
LCD12864_RW=0; //1 读数据;0写数据
LCD12864_E=1; //E=1 使能打开
LCD12864_PSB=1;//1为并行模式,0为串行模式
LCD12864_RET=1;
Delay1ms(50);
LCD12864_RET=0;//低电平复位
Delay1ms(300);
LCD12864_RET=1;//恢复高电平
WrCom(0x30); //基本指令用0x30,扩展指令用0x34
Delay1ms(20);
WrCom(0x30);
WrCom(0x0C); //显示开,光标关
// WrCom(0x14); //光标位置右移一个位置
WrCom(0x01); //清屏
WrCom(0x06); //进入模式指针加1,屏幕不移动
}
/**************************************************************************** 函数名字:void SetAddress(unsigned char x,unsigned char y)
函数功能:初始化
* 输入: 行、数据
* 输出: 无
******************************************************************************* /
void SetAddress(unsigned char x,unsigned char y)
{
unsigned char bAddress;
switch(y)
{
case 1: bAddress=0x80+x;break;
case 2: bAddress=0x90+x;break;
case 3: bAddress=0x88+x;break;
case 4: bAddress=0x98+x;break;
default: break;
}
WrCom(bAddress);
}
/**************************************************************************** 函数名字:void DisplayString(unsigned char x,unsigned char y, unsigned)
函数功能:初始化
* 输入: 行、数据
* 输出: 无
******************************************************************************* /
void DisplayString(unsigned char x,unsigned char y,unsigned char *add)
{
unsigned char i;
i=strlen(add);
SetAddress(x,y);
while(i--)
{
WrDat(*(add++));
}
}
/**************************************************************************** 函数名字:void DisplayTime()
函数功能:显示时间
* 输入: 行、数据
* 输出: 无
******************************************************************************* /
void DisplayTime()
{
WrCom(0x88);
WrDat('0'+(TIME[2]/10));
WrDat('0'+(TIME[2]%10));
DisplayString(1,3,":");
WrDat('0'+(TIME[1]/10));
WrDat('0'+(TIME[1]%10));
WrDat(':');
WrDat('0'+(TIME[0]/10));
WrDat('0'+(TIME[0]%10));
}
/**************************************************************************** 函数名字:void DisplayDay()
函数功能:显示时间
* 输入: 行、数据
* 输出: 无
******************************************************************************* /
void DisplayDay()
{
WrCom(0x80);
WrDat('0'+2);
WrDat('0'+0);
WrDat('0'+(TIME[6]/10));
WrDat('0'+(TIME[6]%10));
DisplayString(2,1,"年");
WrDat('0'+(TIME[4]/10));
WrDat('0'+(TIME[4]%10));
DisplayString(4,1,"月");
WrDat('0'+(TIME[3]/10));
WrDat('0'+(TIME[3]%10));
DisplayString(6,1,"日");
}
/**************************************************************************** 函数名字:void DisplayWeek()
函数功能:显示时间
* 输入: 行、数据
* 输出: 无
******************************************************************************* /
void DisplayWeek()
{
switch(TIME[5])
{
case 1: DisplayString(0,2,"星期:Mo");break;
case 2: DisplayString(0,2,"星期:Tu");break;
case 3: DisplayString(0,2,"星期:We");break;
case 4: DisplayString(0,2,"星期:Th");break;
case 5: DisplayString(0,2,"星期:Fr");break;
case 6: DisplayString(0,2,"星期:Sa");break;
case 7: DisplayString(0,2,"星期:Su");break;
}
}
/*****************************DS1302.h***********************************/
#ifndef _DS1302_h
#define _DS1302_h
/*****包含头文件*******/
#include<reg51.h>
#include<intrins.h>
/***********定义I/O口********************/
sbit DSIO=P3^4;
sbit RST= P3^5;
sbit SCLK=P3^6;
///***********声明全局变量**********************/
extern unsigned char TIME[7];
//---声明全局函数---//
void Ds1302Write(unsigned char addr, unsigned char dat);
unsigned char Ds1302Read(unsigned char addr);
void Ds1302Init();
void Ds1302ReadTime();
unsigned char changeBCD_Variable(unsigned char );
unsigned char changeV ariable_BCD(unsigned char );
#endif
/*****************************DS1302.c***********************************/
#include"DS1302.h"
//---DS1302写入和读取时分秒的地址命令---//
//---秒分时日月周年最低位读写位;-------//
unsigned char code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; unsigned char code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
/****************************************************************************** *
* 函数名: Ds1302Write
* 函数功能: 向DS1302命令(地址+数据)
* 输入: addr,dat
* 输出: 无
******************************************************************************* /
void Ds1302Write(unsigned char addr, unsigned char dat)
{
unsigned char n;
RST = 0;
_nop_();
SCLK = 0;//先将SCLK置低电平。

_nop_();
RST = 1; //然后将RST(CE)置高电平。

_nop_();
for (n=0; n<8; n++)//开始传送八位地址命令
{
DSIO = addr & 0x01;//数据从低位开始传送
addr >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
for (n=0; n<8; n++)//写入8位数据
{
DSIO = dat & 0x01;
dat >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
RST = 0;//传送数据结束
_nop_();
}
/****************************************************************************** *
* 函数名: Ds1302Read
* 函数功能: 读取一个地址的数据
* 输入: addr
* 输出: dat
******************************************************************************* /
unsigned char Ds1302Read(unsigned char addr)
{
unsigned char n,dat,dat1;
RST = 0;
_nop_();
SCLK = 0;//先将SCLK置低电平。

_nop_();
RST = 1;//然后将RST(CE)置高电平。

_nop_();
for(n=0; n<8; n++)//开始传送八位地址命令
{
DSIO = addr & 0x01;//数据从低位开始传送
addr >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
_nop_();
for(n=0; n<8; n++)//读取8位数据
{
dat1 = DSIO;//从最低位开始接收
dat = (dat>>1) | (dat1<<7);
SCLK = 1;
_nop_();
SCLK = 0;//
_nop_();
}
RST = 0;
_nop_(); //以下为DS1302复位的稳定时间,必须的。

SCLK = 1;
_nop_();
DSIO = 0;
_nop_();
DSIO = 1;
_nop_();
return dat;
}
/****************************************************************************** *
* 函数名: Ds1302Init
* 函数功能: 初始化DS1302.
* 输入: 无
* 输出: 无
******************************************************************************* /
void Ds1302Init()
{
unsigned char n;
Ds1302Write(0x8E,0X00); //关闭写保护功能
for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
{
Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
}
Ds1302Write(0x8E,0x80); //打开写保护功能
}
/****************************************************************************** *
* 函数名: Ds1302ReadTime
* 函数功能: ReadTime
* 输入: 无
* 输出: 无
******************************************************************************* /
void Ds1302ReadTime()
{
unsigned char n;
for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
{
TIME[n]=Ds1302Read(READ_RTC_ADDR[n]);
TIME[n]=changeBCD_Variable(TIME[n]);
}
}
/*****************************************************************************/ /*BCD码转换成十进制
*****************************************************************************/ unsigned char changeBCD_Variable(unsigned char data1)
{
unsigned char i=0,j=0;
i=data1&0xf0;
i>>=4;
j=data1&0x0f;
data1=i*10+j;
return data1;
}
/***************************************************************************** *十进制转换成BCD
*****************************************************************************/ unsigned char changeV ariable_BCD(unsigned char data2)
{
unsigned char i=0,j=0;
i=data2/10;
i<<=4;
j=data2%10;
data2=i+j;
return data2;
}
/*****************************key.h***********************************/
#ifndef _Key_h
#define _Key_h
#include<reg51.h>
#include"12864.h"
/*******定义I/O口*********/
#define GPIO_KEY P1
/*********声明全局变量***********/
extern unsigned char keyvalue;
/**************声明全局函数*************/
void KeyDown();
unsigned char keycurrent(unsigned char ,int);
void toolmode();
#endif
/*****************************key.c***********************************/
#include"Key.h"
/****************************************************************************** *
* 函数名: keyvalue
* 函数功能: 矩阵按键值
* 输入: 无
* 输出: keyvalue
******************************************************************************* /
const char code ValueList[]={ //下限上限
0, 59, //秒
1, 59, //分
1, 12, //时
1, 31, //日
1, 12, //月
1, 7, //周
1, 99 // 年
};
/*矩阵按键扫描*/
void KeyDown(void)
{
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)
{
Delay1ms(3);
if(GPIO_KEY!=0x0f)
{
switch(GPIO_KEY)
{
case 0x07: keyvalue=1; break;
case 0x0b: keyvalue=2; break;
case 0x0d: keyvalue=3; break;
case 0x0e: keyvalue=4; break;
}
GPIO_KEY=0xf0;
switch(GPIO_KEY)
{
case 0x70: keyvalue=keyvalue;break;
case 0xb0: keyvalue+=4; break;
case 0xd0: keyvalue+=8; break;
case 0xe0: keyvalue+=12;break;
}
while(GPIO_KEY!=0xf0)
{
Delay1ms(3);
}
}
}
}
unsigned char keycurrent(unsigned char value,int i) {
if(value==2)
{
keyvalue=0;
TIME[i]++;
if(TIME[i]>ValueList[2*i+1])
TIME[i]=ValueList[2*i];
}
if(value==3)
{
keyvalue=0;
TIME[i]--;
if(TIME[i]<=ValueList[2*i])
TIME[i]=ValueList[2*i+1];
}
return TIME[i];
}
/*********按键处理,调节时间***********/ void toolmode(void)
{
unsigned char n;
keyvalue=0;
WrCom(0x01); //清屏
WrCom(0x02); //复位
Ds1302ReadTime();//读ds1302中数值
///////////////////////////////
TIME[0]=0x00;
while(1) //年设置
{
WrCom(0x80);
WrDat('2');
WrDat('0');
WrDat('0'+TIME[6]/10);
WrDat('0'+(TIME[6]%10));
DisplayString(2,1,"年");
KeyDown(); //按键扫描
keycurrent(keyvalue,6);
if(keyvalue==1)
{
keyvalue=0;
break;
}
if(keyvalue==4) //进入月设置{
keyvalue=0;
break;
}
}
while(1) //月份设置
{
WrCom(0x80+3);
WrDat('0'+(TIME[4]/10));
WrDat('0'+(TIME[4]%10));
DisplayString(4,1,"月");
KeyDown();
keycurrent(keyvalue, 4);
if(keyvalue==1)
{
keyvalue=0;
goto EXIT_toolmode;
}
if(keyvalue==4) //进入日期设置
{
keyvalue=0;
break;
}
}
while(1) //日期设置
{
WrCom(0x80+5);
WrDat('0'+(TIME[3]/10));
WrDat('0'+(TIME[3]%10));
DisplayString(6,1,"日");
KeyDown();
keycurrent(keyvalue, 3);
if(keyvalue==1)
{
keyvalue=0;
goto EXIT_toolmode;
}
if(keyvalue==4) //进入周设置{
keyvalue=0;
break;
}
}
while(1) //周设置
{
DisplayWeek();
KeyDown();
keycurrent(keyvalue,5);
if(keyvalue==1)
{
keyvalue=0;
goto EXIT_toolmode;
}
if(keyvalue==4) //进入时间设计{
keyvalue=0;
break;
}
}
while(1) //时间设置
{
WrCom(0x88);
WrDat('0'+(TIME[2]/10));
WrDat('0'+(TIME[2]%10));
DisplayString(1,3,":");
KeyDown();
keycurrent(keyvalue, 2);
if(keyvalue==1)
{
keyvalue=0;
goto EXIT_toolmode;
}
if(keyvalue==4) //进入分钟设置
{
keyvalue=0;
break;
}
}
while(1) //分钟设置
{
DisplayString(1,3,":");
WrDat('0'+(TIME[1]/10));
WrDat('0'+(TIME[1]%10));
WrDat(':');
KeyDown();
keycurrent(keyvalue, 1);
if(keyvalue==1||keyvalue==4)
{
keyvalue=0;
break;
}
}
EXIT_toolmode:
/*将十进制数转换成BCD码*/
for(n=0;n<7;n++)
{
TIME[n]=changeVariable_BCD(TIME[n]);
}
Ds1302Init(); //将数据存入Ds1302中
WrCom(0x0C);
}
/*****************************main.c***********************************/ #include"Key.h"
/*定义全局变量*/
unsigned char keyvalue;
//---DS1302时钟初始化2013年1月1日星期天12点00分00秒。

---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
unsigned char TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x07, 0x13};
void main()
{
bit bTimeFlag=0;
keyvalue=0;
LcdInit();
Ds1302Init();
Ds1302ReadTime();
DisplayDay();
DisplayWeek();
while(1)
{
Ds1302ReadTime();
if(TIME[2]==12)
{bTimeFlag=1;}
if(TIME[2]==0&&bTimeFlag==1)
{
bTimeFlag=0;
DisplayDay();
DisplayWeek();
}
DisplayTime();
KeyDown();
if(keyvalue==1)
{
keyvalue=0;
toolmode();
}
}
}。

相关文档
最新文档