|
發表於 2012-8-12 21:26:48
|
顯示全部樓層
把先前的小綠人時鐘改為GPS時鐘,卻發現問題很多,一直顯示不出來,要不就是閃爍厲害,實驗版的電路是用 74573 使用LATCH 方式用中断方式把他顯示出來,而小綠人則利用一般的定時分工驅動,也因為如此導致 GPS信號讀取時間不足而無法顯示,這正應驗了 LEGION大的"預言"....
//小綠人時鐘改為gps 時鐘 20120812
#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<Num;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)%256;
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%10;
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);
}
}
後續的玩具會利用 74595 驅動 點陣LED 目前 部分線路先做出來,接下來就是 控制驅動電路,最後則是 修改程式把跑馬燈的程式修改給 GPS點陣時鐘使用...
|
|