📄 pcf8563timelcddisplay.txt
字号:
PCF8563时间LCD显示(全部原代码,可直接使用)
/* 8563.c */
/*------------------------------------
PCF8563 I2C 总线从地址:读:0A3H;写:0A2H;
前两个寄存器(内存地址00H,01H)用于控制寄存器和状态寄存器,内存地址02H~08H 用于时钟计
数器(秒~年计数器),地址09H~0CH 用于报警寄存器(定义报警条件),地址0DH 控制
CLKOUT 管脚的输出频率,地址0EH 和0FH 分别用于定时器控制寄存器和定时器寄存器。
秒、分钟、小时、日、月、年、分钟报警、小时报警、日报警寄存器,编码格式为BCD,
星期和星期报警寄存器不以BCD 格式编码。
5:BCD 格式寄存器概况
标明“-”的位无效
地址 寄存器名称 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
02h 秒 VL 00~59BCD 码格式数
03h 分钟 - 00~59BCD 码格式数
04h 小时 - - 00~59BCD 码格式数
05h 日 - - 01~31BCD 码格式数
06h 星期 - - - - - 0~6
07h 月/世纪 C - - 01~12 BCD 码格式数
08h 年 00~99 BCD 码格式数
09h 分钟报警 AE 00~59 BCD 码格式数
0Ah 小时报警 AE - 00~23 BCD 码格式数
0BH 日报警 AE - 01~31 BCD 码格式数
0CH 星期报警 AE - - - - 0~6
------------------------------------*/
#include <reg52.h>
#include <intrins.h>
#include "8563.h"
uchar g8563_Store[7]; /*时间交换区,全局变量声明*/
uchar Store[2];
uchar code c8563_Store[7]={
0x00,
0x59,
0x22, /*写入时间初值:22:59:00*/
0x23, /* 23日 */
0x05, /* 星期5 */
0x12, /* 12月 */
0x05 /* 2005年 */
};
void Time_putnum(uchar datax)
{
uchar temp;
temp=datax;
Store[0]=(temp>>4)&0x0f; /*十位*/
Store[1]=temp&0x0f; /*个位*/
}
/********************************************
内部函数,延时1
********************************************/
void DD()
{
_nop_();
_nop_(); /*根据晶振频率制定延时时间*/
}
/********************************************
内部函数,I2C开始
********************************************/
void Start()
{ EA=0;
SDA=1;
SCL=1;
DD();
SDA=0;
DD();
SCL=0;
}
/********************************************
内部函数,I2C结束
********************************************/
void Stop()
{
SDA=0;
SCL=0;
DD();
SCL=1;
DD();
SDA=1;
DD();
EA=1;
}
/********************************************
内部函数,输出ACK ,每个字节传输完成,输出ack=0,结束读书据,ack=1;
********************************************/
void WriteACK(uchar ack)
{
SDA=ack;
DD();
SCL=1;
DD();
SCL=0;
}
/********************************************
内部函数,等待ACK
********************************************/
void WaitACK()
{ uchar errtime=20;
SDA=1;
DD(); /*读ACK*/
SCL=1;
DD();
while(SDA)
{ errtime--;
if(!errtime) Stop();
}
SCL=0;
DD();
}
/********************************************
内部函数.输出数据字节
入口:B=数据
********************************************/
void writebyte(uchar wdata)
{
uchar i;
for(i=0;i<8;i++)
{
if(wdata&0x80) SDA=1;
else SDA=0;
wdata<<=1;
SCL=1;
DD();
SCL=0;
}
WaitACK(); //I2C器件或通讯出错,将会退出I2C通讯
}
/********************************************
内部函数.输入数据
出口:B
********************************************/
uchar Readbyte()
{
uchar i,bytedata;
SDA=1;
for(i=0;i<8;i++)
{
SCL=1;
bytedata<<=1;
bytedata|=SDA;
SCL=0;
DD();
}
return(bytedata);
}
/********************************************
输出数据->pcf8563
********************************************/
void writeData(uchar address,uchar mdata)
{
Start();
writebyte(0xa2); /*写命令*/
writebyte(address); /*写地址*/
writebyte(mdata); /*写数据*/
Stop();
}
/********************************************
输入数据<-pcf8563
********************************************/
uchar ReadData(uchar address) /*单字节*/
{ uchar rdata;
Start();
writebyte(0xa2); /*写命令*/
writebyte(address); /*写地址*/
Start();
writebyte(0xa3); /*读命令*/
rdata=Readbyte();
WriteACK(1);
Stop();
return(rdata);
}
void ReadData1(uchar address,uchar count,uchar * buff) /*多字节*/
{ uchar i;
Start();
writebyte(0xa2); /*写命令*/
writebyte(address); /*写地址*/
Start();
writebyte(0xa3); /*读命令*/
for(i=0;i<count;i++)
{
buff=Readbyte();
if(i<count-1) WriteACK(0);
}
WriteACK(1);
Stop();
}
/********************************************
内部函数,读入时间到内部缓冲区
********************************************/
void P8563_Read()
{
uchar time[7];
ReadData1(0x02,0x08,time);
g8563_Store[0]=time[0]&0x7f; /*秒*/
g8563_Store[1]=time[1]&0x7f; /*分*/
g8563_Store[2]=time[2]&0x3f; /*小时*/
g8563_Store[3]=time[3]&0x3f; /*日*/
g8563_Store[4]=time[4]&0x07; /*星期*/
g8563_Store[5]=time[5]&0x1f; /*月/世纪*/
g8563_Store[6]=time[6]; /*年*/
}
/********************************************
读入时间到内部缓冲区----外部调用
********************************************/
void P8563_gettime()
{
P8563_Read();
if(g8563_Store[0]==0)
P8563_Read(); /*如果为秒=0,为防止时间变化,再读一次*/
}
/********************************************
写时间修改值
********************************************/
void P8563_settime()
{
uchar i;
for(i=2;i<=8;i++) { writeData(i,g8563_Store[i-2]); } //写含小时之后时间
//writeData(6,g8563_Store[3]); //写星期
}
/********************************************
P8563的初始化-----外部调用
********************************************/
void P8563_init()
{
uchar i;
if((ReadData(0x02)&0x7f)==0x8) /* 检查是否第一次启动,是则初始化时间,
检查对象为秒(0x02)最高位为1则初始化*/
{
for(i=0;i<=6;i++) g8563_Store=c8563_Store; /*初始化时间*/
P8563_settime();
}
}
/* 显示部分 */
#include <REG52.H>
#define uchar unsigned char
#define uint unsigned int
extern uchar code bmp001[];
extern delay1s(uchar i);
extern uchar g8563_Store[6]; /*时间交换区,全局变量声明*/
extern uchar Store[2];
void display()
{
extern Draw_word(uint d_where,uint x_add,bit layer,uchar width);
extern clrscr();
extern Time_putnum(uchar datax);
Time_putnum(g8563_Store[0]);
Draw_word(Store[0],76,1,8); //秒
Draw_word(Store[1],84,1,8);
Draw_word(10,68,1,8); //:
Time_putnum(g8563_Store[1]);
Draw_word(Store[0],52,1,8); //分
Draw_word(Store[1],60,1,8);
Draw_word(10,44,1,8); //:
Time_putnum(g8563_Store[2]);
Draw_word(Store[0],28,1,8); //时
Draw_word(Store[1],36,1,8);
Time_putnum(g8563_Store[3]);
Draw_word(Store[0],74,0,8); //"日"
Draw_word(Store[1],82,0,8);
Draw_word(11,66,0,8); //"/"
Time_putnum(g8563_Store[5]);
Draw_word(Store[0],50,0,8); //"月"
Draw_word(Store[1],58,0,8);
Draw_word(11,42,0,8); //"/"
Time_putnum(g8563_Store[6]);
Draw_word(2,10,0,8); //"年"
Draw_word(0,18,0,8);
Draw_word(Store[0],26,0,8);
Draw_word(Store[1],34,0,8);
Time_putnum(g8563_Store[4]);
Draw_word(Store[1]*2+10,95,0,16); //"星期"
}
/* 12232驱动 */ (BOY123的杰作)
/*============================================================
功能:使用12232液晶显示
==============================================================
硬件:TG12232B (122*32)模拟口线接线方式
连接线图:
----------------------------------------------
|DB0-----P0.0 | DB4-----P0.4 | A0-------P1.7 |
|DB1-----P0.1 | DB5-----P0.5 | RS-------P2.1 |
|DB2-----P0.2 | DB6-----P0.6 | E1-------P1.6 |
|DB3-----P0.3 | DB7-----P0.7 | E2-------P1.5 |
----------------------------------------------*/
#include <reg52.H>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit E1=P1^6; //片选1(Master)左边
sbit E2=P1^5; //片选2(slave)右边
//sbit RW=P1^1; //读1/写0
sbit A0=P1^7; //A0为1时是数据,0时为指令数据
#define DATA P0 //数据
extern unsigned char code bmp001[];
extern delay1s(uchar i);
//左页
//发送数据
void OUTMD(uchar i) //MD:MasterData
{
A0=1; //写数据
E1=1; //1片选M
DATA=i;
E1=0;
}
//左页
//发送命令
void OUTMI(uchar i) //MI:MasterInstruction
{
A0=0; //写指令
E1=1;
DATA=i;
E1=0;
}
//右页
//发送数据
void OUTSD(uchar i) //SD:SendData
{
A0=1; //写数据
E2=1;
DATA=i;
E2=0;
}
//右页
//发送命令
void OUTSI(uchar i) //SendInstruction
{
A0=0; //写指令
E2=1;
DATA=i;
E2=0;
}
//初始化
extern void lcdini(void)
{
//RW=0;
OUTMI(0XE2);
OUTSI(0XE2);//复位
OUTMI(0XAE);
OUTSI(0XAE);//POWER SAVE
OUTMI(0XA4);
OUTSI(0XA4);//动态驱动
OUTMI(0XA9);
OUTSI(0XA9);//1/32占空比
OUTMI(0XA0);
OUTSI(0XA0);//时钟线输出
OUTMI(0XEE);
OUTSI(0XEE);//写模式
OUTMI(0X00);
OUTMI(0XC0);
OUTSI(0X00);
OUTSI(0XC0);
OUTMI(0XAF);
OUTSI(0XAF);
}
/*
函数说明:同时设置主从显示页为0-3页。(内函数,私有,用户不直接调用)
------------------------------------------------------------------------*/
void SetPage(uchar page0,uchar page1)
{
OUTMI(0xB8|page1);OUTSI(0xB8|page0);
}
/*
--------------------------------------------------------------------------------
函数说明:同时设置主从列地址为0-121。(内函数,私有,用户不直接调用)
--------------------------------------------------------------------------------
*/
void SetAddress(uchar address0,uchar address1)
{
OUTMI(address1);OUTSI(address0);
}
/*
--------------------------------------------------------------------------------
调用方式:void PutChar0(uchar ch)
函数说明:在右页当前地址画一个字节8个点。(内函数,私有,用户不直接调用)
--------------------------------------------------------------------------------
-*/
void PutCharR(uchar ch)
{
OUTSD(ch);
}
/*
--------------------------------------------------------------------------------
调用方式:void PutChar1(uchar ch)
函数说明:在左页当前地址画一个字节8个点。(内函数,私有,用户不直接调用)
--------------------------------------------------------------------------------
-*/
void PutCharL(uchar ch)
{
OUTMD(ch);
}
/*
--------------------------------------------------------------------------------
调用方式:void clrscr(void)
函数说明:清屏
--------------------------------------------------------------------------------
-*/
void clrscr(void)
{
uchar i;
uchar page;
for (page=0;page<4;page++)
{
SetPage(page,page);
SetAddress(0,0);
for (i=0;i<61;i++){PutCharR(0);PutCharL(0);}
}
}
//---------------------------------------------------------------
//---------------------------------------------------------------
//采用zimo2 显示汉字,以汉字的显示方式
//void Draw_word(uchar d_where,uint x_add,bit layer,uchar width)
//d_where表示在码表中第几个汉字,x_add横坐标位置,layer显示的层, width显示的宽度。
//---------------------------------------------------------------
void Draw_word(uint d_where,uint x_add,bit layer,uchar width) //<----width: 修改部位
{
uchar x,i=0,address; //address表示显存的物理地址
uchar page=0; //page表示上下两页
bit window=0; //window表示左右两页
//putcharR //右边
//putcharL //左边
d_where=d_where*16; //<----修改部位
for (x=width;x>1;x--)
{
if (x_add>60) {window=1;address=x_add%61;}
else address=x_add
;
if(layer==0) //显示一行八个字
{
SetPage(0,0);
SetAddress(address,address);
if(window==1)PutCharR(bmp001[d_where]);//右边
else PutCharL(bmp001[d_where]);//左边
SetPage(1,1);
SetAddress(address,address);
if(window==1)PutCharR(bmp001[d_where+width]);
else PutCharL(bmp001[d_where+width]);
}
else
{ //显示第二行八个汉字
SetPage(2,2);
SetAddress(address,address);
if(window==1)PutCharR(bmp001[d_where]);//右边
else PutCharL(bmp001[d_where]);//左边
SetPage(3,3);
SetAddress(address,address);
if(window==1)PutCharR(bmp001[d_where+width]);
else PutCharL(bmp001[d_where+width]);
}
x_add++;
d_where++;
}
}
//液晶显示规则
// M(左) S(右)
// page page
// 0 | 0
// 1 | 1
// 2 | 2
// 3 | 3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -