利用中午午休的一些零星時(shí)間設(shè)計(jì)制作了一款1.8寸GPS授時(shí)時(shí)鐘,現(xiàn)將自己的制作過(guò)程和經(jīng)驗(yàn)教訓(xùn)寫(xiě)下來(lái)和大家分享和共同學(xué)習(xí)。
提到GPS,大家現(xiàn)在都在使用智能手機(jī),很快就想到了GPS定位、導(dǎo)航等功能。沒(méi)錯(cuò),GPS系統(tǒng)隨著科技的進(jìn)步已經(jīng)走到了你的身邊,并不是想象中的那么神秘。其實(shí)GPS收到衛(wèi)星型號(hào)后會(huì)接收到相當(dāng)多的衛(wèi)星定位信息,比如:日期、時(shí)間、坐標(biāo)經(jīng)緯度、海拔高度等等數(shù)據(jù)。本時(shí)鐘就是利用GPS模塊配合GPS天線收到GPS衛(wèi)星信息獲取其中的時(shí)間數(shù)據(jù)來(lái)校正和顯示當(dāng)前精準(zhǔn)的時(shí)間。
優(yōu)良的GPS模塊當(dāng)然價(jià)格也不菲,往往售價(jià)都在幾百元,現(xiàn)在網(wǎng)上淘得幾元錢(qián)一個(gè)的二手GPS模塊也是相當(dāng)?shù)牟诲e(cuò)了,本時(shí)鐘選用了價(jià)格便宜的Ublox LEA-4A GPS模塊,還有GPS天線。GPS模塊和天線都是51hei提供的.

本作一物多用的原則,制作前考慮到使用4個(gè)1.8寸數(shù)碼管共陽(yáng)紅(外型尺寸38x56MM),使用5V電源不能夠驅(qū)動(dòng)點(diǎn)亮數(shù)碼管,需要9V至12V的電源,但又不想使用專(zhuān)用的電源接口和電源,考慮到通用性,固將電源接口采用MicroUSB接口(也就是平時(shí)智能手機(jī)常用的充電和數(shù)據(jù)線接口),電源也可使用手機(jī)的充電電源,方便靈活又不需專(zhuān)門(mén)配備電源,由于Ublox LEA系列的GPS模塊自帶有USB接口,即可將模塊中的USB引腳接入到這個(gè)MicroUSB電源接口上,這樣就可以將本時(shí)鐘作為具有USB接口的外部GPS模塊和電腦PC想連接,使用專(zhuān)門(mén)的GPS驅(qū)動(dòng)和軟件,就可以在PC機(jī)上使用定位導(dǎo)航功能了,比如谷歌地球、高明的地圖軟件。另外可以將本時(shí)鐘添加一些常用的單元部分進(jìn)行功能擴(kuò)展,讓其成為一個(gè)多用途的1.8寸顯示的C51單片機(jī)實(shí)驗(yàn)和學(xué)習(xí)板,增加了可玩性。加入的單元部分有:1. C51-ISP編程接口(可以通過(guò)該接口方便的編程單片機(jī)程序);2. DS18B20溫度集成(可以通過(guò)該探頭獲取環(huán)境溫度)3. 4個(gè)按鍵(可以根據(jù)需要編寫(xiě)具有按鍵功能的時(shí)鐘)4. VS1838紅外接收頭(可以通過(guò)編程加入紅外遙控功能)5. 24C02存儲(chǔ)芯片(可以編寫(xiě)一些具有存儲(chǔ)功能的程序)6. DS1302時(shí)鐘芯片(可以編寫(xiě)時(shí)鐘程序)7. 蜂鳴器(可以編寫(xiě)鬧鐘和一些聲響的程序)8. XL6009升壓模塊(可以通過(guò)電位器調(diào)節(jié)數(shù)碼管的亮度)9. GPS模塊的MicroUSB接口(可以通過(guò)手機(jī)數(shù)據(jù)線作為電源或和PC機(jī)聯(lián)機(jī)成為外部GPS模塊) 電路圖設(shè)計(jì)如下: PCB板背面圖

PCB板正面圖

原理圖和PCB板圖均使用Altium Designer 14軟件進(jìn)行設(shè)計(jì),在使用Altium Designer14設(shè)計(jì)時(shí)也是不斷學(xué)習(xí)的一個(gè)過(guò)程,元件圖庫(kù)、PCB元件封裝庫(kù)、3D元件庫(kù)、布局、排版等,有時(shí)一個(gè)元件的繪制都會(huì)花去你很多時(shí)間,很多元件都是我自己拿著元件測(cè)量尺寸和參照網(wǎng)上的封裝圖來(lái)手繪,還是很辛苦的。為了學(xué)習(xí),這個(gè)PCB板特制作了3D效果圖:
PCB正面3D


PCB背面3D


PCB部分放大3D


設(shè)計(jì)好后拿去PCB打樣幾塊,板子收到后,看似做工非常漂亮。

開(kāi)始焊接第一塊樣板,焊接完后檢查無(wú)誤后通電測(cè)試,接下來(lái)就遇到了幾個(gè)問(wèn)題:
1. 通過(guò)ISP口寫(xiě)入程序后,單片機(jī)不運(yùn)行程序,再次檢查焊接沒(méi)問(wèn)題后,仔細(xì)查看原理圖后發(fā)現(xiàn),在設(shè)計(jì)原理圖時(shí)忙于考慮各IO口的分配問(wèn)題卻忽略了29腳EA/VPP,將其懸空了,應(yīng)將29腳接到5V電源上,讓單片機(jī)執(zhí)行內(nèi)部程序。更改后單片機(jī)正常運(yùn)行了。 2. Q2工作不正常,經(jīng)檢查后發(fā)現(xiàn),在設(shè)計(jì)時(shí)將NPN三極管和PNP三極管都用了相同的PCB封裝庫(kù)PNP,和原理圖的NPN封裝對(duì)應(yīng)腳不一樣,C、E腳剛好相反了,焊下Q2,將其反面安裝焊接,問(wèn)題得到解決。 3. Q3、Q4、Q5、Q6,這4個(gè)位驅(qū)動(dòng)不起作用,由于想省掉一個(gè)ULN2003的集成,借用了1.5寸的位驅(qū)動(dòng)用4個(gè)3極管,沒(méi)考慮到使用的是1.8寸的數(shù)碼管將其位電壓已經(jīng)提高到9V至12V,致使這4個(gè)位驅(qū)動(dòng)處于放大狀態(tài)失去了開(kāi)關(guān)的作用,將這4個(gè)位驅(qū)動(dòng)加一級(jí)3極管,測(cè)試位驅(qū)動(dòng)正常。 4. 由于錯(cuò)誤的將購(gòu)買(mǎi)的GPS天線認(rèn)為是無(wú)源天線,設(shè)計(jì)的時(shí)候按無(wú)源天線的線路設(shè)計(jì),導(dǎo)致GPS模塊無(wú)法收到GPS信息,經(jīng)反復(fù)的實(shí)驗(yàn)測(cè)試和查閱GPS模塊參數(shù)資料,得知購(gòu)買(mǎi)的是有源GPS天線,需要給天線加載電源天線才能有放大作用,根據(jù)有源天線原理,切斷GPS模塊12、24、19引腳的接地,將18(VCC_RF)、19(V_ANT)腳連接,使其16(RF_IN)腳天線輸入端加載3.3V左右的電壓,為有源天線提供電源。 5. 經(jīng)過(guò)以上4步修改后接入GPS有源天線發(fā)現(xiàn)單片機(jī)還是沒(méi)能正確的接收到需要的信息,將USB線連接到電腦安裝驅(qū)動(dòng)和GPS模塊測(cè)試軟件u-center7.0軟件進(jìn)行聯(lián)機(jī)查看,單片機(jī)程序是來(lái)自于網(wǎng)友編制的,波特率設(shè)置為9600(TH1 = 0xFD; //9600波特率的初值),而GPS模塊查看為4800的波特率,通訊協(xié)議上不一致,看到LEA-4A資料上說(shuō)可以修改波特率,在軟件中將波特率修改為9600 這次可以正常收到GPS信息并把時(shí)間顯示出來(lái)了。但是將電源切斷后從新加電,又無(wú)法收到信息了,再用軟件查看模塊波特率又回到了4800,也就是說(shuō)沒(méi)有保存起,再查看模塊相關(guān)資料得知LEA-4A模塊是ROM經(jīng)濟(jì)型產(chǎn)品并無(wú)flash存儲(chǔ)器,無(wú)法保存設(shè)置,可以通過(guò)改變硬件方式改變波特率,為了減少硬件改動(dòng),固將單片機(jī)程序修改成波特率4800(TH1 = 0xFA; //4800波特率的初值)來(lái)適應(yīng)模塊的默認(rèn)4800波特率。這下終于成功了。 測(cè)試中發(fā)現(xiàn):接收到的日期和時(shí)間信息比較快,快時(shí)約12秒,慢時(shí)半分鐘,這個(gè)天線擺放的位置和角度有一定關(guān)系。該天線下部帶有吸鐵,可以吸在金屬物體上,發(fā)現(xiàn)吸在具有大面積金屬板上接收到信息時(shí)間會(huì)縮短,也許是有反射面的緣故吧。
至于連接PC用軟件定位和導(dǎo)航這里就不作更多的解釋了。
最后完成

上電未接收到GPS衛(wèi)星信號(hào)時(shí),電壓5V,電流0.25A

接收到GPS衛(wèi)星信號(hào)并校準(zhǔn)顯示時(shí)間,電壓5V,電流0.16A

總結(jié):通過(guò)以上5點(diǎn)故障分析,在設(shè)計(jì)電路時(shí)應(yīng)做到思路清晰,小到每個(gè)零件的校對(duì),查看元件滿(mǎn)足正常運(yùn)行的條件,要做到每個(gè)元件、模塊功能參數(shù)熟悉,最好是經(jīng)過(guò)實(shí)驗(yàn)仿真后再制作PCB板,有串口通訊協(xié)議的應(yīng)先考慮和確認(rèn)協(xié)議的一致性,盡量少走彎路和犯低級(jí)性錯(cuò)。
附言:整套 制作成本大約六十多。
這里附上單片機(jī)源程序:
#include "reg52.h"
#define LEDPORT P0
sbit D1=P3^5;
sbit D2=P3^4;
sbit D3=P3^6;
sbit D4=P3^7;
sbit LED=P0^7;
unsigned char hour,min,sec;
bit rev_start,rev_stop;
//unsigned char code tab[]={0xA0,0xBE,0x64,0x2C,0x3A,0x29,0x21,0xBC,0x20,0x28,0xff};//數(shù)碼管
//unsigned char code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//數(shù)碼管
unsigned char code tab[]={0x3F,0x0C,0x5B,0x5E,0x6C,0x76,0x77,0x1C,0x7F,0x7E,0x00};//0-9,滅
unsigned char buf[80]; //請(qǐng)把GPS那貨發(fā)來(lái)的數(shù)據(jù)放到我的肚子里
void TimerInit()
{
TMOD=0x21;
TH0 = 0xF1; //4ms左右
TL0 = 0x9A;
EA=1;
ET0=1;
TR0=1;
SCON = 0x50;//使用串行工作方式1,10位異步收發(fā)8位數(shù)據(jù),波特率可變(由T1的溢出率控制)
// TH1 = 0xFD;//9600波特率的初值
TH1 = 0xFA;//4800波特率的初值
TL1 = TH1;//9600波特率的初值
ES = 1;
TR1 = 1;
}
void Display(unsigned char hour,min) //數(shù)碼管顯示
{
static unsigned char i;
LEDPORT=0x00;
switch (i)
{
case 0: if(hour/16) LEDPORT=tab[hour/16]; else LEDPORT=tab[10];D1=1;D2=D3=D4=0;break;
case 1: LEDPORT=tab[hour%16]; D2=1;D1=D3=D4=0; break;
case 2: LEDPORT=tab[min/16];D3=1;D1=D2=D4=0;break;
case 3: LEDPORT=tab[min%16];D4=1;D2=D3=D1=0;break;
}
i++;
if(i==4)i=0;
}
void main()
{
TimerInit();
while(1)
{
if((rev_stop==1)&&(buf[5]=='C'))//如果接收到GPRMC
{
ES=0;
hour= (buf [7]-0x30)* 16+ buf[8] -0x30;
min= (buf [9]-0x30)* 16+ buf[10]-0x30;
sec= (buf[11]-0x30)* 16+ buf[12]-0x30;
hour= hour / 16 * 10 + hour % 16;
LED=!LED;
hour= (hour+8) % 24;//UTC Time換算成北京時(shí)間
hour=hour/10*16+hour%10;
ES=1;
rev_stop=0;
}
}
}
void Timer0() interrupt 1
{
TH0 = 0xF1;
TL0 = 0x9A;
Display(hour,min);//定時(shí)器兄弟簡(jiǎn)單而單調(diào)的工作,很輕松的。每4ms刷新下數(shù)碼管,全年無(wú)休哦
}
/***************************************************************/
/*************************串口數(shù)據(jù)接收**************************/
/***************************************************************/
void Uart_Receive(void) interrupt 4
{
unsigned char ch,num;
ES = 0;
if (RI)//如果接收完成則進(jìn)入
{
ch = SBUF;
if (ch == '$') //如果收到字符'$',便開(kāi)始接收
{
rev_start = 1;
rev_stop = 0; //接收停止標(biāo)志
}
if (rev_start == 1) //標(biāo)志位為1,開(kāi)始接收
{
buf[num++] = ch; //字符存到數(shù)組中
if (ch == '\n') //如果接收到換行
{
buf[num] = '\n';
rev_start = 0;
rev_stop = 1; //接收停止標(biāo)志
num = 0;
}
}
}
RI = 0; //RI清0,重新接收
ES = 1; //串口1中斷允許
}
|