|
本帖最后由 fang3 于 2013-2-5 23:44 编辑
这GPS模块买了好久了,一直没空做 ,模块是自动每秒钟发送一次数据的,编程相对简单了,就是判断关键字接收时间,因为赶着做,没来得及加时钟芯片,其实也没必要加时钟芯片,用软件计时可以了,设一个小时自动校一次时足够了,钟非常简单,连个校时按键都没有,收到卫星信号就可以了,数码管1.8寸的四位,要用到ULN2003驱动了,STC12C1052+74164+uc2003驱动1.8寸双色数码管程序是自编的
三星的GPS模块哦
基本的线路图
成品后的样子
GPS数码管四位电子钟.rar
(2.07 KB, 下载次数: 694)
源代码
程序全贴出
;12C1052+74164+UC2003驱动1.8寸数码管四位电子钟
;11.592M晶振;GPS模块接在P3.0 P3.1
;***************************************
LEDR1 BIT P1.4;时十位
LEDR2 BIT P1.5;时个位
LEDR3 BIT P1.6;分十位
LEDR4 BIT P1.7;分个位
HOU EQU 62H;时
MIN EQU 61H;分
SEC EQU 60H;秒
IO BIT P3.4;74HC164数据口
SCK BIT P3.3;74HC164时钟线
ORG 0H
AJMP START
ORG 0BH
AJMP INT_T0 ;T0中断
ORG 23H;;串行中断
LJMP GPS
ORG 30H
START:
MOV P1,#0;
MOV P3,#0FFH
MOV DPTR,#TAB
;***************
;初始化串口波特率4800,允计接收
MOV SCON,#50H;
MOV TMOD,#21H;
MOV TH1,#0FAH;
MOV TL1,#0FAH
SETB TR1
SETB ES
;***************
MOV TH0,#4CH;定时器0 50ms
MOV TL0,#0
SETB TR0
SETB ET0
SETB EA
;*******************
MAIN:
ACALL DISPLAY
AJMP MAIN
;;;;;;;;;;;;;;;;;;;;;;
;**************************
DISPLAY:;显示
MOV DPTR,#TAB
MOV A,HOU;时十位
MOV B,#10
DIV AB
MOVC A,@A+DPTR
CALL HC164
SETB LEDR1
CALL DELAY1MS
CLR LEDR1
;----------------
MOV A,B
MOVC A,@A+DPTR
mov c,0ah;秒点闪烁
mov acc.7,c
CALL HC164;时个位
SETB LEDR2
CALL DELAY1MS
CLR LEDR2
;**************************
MOV DPTR,#TAB2;倒转数码管
MOV A,MIN;分十位
MOV B,#10
DIV AB
MOVC A,@A+DPTR
mov c,0ah;秒点闪烁
mov acc.7,c
CALL HC164
SETB LEDR3
CALL DELAY1MS
CLR LEDR3
;----------------
MOV DPTR,#TAB
MOV A,B
MOVC A,@A+DPTR
CALL HC164;分个位
SETB LEDR4
CALL DELAY1MS
CLR LEDR4
RET
;**************************
HC164:;164串行发送
MOV R2,#8
NEXTB:
RLC A
MOV IO,C
SETB SCK
CLR SCK
DJNZ R2,NEXTB
RET
;****************;****************;****************
INT_T0:
PUSH ACC ;定时器0中断计时
PUSH PSW
MOV TH0,#4CH;50MS
MOV TL0,#0
INC 30H
MOV A,30H
CJNE A,#10,T0_OUT;
MOV 30H,#0
CPL 0AH;每0.5秒取反显示位
INC 31H
MOV A,31H
CJNE A,#2,T0_OUT;500MS*2=1S
MOV 31H,#0
INC SEC;秒加一
MOV A,SEC
CJNE A,#60,T0_OUT
MOV SEC,#0
INC MIN;分加一
MOV A,MIN
CJNE A,#60,T0_OUT
MOV MIN,#0
SETB ES;打开串行中断,GPS校时
INC HOU;时加一
MOV A,HOU
CJNE A,#24,T0_OUT
MOV HOU,#0
T0_OUT:
POP PSW
POP ACC
RETI
;****************;****************;****************
DELAY1MS: ;延时
MOV R6,#12H
DL0:
MOV R5,#98H
DJNZ R5,$
DJNZ R6,DL0
NOP
RET
;****************;****************;****************
TABGPRMC: DB "$GPRMC,"
;****************;****************;****************
;-------串行口中断
;接收到$GPRMC, 后面的是时分秒数据ANSI格式的
;*********************;****************
GPS:;$GPRMC
CLR ES;关串行中断,避免反复中断,下面接收用查询
PUSH ACC;保护
PUSH DPH
PUSH DPL
MOV DPTR,#TABGPRMC;$GPRMC的数据指针
MOV R2,#0;
;**********************
GPRMC:;接收比较是否是收到“$GPRMC,”
JNB RI,$
CLR RI
MOV A,R2
MOVC A,@A+DPTR
CJNE A,SBUF,OUT
INC R2;下一个数据
CJNE R2,#7,GPRMC;校对完7个数据
;**********************
MOV R0,#40H;保存地址指针
MOV R1,#6;时分秒6个ANSI码数据
GET_GPS:
JNB RI,$
CLR RI
MOV A,SBUF
SUBB A,#30H;ANSI减30H是16进制数
MOV @R0,A
INC R0;下一内存
DJNZ R1,GET_GPS
;**********************
MOV R1,#5;跳过5个数分别为“. 毫秒3个数 ,”
GE:
JNB RI,$
CLR RI
DJNZ R1,GE
;**********************
JNB RI,$
CLR RI
MOV A,SBUF
CJNE A,#'A',OUT;接收到A是数据有效
;---------------
;处理数据,把6位数合成时分秒三位数
MOV R0,#40H
MOV R1,#62H
ZLGO:
MOV A,@R0
MOV B,#10
MUL AB
INC R0
ADD A,@R0
MOV @R1,A
INC R0
DEC R1
CJNE R0,#46H,ZLGO
;----------------
;收到的是伦敦时间,北京东8区 +8小时
mov a,hou
add a,#8;
cjne a,#24,jj;是否大于24小时
jj:jc xy
subb a,#24;大于24减24
xy:
mov hou,a;保存成北京时间
POP DPL
POP DPH
POP ACC
CLR ES;关闭串行中断
RETI
;****************;****************
OUT:
POP DPL
POP DPH
POP ACC
SETB ES;打开串行中断
RETI
TAB: DB 7EH,18H,6DH,3DH,1BH,37H,77H,1CH,7FH,3FH,5FH,73H,66H,79H,67H,47H
DB 1H,25H;-+
TAB2B 7EH,42H,6DH,67H,53H,37H;倒装数码管
这是C语言的,我译过来,不知道语法对不对?
#include <reg52.H> //头文件包含
#define uchar unsigned char //宏定义
#define uint unsigned int
sbit MIAO =P3^7; //秒点 ,数码管第二位小数点,可以自己随意定义.
sbit HOU_S=P1^4; //时十位位选
sbit HOU_G=P1^5; //时个位位选
sbit MIN_S=P1^6; //分十位位选
sbit MIN_G=P1^7; //分个位位选
sbit io=P3^4;
sbit SCK=P3^3;
bit SHAN; //闪烁标志位
uchar sec,min,hou; //定义秒、分、时寄存器
uchar code LEDTab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数码管段码表0--9码
uchar code GPRMC[]={"$GPRMC,"};
uchar Get_Gps();
void delay(uchar t); //延时函数
void init(); //初始化函数
void display(); //显示函数
/***************************************
函 数 名:main
功 能:主函数
说 明:
入口参数:无
返 回 值:无
****************************************/
void main()
{
init(); //调用初始化函数
display(); //调用显示函数
}
}
/***************************************
函 数 名:init
功 能:;初始化串口波特率4800
说 明:初始化定时器及中断
入口参数:无
返 回 值:无
***************************************/
void init()
{
TMOD=0X21;TH0=0X4C;TL0=0;SCON=0x50; //定时器0模式1,50毫秒
TH0=0Xfa;TL0=0Xfa;
ET0=1;TR0=1;TR1=1;ES=1;EA=1; //开定时器0中断、启动定时器0、开总中断
}
void HC164(uchar dat)//:;164串行发送
{
uchar i;
for (i=0; i<8; i++) //8位计数器
{
dat <<= 1; //移出数据的最高位
io = CY; //送数据口
SCK = 1; //拉高时钟线
SCK = 0; //拉低时钟线
}
}
/***************************************
函 数 名:display
功 能:显示函数
说 明:
入口参数:无
返 回 值:无
***************************************/
void display()
{
HC164(LEDTab[min%10]); //分个位送数码管显示
MIN_G=0; //打开分个位位选
delay(1); //显示1毫秒
MIN_G=1; //关闭分个位位选
HC164(LEDTab[min/10]); //分十位送数码管显示
MIN_S=0; //打开分十位位选
delay(1); //显示1毫秒
MIN_S=1; //关闭分十位位选
HC164(LEDTab[hou%10]); //时个位送数码管显示
HOU_G=0; //打开时个位位选
delay(1); //显示1毫秒
HOU_G=1; //关闭时个位位选
HC164(LEDTab[hou/10]); //时十位送数码管显示
HOU_S=0; //打开时十位位选
delay(1); //显示1毫秒
HOU_S=1; //关闭时十位位选
}
/***************************************
函 数 名:delay
功 能:延时函数
说 明:
入口参数:t:延时时间长短
返 回 值:无
***************************************/
void delay(uchar t)
{
uchar i; //定义变量
for(;t>0;t--) //如果t大于0,t减1(外层循环)
for(i=124;i>0;i--); //i等于124,如果i大于0,i减1
}
/***************************************
函 数 名:timer0
功 能:定时器0中断函数
说 明:
入口参数:无
返 回 值:无
***************************************/
void timer0() interrupt 1 //定时器0(中断1)
{
uchar tim1,tim2; //定义临时变量
TL0=0;TH0=0X4C; //重装定时器初值
tim1++; //每中断一次tim1加1
if(tim1==10) //中断10(0.5秒)
{
SHAN=!SHAN; //闪烁标志取反
tim1=0;tim2++; //tim1清零,tim2加1
if(tim2==2) //到了1秒
{
tim2=0;sec++; //tim2清零,秒加1
if(sec==60) //如果秒到60
{
sec=0;min++; //秒变0,分加1
if(min==60) //如果分到60
{ ES=1
min=0;hou++; //分变0,时加1
if(hou==24) hou=0; //如果时到24,时变0
}
}
}
}
}
/***************************************
***************************************/
void timer0() interrupt 4 //(中断4)
{
uchar *p,i;
ES=0;
if (Get_Gps())//;接收比较是否是收到$GPRMC,
{
ES=1;
return;
}
else
*p=0x40
for(i=0;i<6;i++)//读取当前时间
{
while (!RI);
RI=0;
*p = SBUF-0X30;//ANSI减30H是16进制数
*p++;
}
for(i=0;i<5;i++)//跳过5个数分别为. 毫秒3个数 ,
{
while (!RI);
RI=0;
}
while (!RI);
RI=0;
if (SBUF!='A')//接收到A是数据有效
{
ES=1;
return;
}
else
*p=0x40;
hou=(*p)*10;//;处理数据,把6位数合成时分秒三位数
*p++;
hou=*p+hou;
*p++;
min=(*p)*10;
*p++;
min=*p+min;
*p++;
sec=(*p)*10;
*p++;
sec=*p+sec;
hou=hou+8;//收到的是伦敦时间,北京东8区 +8小时
if (hou<24)
return;
else
hou=hou-24;//保存成北京时间
}
;------------------------------
unsigned char Get_Gps()//;接收比较是否是收到“$GPRMC,”
{
for(i=0;i<7;i++)
{
while (!RI);
RI=0;
if(SBUF == GPRMC);
else
return 1;
}
return 0;
}
|
评分
-
2
查看全部评分
-
|