| 
 | 
 
 樓主 |
發表於 2012-8-19 23:03:13
|
顯示全部樓層
 
 
 
 更新 latch 版本 可以顯示 時 分 秒  在50~59秒時顯示 月 日 年,有興趣的請笑納!! 
 
 
//20120808 modify OK  while(rec==0); 等待直到1才跳離 實驗板電路 ,7段顯示用  
 
#include<reg52.h> 
#define DataPort P0 // display LED segment 
#define DrivePort P1 //display LED digit  
//unsigned char code GPS_ASC[]="GPRMC,"; 
unsigned char CLCK[6];//時分秒存放={1,2,3,4,5,6} 
unsigned char YMD[6]={1,2,0,8,1,9};//年月日存放  
unsigned char Gok;// "$GPRMC," 確認完成 
sbit Gok_LED =P1^2;// 收到"$GPRMC,"送出LED 
sbit rec_led =P1^3; 
bit rec;  // receive rs232 OK_flag 
unsigned char REV_DATA;//儲存RS232緩衝區的暫存變數 
void Init_Timer0(void);//定时器初始化 
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换 
sbit LATCH1=P2^2;//定义锁存使能端口 段锁存 
sbit LATCH2=P2^3;//                 位锁存 
 
unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9 
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码 
unsigned char TempData[8]; //存储显示值的全局变量 
void CLCKFL(unsigned char CLCKCT);//簡化時分秒的儲存程式 
void JPDM(unsigned char DM);//跳過幾個',"號 
 
 
void Display(unsigned char FirstBit,unsigned char Num) 
{ 
      static unsigned char i=0; 
           
 
           DataPort=0;   //清空数据,防止有交替重影 
       LATCH1=1;     //段锁存 
       LATCH1=0; 
 
       DataPort=dofly_WeiMa[i+FirstBit]; //取位码  
       LATCH2=1;     //位锁存 
       LATCH2=0; 
 
       DataPort=TempData[i]; //取显示数据,段码 
       LATCH1=1;     //段锁存 
       LATCH1=0; 
        
           i++; 
       if(i==Num) 
              i=0; 
 
 
} 
 
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;//0xd8;                  //重新赋值 2ms 
 TL0=(65536-2010)%256; //0xf0; 
 
    Display(0,6); 
    
} 
 
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; 
} 
 
void CLCKFL(unsigned char CLCKCT) 
{ 
  unsigned char ct=0; 
  rec=0;//必要的 
   while(CLCKCT>ct)//儲存數量 
   { 
    while(rec==0); 
        if(rec==1) 
         { 
          CLCK[ct]=REV_DATA-0x30; 
      rec=0; 
          ct++; 
          } 
        } 
 } 
 
//0819 填入6個年月日資料 
void YMDFL(unsigned char YMDCT) 
{ 
  unsigned char yt=0; 
  rec=0;//必要的 
   while(YMDCT>yt)//儲存數量 
   { 
    while(rec==0); 
        if(rec==1) 
         { 
          YMD[yt]=REV_DATA-0x30; 
      rec=0; 
          yt++; 
          } 
        } 
 } 
 
 //--------------------------- 
 
 
 
//0819 跳過幾個逗號 
 
void JPDM(unsigned char DM) 
{ 
 // unsigned char dmt=0; 
  rec=0; 
  while(DM)//>dmt 
   { 
    while(rec==0); 
        if (rec==1) 
         { 
     if(REV_DATA == ',') 
         { 
         rec=0; 
         DM--;//dmt++ 
         } 
         } 
   } 
} 
 
 
 
//------------------- 
 
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; 
 
    CLCKFL(6);//取 時分秒 
    JPDM(8);//跳過8個逗號 
        YMDFL(6);//取 年月日 
 
  TT=CLCK[0]*10+CLCK[1]+8; 
  if(TT>23) 
     TT-=24; 
         CLCK[0]=TT/10; 
         CLCK[1]=TT%10; 
    
 
 
  return 1; 
  } 
 
 
 
void Get_Gps(void) 
{ 
if(rec==1) 
  { 
    rec=0;//清除授信旗標 
    if(REV_DATA == '$') 
     { 
          Gok=GPRMC_K();//確認收到 "GPRMC," 字元 
      } 
    } 
  } 
 
 
void Dis_tr(void)//轉換相關值到顯示 
{ 
 unsigned j; 
for(j=0;j<6;j++) 
  { 
   if(CLCK[4]==5)//50~59秒顯示年 月 日 
   TempData[j]=dofly_DuanMa[YMD[j]];//CLCK 
   else 
   TempData[j]=dofly_DuanMa[CLCK[j]];// 
  } 
 } 
 
 
void main(void) 
{ 
 Init_Timer0(); 
 UART_Init(); 
 while(1) 
 { 
 Get_Gps(); 
  if(Gok==1) 
      { 
     Dis_tr();//轉換相關值到顯示 
           }  
 
  } 
 } 
 |   
 
 
 
 |