钻石会员
主题
帖子
积分16938
阅读权限50
注册时间2010-2-3
最后登录1970-1-1
在线时间 小时
|
也想做一个12864(无字库)GPS时钟 但有问题
1:十位到9才进位即一分钟变90秒一小时变90分钟
2:走时跳秒规律如下09-16,25-32,41-48,57-64,73-80,中间跳过7秒
求高手指导,谢谢!我只会改个端口定义啥的,见笑了!
发程序:
/****************************************/
/*不带字库的12864LCD/
/*目标器件:STC89C52) */
/*晶振:11.0592MHZ */
/*编译环境:Keil3 */
/****************************************/
/*********************************包含头文件********************************/
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar miao,shi,fen;
bit rev_start,rev_stop;
unsigned char buf[80]; //请把GPS那货发来的数据放到我的肚子里
/********************************命令字定义*********************************/
#define LCDLCDDisp_On 0x3f
#define LCDLCDDisp_Off 0x3e
#define LCDCol_Add 0x40
#define Page_Add 0xb8
#define Start_Line 0xc0
/*********************************端口定义**********************************/
sbit LCDMcs=P1^3; //左半屏使能,当LCDMcs=1,左半屏显示
sbit LCDScs=P1^4; //右半屏使能,当LCDScs=1,右半屏显示
sbit LCDEnable=P1^2; //使能
sbit LCDDi=P1^0; //数据/命令选择(RS)
sbit LCDRW=P1^1; //读/写信号
sbit LCRst=P1^5; //复位脚
sbit LCLight=P2^7; //背光灯
sbit LED=P2^4; //数据接收指示
sbit LED1=P2^5; //数据接收指示
void TimerInit()
{
TMOD=0x21;
TH0 = 0xF1; // 4ms刷新
TL0 = 0x09;
EA=1;
ET0=1;
TR0=1;
SCON = 0x50; //使用串行工作方式1,10位异步收发8位数据,波特率可变(由T1的溢出率控制)
TH1 = 0xFd; //9600波特率的初值
TL1 = 0XFa; //9600波特率的初值
ES = 1;
TR1 = 1;
}
void Timer0() interrupt 1 ///每4ms刷新下
{
TH0 = 0xF1;
TL0 = 0x9A;
}
/**********************************字模表***********************************/
char code shmaohao[]={
/*-- 文字: : --*/
/*-- 宋体18; 此字体下对应的点阵为:宽x高=12x24 --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x0E,0x0E,0x0E,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x1C,
0x00,0x00,0x00,0x00,
};
/*************************用于显示时分秒**************************/
char code shk[][36]={
{
/*-- 文字: 0 --*/
/*-- 宋体18; 此字体下对应的点阵为:宽x高=12x24 --*/
0x00,0x00,0xC0,0xE0,0xE0,0x20,0x20,0xE0,0xE0,0xC0,0x00,0x00,0x78,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x03,0x0F,0x1F,0x1C,0x10,0x10,0x1C,
0x1F,0x0F,0x03,0x00,
},
{
/*-- 文字: 1 --*/
/*-- 宋体18; 此字体下对应的点阵为:宽x高=12x24 --*/
0x00,0x00,0x80,0x80,0x80,0xC0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x18,0x1F,0x1F,0x1F,
0x10,0x10,0x00,0x00,
},
{
/*-- 文字: 2 --*/
/*-- 宋体18; 此字体下对应的点阵为:宽x高=12x24 --*/
0x00,0x80,0xC0,0xE0,0x60,0x20,0x20,0x60,0xE0,0xC0,0x80,0x00,0x00,0x03,0x03,0x03,
0x80,0xC0,0xE0,0x78,0x3F,0x1F,0x07,0x00,0x18,0x1C,0x1E,0x1B,0x19,0x18,0x18,0x18,
0x1C,0x1F,0x1F,0x00,
},
{
/*-- 文字: 3 --*/
/*-- 宋体18; 此字体下对应的点阵为:宽x高=12x24 --*/
0x00,0x80,0xC0,0xE0,0x20,0x20,0x60,0xE0,0xE0,0xC0,0x00,0x00,0x00,0x03,0x03,0x03,
0x10,0x10,0x18,0x3F,0xEF,0xE7,0xC3,0x00,0x00,0x0F,0x0F,0x1F,0x18,0x10,0x10,0x18,
0x1F,0x0F,0x07,0x00,
},
{
/*-- 文字: 4 --*/
/*-- 宋体18; 此字体下对应的点阵为:宽x高=12x24 --*/
0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xF0,0xF0,0x00,0x00,0x00,0x80,0xE0,0xF8,0xBC,
0x8F,0x83,0xFF,0xFF,0xFF,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x1F,0x1F,
0x1F,0x18,0x10,0x00,
},
{
/*-- 文字: 5 --*/
/*-- 宋体18; 此字体下对应的点阵为:宽x高=12x24 --*/
0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x30,0x3F,0x3F,
0x18,0x08,0x08,0x18,0xF8,0xF0,0xE0,0x00,0x00,0x0F,0x0F,0x1F,0x10,0x10,0x10,0x18,
0x1F,0x0F,0x07,0x00,
},
{
/*-- 文字: 6 --*/
/*-- 宋体18; 此字体下对应的点阵为:宽x高=12x24 --*/
0x00,0x00,0x80,0xC0,0xE0,0x60,0x20,0xE0,0xE0,0xE0,0x00,0x00,0xF8,0xFF,0xFF,0xFF,
0x18,0x08,0x08,0x18,0xF8,0xF0,0xE0,0x00,0x00,0x07,0x0F,0x1F,0x18,0x10,0x10,0x18,
0x1F,0x0F,0x07,0x00,
},
{
/*-- 文字: 7 --*/
/*-- 宋体18; 此字体下对应的点阵为:宽x高=12x24 --*/
0x00,0xE0,0xE0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xE0,0x60,0x00,0x00,0x03,0x03,0x00,
0x80,0xE0,0xF8,0x3E,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F,0x00,
0x00,0x00,0x00,0x00,
},
{
/*-- 文字: 8 --*/
/*-- 宋体18; 此字体下对应的点阵为:宽x高=12x24 --*/
0x00,0x80,0xC0,0xE0,0x60,0x20,0x20,0x60,0xE0,0xC0,0x80,0x00,0x00,0xC7,0xEF,0x7F,
0x3C,0x38,0x30,0x78,0xFF,0xEF,0xC7,0x00,0x03,0x0F,0x0F,0x1C,0x18,0x10,0x10,0x18,
0x1F,0x0F,0x07,0x00,
},
{
/*-- 文字: 9 --*/
/*-- 宋体18; 此字体下对应的点阵为:宽x高=12x24 --*/
0x00,0x80,0xC0,0xE0,0x60,0x20,0x20,0x60,0xE0,0xC0,0x80,0x00,0x0E,0x3F,0x7F,0x7F,
0x60,0x40,0x60,0x60,0xFF,0xFF,0xFF,0x00,0x00,0x0C,0x1C,0x1C,0x1C,0x10,0x18,0x1E,
0x0F,0x07,0x01,0x00,
}
};
/****************************************************************************
函数功能:延时程序
入口参数:t
出口参数:
****************************************************************************/
void LCDdelay(unsigned int t)
{
unsigned int i,j;
for(i=0;i<t;i++);
for(j=0;j<10;j++);
}
/****************************************************************************
状态检查,LCD是否忙
*****************************************************************************/
void CheckState()
{
unsigned char dat,DATA;//状态信息(判断是否忙)
LCDDi=0; // 数据\指令选择,D/I(RS)=“L” ,表示 DB7∽DB0 为显示指令数据
LCDRW=1; //R/W=“H” ,E=“H”数据被读到DB7∽DB0
do{
DATA=0x00;
LCDEnable=1; //EN下降源
LCDdelay(2);//延时
dat=DATA;
LCDEnable=0;
dat=0x80 & dat; //仅当第7位为0时才可操作(判别busy信号)
}while(!(dat==0x00));
}
/*****************************************************************************
函数功能:写命令到LCD程序
入口参数:cmdcode
出口参数:
*****************************************************************************/
void write_com(unsigned char cmdcode)
{
CheckState();//检测LCD是否忙
LCDDi=0;
LCDRW=0;
P0=cmdcode;
LCDdelay(2);
LCDEnable=1;
LCDdelay(2);
LCDEnable=0;
}
/*****************************************************************************
函数功能:写数据到LCD程序
入口参数:LCDDispdata
出口参数:
*****************************************************************************/
void write_data(unsigned char LCDDispdata)
{
CheckState();//检测LCD是否忙
LCDDi=1;
LCDRW=0;
P0=LCDDispdata;
LCDdelay(2);
LCDEnable=1;
LCDdelay(2);
LCDEnable=0;
}
/*****************************************************************************
函数功能:清除LCD内存程序
入口参数:pag,col,hzk
出口参数:
*****************************************************************************/
void Clr_Scr()
{
unsigned char j,k;
LCDMcs=1;LCDScs=1;//我的液晶屏用这样才能清屏
//LCDMcs=0;LCDScs=0;//仿真软件里proteus里面的屏要这样才能清屏
write_com(Page_Add+0);
write_com(LCDCol_Add+0);
for(k=0;k<8;k++)//控制页数0-7,共8页
{
write_com(Page_Add+k);
for(j=0;j<64;j++)
{
write_com(LCDCol_Add+j);
write_data(0x00);//控制列数0-63,共64列,写点内容,列地址自动加1
}
}
LCDMcs=0;LCDScs=0;
}
/*****************************************************************************
函数功能:指定位置显示数字12*24程序
入口参数:pag,col,hzk
出口参数:
*****************************************************************************/
void hz_LCDDisp12(unsigned char pag,unsigned char col, unsigned char code *hzk)
{
unsigned char j=0,i=0;
for(j=0;j<3;j++)
{
write_com(Page_Add+pag+j);
write_com(LCDCol_Add+col);
for(i=0;i<12;i++)
write_data(hzk[12*j+i]);
}
}
/*****************************************************************************
函数功能:LCD初始化程序
入口参数:
出口参数:
*****************************************************************************/
void init_lcd()
{
LCDdelay(100);
LCDMcs=1;
LCDScs=1;
LCDdelay(100);
write_com(LCDLCDDisp_Off);
write_com(Page_Add+0);
write_com(Start_Line+0);
write_com(LCDCol_Add+0);
write_com(LCDLCDDisp_On);
}
/*****************************************************************************
函数功能:主程序
入口参数:
出口参数:
*****************************************************************************/
void main(void)
{
LCLight=0; //开LCD背光
init_lcd();
Clr_Scr();
LCDMcs=1;LCDScs=0; //左、右都显示
TimerInit();
while(1)
{
if((rev_stop==1)&&(buf[5]=='C'))//如果接收到GPRMC
{
if(buf[18]=='A')//如果GPS成功定位
ES=0;
shi= (buf [7]-0x30)* 16+ (buf[8] -0x30);
fen= (buf [9]-0x30)* 16+ (buf[10]-0x30);
miao= (buf[11]-0x30)* 16+ (buf[12]-0x30);
shi= shi / 16 * 10 + shi % 16;
LED1=0;
shi= (shi+8) % 24; //UTC Time换算成北京时间
shi=shi/10*16+shi%10;
ES=1;
rev_stop=0;
}
LCDMcs=1;LCDScs=0; //左显示
LCDdelay(2);
//时间
hz_LCDDisp12(2,16,shk[shi/10]);
hz_LCDDisp12(2,28,shk[shi%10]);
hz_LCDDisp12(2,40,shmaohao);
hz_LCDDisp12(2,52,shk[fen/10]);
LCDMcs=0;LCDScs=1; //右显示
LCDdelay(2);
//时间
hz_LCDDisp12(2,0,shk[fen%10]);
hz_LCDDisp12(2,12,shmaohao);
hz_LCDDisp12(2,24,shk[miao/10]);
hz_LCDDisp12(2,36,shk[miao%10]);
}
}
/***************************************************************/
/*************************串口数据接收**************************/
/***************************************************************/
void Uart_Receive(void) interrupt 4
{
unsigned char ch,num;
ES = 0;
if (RI) //如果接收完成则进入
{
ch = SBUF;
if (ch == '$') //如果收到字符'$',便开始接收
{
rev_start = 1;
rev_stop = 0; //接收停止标志
}
if (rev_start == 1) //标志位为1,开始接收
{
LED=0;
buf[num++] = ch; //字符存到数组中
if (ch == '\n') //如果接收到换行
{
buf[num] = '\n';
rev_start = 0;
rev_stop = 1; //接收停止标志
num = 0;
LED=0;
}
}
}
RI = 0; //RI清0,重新接收
ES = 1; //串口1中断允许
}
|
|