专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

GPS时钟51单片机程序

作者:antlu   来源:本站原创   点击数:  更新时间:2014年07月31日   【字体:

  网上看到的GPS时钟程序,特此收藏,给广大电子制作爱好者参考。GPS时钟,硬件非常简单,程序也算是不太高深,不需要按鍵,不用 DS1302 IC,只要了一个GPS模块,好处是不需要调整時间,只要有卫星信号就核对时间。

 

// 作者:antlu

#include<reg52.h>
#define DataPort P0 // display LED segment
#define DrivePort P2 //display LED digit
//sbit Gok_LED =P1^2;// 收到"$GPRMC,"送出LED
bit disp_flag;
bit rec;  // receive rs232 OK_flag
void DelayUs2x(unsigned char t);//us?延?函??明
void DelayMs(unsigned char t); //ms?延?
void Display(unsigned char n,unsigned char Num);// 把七段顯示出去
unsigned char code  segment[10]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// VFD
unsigned char code grid[4]={ 0x01,0x02,0x04,0x08 };
// 10H H 10m m, 位碼3>>分, 位碼2>>10分,位碼1>>時, 位碼0>>10時,
unsigned char TempData[4];
//,把段碼的資料存到要顯示的緩衝器上面,利用類似查表的對應方式,送出至顯示器. TempData[ ] 是放置要顯示的7段資料
unsigned char CLCK[6];
//void Display(char n,char Num);
unsigned char count;
void Display_Data_Operation(void)//以時間分秒為共同語言, 數字轉換成7段顯示
{
   TempData[3]= segment[CLCK[0]];//?
   // if (CLCK[2]==0)
   //  TempData[3]=0;
   TempData[2]= segment[CLCK[1]];//
   TempData[1]= segment[CLCK[2]]; //分
   TempData[0]= segment[CLCK[3]];//
   //Display(0,4);   
}   
//--------------------------------------------------------------------------------------------
void Display(unsigned char n,unsigned char Num)// 把七段顯示出去
{
   unsigned char i;
   n=0;//已經沒有用了,但先前程式設計關係還是把他設為0
   for(i=0;i
   {
      DataPort= TempData; //
      DrivePort= grid;      
      DelayMs(5); //0908 update 因閃爍把20改成10 >>5>>2
   }
}
void DelayUs2x(unsigned char t)
{  
   while(--t);
}
void DelayMs(unsigned char t)
{
    while(t--)
    {
       //大致延?1mS
       DelayUs2x(245);
       DelayUs2x(245);
    }
}
///////////////FROM GPS ///////////////////////////////////////////////////
unsigned char Gok;// "$GPRMC," 確認完成
unsigned char REV_DATA;//儲存RS232緩衝區的暫存變數
void Init_Timer0(void);//定?器初始化
//----- FROM GPS PROG -----
void Init_Timer0(void)
{
    TMOD |= 0x01;      //使用模式1,16位定?器,使用"|"符?可以在使用多?定?器?不受影?            
    EA=1;            //?中?打?
    ET0=1;           //定?器中?打?
    TR0=1;           //定?器??打?
}
void Timer0_isr(void) interrupt 1
{
    // static unsigned int count;
    TH0=(65536-2010)/256;          //重新?值 2ms
    TL0=(65536-2010)%6;
    count++;
    if (count==10)
    {
       count=0;
       disp_flag=1;
    }
}
void UART_Init(void)
{
    SCON  = 0x50;                // SCON: 模式 1, 8-bit UART, 使能接收 
    TMOD |= 0x20;               // TMOD: timer 1, mode 2, 8-bit 重?
    TH1   = 0xFA;               // TH1:  重?值 4800 11.0592MHz 
    TR1   = 1;                  // TR1:  timer 1 打?                        
    EA    = 1;                  //打??中?
    ES    = 1;                  //打?串口中?
}
void UART_SER (void) interrupt 4 //來自串口時鐘 1602 程式
{
     if(RI)                        //判?是接收中??生
     {
      RI=0;                      //?志位清零
      REV_DATA =SBUF;                 //?入???的值
      rec=1;
     //rec_led=1;
     }
     if(TI)  //如果是?送?志位,清零
     TI=0;
}
unsigned char GPRMC_K(void)//比較 $GPRMC
{
    unsigned char TT;//轉換用
    while(rec==0);
    if(rec==1)
    if(REV_DATA == 'G')//一路比較下去全部要相同 "GPRMC,"
    rec=0;
    else
    return 0;
    while(rec==0);       
    if(rec==1)        
    if(REV_DATA == 'P')          
    rec=0;   
    while(rec==0);       
    if(rec==1)        
    if(REV_DATA == 'R')//一路比較下去全部要相同 "GPRMC,"          
    rec=0;        
    else
    return 0;        
    while(rec==0);       
    if(rec==1)        
    if(REV_DATA == 'M')//一路比較下去全部要相同 "GPRMC,"          
    rec=0;   
    while(rec==0);       
    if(rec==1)        
    if(REV_DATA == 'C')//一路比較下去全部要相同 "GPRMC,"          
    rec=0;
    while(rec==0);    
    if(rec==1)    
    if(REV_DATA == ',')//一路比較下去全部要相同 "GPRMC,"
    rec=0;
    else
    return 0;
    while(rec==0);      
    if(rec==1)                
    CLCK[0]=REV_DATA-0x30;//10hr
    rec=0;                    
    while(rec==0);      
    if(rec==1)                
    CLCK[1]=REV_DATA-0x30;//1hr
    rec=0;                  
    while(rec==0);      
    if(rec==1)                
    CLCK[2]=REV_DATA-0x30;//10min
    rec=0;                  
    while(rec==0);       
    if(rec==1)                
    CLCK[3]=REV_DATA-0x30;//1min
    rec=0;         
    while(rec==0);       
    if(rec==1)                
    CLCK[4]=REV_DATA-0x30;//10sec
    rec=0;         
    while(rec==0);       
    if(rec==1)                
    CLCK[5]=REV_DATA-0x30;//sec        
    TT=CLCK[0]*10+CLCK[1]+8;
    if(TT>23)
    TT-=24;
    CLCK[0]=TT/10;
    CLCK[1]=TT;
    return 1;
}
void Get_Gps(void)
{
    if(rec==1)
    {
       rec=0;//清除授信旗標
       if(REV_DATA == '$')
       {
          Gok=GPRMC_K();//確認收到 "GPRMC," 字元
       }
    }
}
// ---------  GPS MAIN PROGRAM -------------
void main(void)
{
    Init_Timer0();
    UART_Init();
    while(1)
    {
        Get_Gps();
        if(Gok==1)
        {
           Display_Data_Operation ();//轉換相關值到顯示
        }
 if(disp_flag==1)
        {
           disp_flag=0;
           Display(0,4);
        }
        Display(0,4);
    }
}
关闭窗口

相关文章