矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 12993|回复: 40

【参赛】做只简单的GPS时钟

   关闭 [复制链接]
发表于 2013-2-5 10:34:52 | 显示全部楼层 |阅读模式
本帖最后由 fang3 于 2013-2-5 23:44 编辑

这GPS模块买了好久了,一直没空做 ,模块是自动每秒钟发送一次数据的,编程相对简单了,就是判断关键字接收时间,因为赶着做,没来得及加时钟芯片,其实也没必要加时钟芯片,用软件计时可以了,设一个小时自动校一次时足够了,钟非常简单,连个校时按键都没有,收到卫星信号就可以了,数码管1.8寸的四位,要用到ULN2003驱动了,STC12C1052+74164+uc2003驱动1.8寸双色数码管程序是自编的
108_541075_906916468d05a46.jpg 108_541075_40088cd45c9734d.jpg 三星的GPS模块哦

108_541075_851e255958523b2.jpg 基本的线路图

108_541075_8d836c8896ffd3f.jpg 108_541075_146f92b51c92251.jpg 108_541075_d51e0838b108803.jpg 成品后的样子

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

查看全部评分

     
发表于 2013-2-5 10:59:26 | 显示全部楼层
      做的真不错,能显示年月日吗?
回复 支持 反对

使用道具 举报

     
发表于 2013-2-5 11:06:24 | 显示全部楼层
那本英汉小词典我有,99年版。
回复 支持 反对

使用道具 举报

     
发表于 2013-2-5 11:18:00 来自手机 | 显示全部楼层
看程序里貌似没有年月的,不过这玩意不用校时,很准的计时器,希望兄弟能获奖哦,不错
回复 支持 反对

使用道具 举报

     
发表于 2013-2-5 11:49:21 | 显示全部楼层
这个做的真好。
回复 支持 反对

使用道具 举报

发表于 2013-2-5 14:44:04 | 显示全部楼层
做的太好啦 走的准么?
回复 支持 反对

使用道具 举报

发表于 2013-2-5 17:02:23 | 显示全部楼层
高手,做的不错
回复 支持 反对

使用道具 举报

     
发表于 2013-2-11 10:05:03 | 显示全部楼层
做的不错啊
回复 支持 反对

使用道具 举报

发表于 2013-2-11 10:34:11 | 显示全部楼层
真不错呀,不用担心校对时间的事情。
回复 支持 反对

使用道具 举报

发表于 2013-2-25 00:24:20 | 显示全部楼层
建议美化一下,东西很不错,成本低,时间就是高精度原子时,以后上学不怕迟到了…
回复 支持 反对

使用道具 举报

     
发表于 2013-2-25 08:40:21 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

     
发表于 2013-2-25 21:59:54 | 显示全部楼层
太好了,我决定投你一票。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-3-3 00:21:49 | 显示全部楼层
请大家投下神圣的一票!!!您的选择就是我努力的动力
回复 支持 反对

使用道具 举报

     
发表于 2013-3-3 07:15:23 来自手机 | 显示全部楼层
怎么投票 我要投你一票
回复 支持 反对

使用道具 举报

     
发表于 2013-3-10 00:36:08 | 显示全部楼层
电子马甲 发表于 2013-3-3 07:15
怎么投票 我要投你一票

好像要银牌才能投票的哦,这样的话,好多弟兄都没资格了,也好,一定程度上杜绝马甲自投
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-4-29 22:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表