📄 main_lcd.c
字号:
/*****************************************************************/
/* */
/*名称: ds1302读写+显示程序 */
/*功能: 读写DS1302,通过LCD12864显示出来。 */
/*难度等级: 高 */
/* 作者: zengrenliang */
/* 版权: http://www.51kaifa.com */
/*编写日期: 2006.05.21 */
/*****************************************************************/
#include <reg52.h>
#include"ds1302.h"
#include <string.h>
#define uchar unsigned char
/******************************引脚定义*****************************/
sbit lck = P3^5;//锁存信号
sbit CSA = P2^4;//又区选择
sbit CSB = P2^5;//左区选择
sbit RW = P2^7;//LCD片选
sbit DI = P2^6;//数据/命令选择
/************************LCD12864常用命令及参数定义******************/
#define DISPON 0x3f
#define DISPOFF 0x3e
#define DISPFIRST 0xc0
#define SETX 0x40
#define SETY 0xb8
#define LCDBUZY 0x80
#define L 0x00
#define R 0x40
#define LIMIT 0x80
/*********************************全局变量***************************/
uchar cbyte, statu;
bit xy;
/***********************************函数声明**************************/
void initial();
void uDelay(uchar MS);
void WrL(uchar x);
void WrR(uchar x);
void Lcmcls(void);
void LcdbuzyR(void);
void LcdbuzyL(void);
void delay1s(void);
void Lcminit (void);
void Putpicture(void);
void readtemp(void);
void delay(unsigned int time);
void VtoH8x16change(uchar *hzbuf);
void Puthalf(uchar *strch,uchar row,uchar col);
void Wrdata(uchar x,uchar row,uchar col);
void Puthz(uchar *str,uchar row,uchar col);
void v_Get1302(uchar ucCurtime[]);
void Locatexy(uchar row,uchar col);
void v_Set1302(uchar *pSecDa) ;
void vWrite8x16Character(uchar *ch,uchar row,uchar col,bit flag);
void vWrite16x16Chinese(uchar *ch,uchar row,uchar col,bit flag);
void vWrite8x16String(uchar *str,uchar col, uchar row, bit flag);
extern uchar code picture[];//以图片的形式显示 "年 月 日,时 分 秒"
extern uchar code char_Table[95][16];//字符点阵码表
uchar buffer[8];//DS1302的数据存储区
uchar code *XingQi[7] = //星期
{
"Monday","Tuesday", "Wednesday","Thursday","Friday","Saturday","Sunday"
};
/*******************************主程序******************************/
void main(void)
{
uchar disp;
uchar temp,copymt;
copymt = 0xff;
buffer[0]=00;//秒
buffer[1]=30;//分
buffer[2]=12;//时
buffer[3]=10;//日
buffer[4]=1;//月
buffer[5]=02;//星期
buffer[6]=07;//年
initial();
Lcminit();//初始化LCD
v_Set1302(&buffer);//设置和启动DS1302
Putpicture();//显示 "时 分 秒 ,年 月 日"
while(1)
{
v_Get1302(&buffer); //读取DS1302
delay(10000);
if(buffer[0]!=copymt){//每秒刷新一次
copymt = buffer[0];
disp = buffer[0] % 10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],0,92,0);//秒个位
temp =buffer[0];// & 0x7f;
temp = temp/10;
disp = temp%10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],0,84,0);//秒十位
disp = buffer[1] % 10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],0,52,0);//分个位
temp =buffer[1];// & 0x7f;
temp = temp/10;
disp = temp%10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],0,44,0);//分十位
disp = buffer[2] % 10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],0,12,0);//时个位
temp =buffer[2];// & 0x7f;
temp = temp/10;
disp = temp%10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],0,4,0);//时十位
vWrite8x16String(XingQi[buffer[5]] ,3, 40,0);//显示星期
disp = buffer[3] % 10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],6,96,0);//日个位
temp =buffer[3];// & 0x7f;
temp = temp/10;
disp = temp%10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],6,88,0);//日十位
disp = buffer[4] % 10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],6,64,0);//月个位
temp =buffer[4];// & 0x7f;
temp = temp/10;
disp = temp%10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],6,56,0);//月十位
disp = buffer[6] % 10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],6,32,0);//年个位
temp =buffer[6]/* & 0x7f*/;
temp = temp/10;
disp = temp%10 + '0';
vWrite8x16Character(&char_Table[disp-0x20][0],6,24,0);//年十位
}
}
}
/*********************************微秒级延时******************************/
void delay(unsigned int time)
{ unsigned int i;
for(i=0;i<time;i++);
}
//*********************************初始化LCD*******************************/
void Lcminit (void)
{
cbyte=DISPOFF;
WrL(cbyte);
WrR(cbyte);
cbyte=DISPON;
WrL(cbyte);
WrR(cbyte);
cbyte=DISPFIRST;
WrL(cbyte);
WrR(cbyte);
Lcmcls();
Locatexy(0,0);
}
/***********************************LCD清屏********************************/
void Lcmcls(void)
{ uchar i,j;
for(i=0;i<8;i++){
delay(6);
for(j=0;j<LIMIT;j++){
delay(6);
Wrdata(0x0,i,j);
}
}
}
/*****************写左区******************/
void WrL(uchar x)
{
RW = 1;//RW=1(读)
CSA = 0;
CSB = 1;
DI = 0;//命令操作
lck = 0;
P1 = 0xff;//ELCD=1,使能LCD
lck = 1;
while(P0 & LCDBUZY);//最高位为1,表示忙,则循环检测
lck = 0;
P1 = 0xef;//ELCD=1,使能LCD
lck = 1;
RW = 0;//RW=0(写)
P0 = x; //数据送到P0口
CSA = 0;
CSB = 1;
DI = 0;
lck = 0;
P1 = 0xff;//ELCD=1,使能LCD,把数据打入LCD
lck = 1;
delay(3);
lck = 0;
P1 = 0xef;//ELCD=0
lck = 1;
}
/**************写右区**************/
void WrR(uchar data x)
{
RW = 1;//R/W=1读
CSA = 1;
CSB = 0;
DI = 0;//命令操作
lck = 0;
P1 = 0xff;
lck = 1;
//EN = 1;//使能LCD
while(P0 & LCDBUZY);//最高位为1,表示忙,则循环
lck = 0;
P1 = 0xe;
lck = 1;
RW = 0;//RW = 0写
P0=x; //数据送到P0口
CSA = 1;
CSB = 0;
DI = 0;
lck = 0;
P1 = 0xff;
lck = 1;//使能LCD,把数据打入LCD
delay(3);
lck = 0;
P1 = 0xef;
lck = 1;
}
/*************定位*****************/
void Locatexy(uchar row,uchar col)
{
uchar x, y, right;
switch(col&0xc0)
{
case 0:{//右半屏
RW = 1;//R/W=1(读)
CSA = 1;
CSB = 0;
DI = 0;//命令操作
lck = 0;
P1 = 0xff;
lck = 1;; //使能LCD
while(P0 & LCDBUZY);//最高位为1,表示忙,则循环
lck = 0;
P1 = 0xef;
lck = 1;
right = 1;break;}//置右半屏标志
case 0x40:{//左半屏
RW = 1;//R/W=1读
CSA = 0;
CSB = 1;
DI = 0;//命令操作
lck = 0;
P1 = 0xff;
lck = 1;//使能LCD
while(P0 & LCDBUZY);//最高位为1,表示忙,则循环
lck = 0;
P1 = 0xef;
lck = 1;
right = 0;break;}//置左半屏标志
}
x=col&0x3f|SETX;//把列数据变成行命令
y=row&0x07|SETY;//把行数据变成行命令
/**********************************/
lck = 0;
P1 = 0xff;
lck = 1;//判断忙标志
while(P0 & LCDBUZY);//最高位为1,表示忙,则循环
lck = 0;
P1 = 0xef;
lck = 1;
/*********以上为判断忙标志********/
/*********************************/
RW = 0;//R/W=0写
P0 = y;//行数据送到P0口
lck = 0;
P1 = 0xff;
lck = 1;//使能LCD,把数据打入LCD
delay(3);
lck = 0;
P1 = 0xef;
lck = 1;
/**********以上为送行命令***********/
RW =1;//R/W=1读
lck = 0;
P1 = 0xff;
lck = 1;//使能LCD,准备读忙标志
while(P0 & LCDBUZY);//最高位为1,表示忙,则循环
lck = 0;
P1 = 0xef;
lck = 1;
/*********以上为判断忙标志********/
RW = 0;//R/W=0写
P0 = x;//列数据送P0口
lck = 0;
P1 = 0xff;
lck = 1;//使能LCD,把数据打入LCD
delay(3);
lck = 0;
P1 = 0xef;
lck = 1;
/**********以上为送列命令***********/
if(right)
statu = 1;//置右半区标志
else
statu = 0;//置左半区标志
}
/**************数据写输出***************/
void Wrdata(uchar x,uchar row,uchar col)
{
Locatexy(row,col);//定位显示位置
RW = 0;//R/W=0
DI = 1;//数据操作
lck = 0;
P1 = 0xef;
lck = 1;;//不使能LCD
if(statu){//根据状态确定是左半屏还是右半屏
CSA= 1;
CSB= 0;
}else{
CSA=0;
CSB=1;
}
P0 = x;//送显示数据
lck = 0;
P1 = 0xff;
lck = 1; //使能LCD,把P0数据打入LCD
delay(3);
lck = 0;
P1 = 0xef;
lck = 1;
}
/******************************************图形输出*********************************/
void Putpicture(void)
{
unsigned char i,j,row, col ;
unsigned int x;
row = 0; col=0;
for(j=0;j<128;j++){
x=j*0x08;
for(i=0;i<8;i++)
{
cbyte=picture[x++];
Wrdata(cbyte,row,col);
row++;
}
row=0;
col++;
}
}
/****************************************半角数据点阵输出******************************/
void Puthalf(uchar *strch,uchar row,uchar col)
{
uchar i,bakerx;
bakerx = row;
for(i=0;i<16;i++)//上半字输出
{
cbyte=strch[i];
Wrdata(cbyte,bakerx,col);
cbyte=strch[i+1];
Wrdata(cbyte,bakerx+1,col);
col++;
i++;
}
}
/***************************************字符型点阵行--》列转换************************/
void VtoH8x16change(uchar *hzbuf)
{ uchar i,j,k, cash[16];
uchar newbyte, savebit[8];
for(k=0;k<16;k++){
newbyte = 0;
for(i=0;i<8;i++){
savebit[i]=hzbuf[i] & 0x80;
}
for(j=0;j<8;j++){
savebit[j] = savebit[j] >> (7-j);
newbyte = newbyte | savebit[j];
}
cash[k] = newbyte;
newbyte = 0;
for(i=8;i<16;i++){
savebit[i-8]=hzbuf[i] & 0x80;
}
for(j=0;j<8;j++){
savebit[j] = savebit[j] >> (7-j);
newbyte = newbyte |savebit[j];
}
cash[k+1] = newbyte;
for(j=0;j<16;j++){
hzbuf[j] = hzbuf[j] <<1;
}
k++;
}
for(i=0;i<16;i++)
hzbuf[i] = cash[i];
}
/*************************************显示英文和符号字符*******************************/
void vWrite8x16Character(uchar *ch,uchar row,uchar col,bit flag)
{
uchar ucXArray[16],i;
if(flag){ // 反白显示英文
for(i = 0; i < 16; i++)
ucXArray[i] = ~ch[i];
}else{
for(i = 0; i < 16; i++)
ucXArray[i] = ch[i];
}
VtoH8x16change(ucXArray);
Puthalf(ucXArray,row,col);
}
/******************************************显示中英文字符串************************************/
void vWrite8x16String(uchar *str,uchar row, uchar col, bit flag)
{
unsigned char i, j,thiscol;
j = strlen(str);
for(i = 0; i < j; i++)
{ thiscol = (i % 16) * 8 + col;//计算列地址
if(str[i] < 0xa1)//当前显示内容为英文字符
vWrite8x16Character(&char_Table[str[i]-0x20][0],row,thiscol,flag);
}
}
/**************************************结束*************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -