亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 16135|回復(fù): 9
打印 上一主題 下一主題
收起左側(cè)

HMC5883數(shù)字指南針(電子羅盤(pán))的設(shè)計(jì)論文下載 帶單片機(jī)源程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
數(shù)字指南針(電子羅盤(pán))的設(shè)計(jì)
大學(xué)本科生畢業(yè)設(shè)計(jì)(論文)
目 錄
摘要……………………………………………………………………………………………………1
前言……………………………………………………………………………………………………3
第一章 緒論……………………………………………………………………………………….....4
第1.1節(jié) 電子羅盤(pán)的原理…………………………………………………………………………4
第1.2節(jié) 電子羅盤(pán)的發(fā)展趨勢(shì)……………………………………………………………………4
第二章 總體方案設(shè)計(jì)…………………………………………………………………………….....6
第2.1節(jié) 總體方案選擇…………………………………………………………………………....6
第2.2節(jié) 硬件方案………………………………………………………………………………....7
第2.3節(jié) 軟件方案………………………………………………………………………………....8
第三章 硬件系統(tǒng)設(shè)計(jì)…………………………………………………………………………….....10
第3.1節(jié) 控制模塊設(shè)計(jì)…………………………………………………………………………....10
第3.2節(jié) 傳感器模塊設(shè)計(jì)………………………………………………………………………....11
第3.3節(jié) 顯示模塊設(shè)計(jì)……………………………………………………………………………13
第3.4節(jié) 總體電路設(shè)計(jì)…………………………………………………………………………....14
第四章 軟件系統(tǒng)設(shè)計(jì)……………………………………………………………………………….17
第4.1節(jié) 主程序設(shè)計(jì)………………………………………………………………………………17
第4.2節(jié) 傳感器模塊程序設(shè)計(jì)……………………………………………………………………18
第4.3節(jié) 顯示模塊程序設(shè)計(jì)………………………………………………………………………19
第五章 系統(tǒng)調(diào)試…………………………………………………………………………………….20
總結(jié)……………………………………………………………………………………………….......21
參考文獻(xiàn)………………………………………………………………………………………….......22
致謝……………………………………………………………………………………………….......23
附錄1 實(shí)物照片說(shuō)明………………………………………………………………………………..24
附錄2 部分源程序…………………………………………………………………………………..24

【摘要】:當(dāng)今社會(huì)交通越來(lái)越發(fā)達(dá),導(dǎo)航系統(tǒng)也逐漸普遍。在以前人們使用紙質(zhì)地圖看路況。現(xiàn)如今由于經(jīng)濟(jì)發(fā)展,交通路線(xiàn)也變化非常之大。現(xiàn)在雖然有GPS,但是在一些山區(qū)有覆蓋遮蔽的地方,GPS也會(huì)失去作用。汽車(chē)出行不方便,為解決這個(gè)問(wèn)題,本文主要研究使用在汽車(chē)導(dǎo)航設(shè)備的能夠精確定向的電子羅盤(pán)系統(tǒng)。本文主要介紹磁阻式電子羅盤(pán)的工作原理,并詳細(xì)介紹了磁阻傳感器HMC5883,AT89S52單片機(jī)的磁阻式電子羅盤(pán)的硬件設(shè)計(jì);根據(jù)傳感器信號(hào)輸出特點(diǎn),利用AT89S52單片機(jī)處理信息功能經(jīng)過(guò)分析后,經(jīng)顯示屏顯示方向。在研制磁阻電子羅盤(pán)原理樣機(jī)過(guò)程中,我對(duì)系統(tǒng)做出一定的誤差補(bǔ)償,使其系統(tǒng)的精度提高,并且對(duì)系統(tǒng)做經(jīng)一步的改進(jìn)。

對(duì)研制的數(shù)字電子羅盤(pán)系統(tǒng)樣機(jī),進(jìn)行測(cè)試。其結(jié)果顯示,該數(shù)字電子羅盤(pán)能對(duì)行駛方向進(jìn)行的動(dòng)態(tài)測(cè)量,在 0°到360°范圍行駛方向測(cè)量精度可達(dá)±2.0°。研制的數(shù)字電子羅盤(pán),具有體積小、性能穩(wěn)定、反應(yīng)快、低功耗等優(yōu)點(diǎn),在車(chē)輛導(dǎo)航設(shè)備領(lǐng)域有非常廣闊的應(yīng)用前景。

前言
通常的導(dǎo)航儀器主要有兩種:陀螺羅經(jīng)和磁羅盤(pán)。對(duì)地磁場(chǎng)測(cè)量方向的儀器叫做磁羅盤(pán)。我國(guó)發(fā)明指南針就是一個(gè)簡(jiǎn)易的磁羅盤(pán),對(duì)整個(gè)人類(lèi)社會(huì)發(fā)展做出巨大貢獻(xiàn)。在公元 50 年左右,磁石已經(jīng)被運(yùn)用到導(dǎo)航航啦,并且研制出了司南。在公元 960-1127 年時(shí)候,支撐是的指南針——指南龜被研制出來(lái)。到 20 世紀(jì)初,隨著工業(yè)的發(fā)展,羅盤(pán)制造工藝也得到了飛速的發(fā)展,材料的選擇和機(jī)械制造使得羅盤(pán)的性能有了顯著地提高。尤其是是機(jī)械式磁羅盤(pán),現(xiàn)在某些情況下依然使用機(jī)械式磁羅盤(pán) 。到了20世紀(jì)出,陀螺羅盤(pán)的問(wèn)世,對(duì)羅盤(pán)又是一場(chǎng)革命。羅盤(pán)感應(yīng)這地球的自轉(zhuǎn),磁性物質(zhì)對(duì)其沒(méi)有影響。使得陀螺羅盤(pán)的標(biāo)度盤(pán)非常穩(wěn)定,讀取數(shù)據(jù)更加精確。當(dāng)代GPS雖然有廣泛的應(yīng)用,但是信號(hào)經(jīng)常被物體所遮擋,使其精度大打折扣。有效性也大大降低。數(shù)字電子羅盤(pán)系統(tǒng)則將填補(bǔ)這一個(gè)不足,采用地磁場(chǎng)的工作原理,無(wú)論何時(shí)何地磁場(chǎng)的水平分量永遠(yuǎn)指向地磁北極,對(duì)GPS信號(hào)進(jìn)行有效補(bǔ)償。
隨著科技發(fā)展和道路建設(shè)完善,汽車(chē)會(huì)給人們生活極大方便,汽車(chē)將會(huì)普及在我們生活中。電子羅盤(pán)定向系統(tǒng)將會(huì)出現(xiàn)每一輛汽車(chē)?yán)铮粚脮r(shí)很多人會(huì)開(kāi)自己的車(chē)旅游,回家,談生意等等,當(dāng)置于一個(gè)陌生的環(huán)境中,導(dǎo)航定向?qū)τ谛熊?chē)安全非常重要。所以,迫切需要研究出一種低功耗,便于攜帶,內(nèi)置磁場(chǎng)感應(yīng)器,系統(tǒng)穩(wěn)定,并且能完成精確定向的微系統(tǒng),而本課題設(shè)計(jì)就是研究出一個(gè)數(shù)字電子羅盤(pán),專(zhuān)門(mén)解決這個(gè)問(wèn)題而產(chǎn)生的。

第一章 緒論第1.1節(jié) 電子羅盤(pán)原理
目前電子羅盤(pán)按照有無(wú)傾角補(bǔ)償可以分為平面電子羅盤(pán)和三維電子羅盤(pán),也可以按照傳感器的不同分為磁阻效應(yīng)傳感器、霍爾效應(yīng)傳感器和磁通門(mén)傳感器。
利用磁性材料的磁阻效應(yīng)制成磁性效應(yīng)傳感器。磁性材料的易磁化軸、形狀和磁化磁場(chǎng)的方向影響著其磁化方向。圖 1.1顯示出,當(dāng)電流流通磁性材料時(shí),其電阻阻值大小由材料流通電流的方向與磁化方向的夾角θ決定。把磁場(chǎng) M加在磁性材料上,之前磁化方向開(kāi)始轉(zhuǎn)動(dòng)。如果磁化方向轉(zhuǎn)向與電流的方向垂直,θ角增大,電阻阻值將減小;如果平行,即θ角減小,電阻阻值將增大,電流方向與電阻值的關(guān)系為cos2θ,這就是磁阻效應(yīng)                                                                           

圖1.1磁阻效應(yīng)原理

磁阻式傳感器具有低功耗,抗干擾,溫度穩(wěn)定性好,而且電路很容易搭建。靈敏度和線(xiàn)性度比較好。其性能及穩(wěn)定性容易被遲滯誤差和零點(diǎn)溫度漂移所影響,地磁場(chǎng)強(qiáng)度比較小,外界非磁場(chǎng)容易對(duì)磁阻式電子羅盤(pán)產(chǎn)生干擾。電子羅盤(pán)發(fā)展相當(dāng)迅速,在需要導(dǎo)航的系統(tǒng)的各行各業(yè)。并且有著非常大的應(yīng)用前景。
第1.2節(jié) 電子羅盤(pán)的發(fā)展趨勢(shì)
由于GPS導(dǎo)航在高山、樹(shù)林時(shí)信號(hào)傳輸不能很好的回饋到衛(wèi)星中。同時(shí)GPS容易受到其他信號(hào)、波形干擾,導(dǎo)致其穩(wěn)定在某些地區(qū)較差。所以需要一個(gè)穩(wěn)定的導(dǎo)航系統(tǒng)在任何場(chǎng)地都能測(cè)出行駛方向,所以這個(gè)導(dǎo)航系統(tǒng)有很大的發(fā)展前景。有地磁大小和方向隨地點(diǎn)不同而不同, 無(wú)論在地球的每一個(gè)地方,磁場(chǎng)的水平分量永遠(yuǎn)指向磁北,電子羅盤(pán)根據(jù)這一個(gè)原理制作的,所以電子羅盤(pán)可以用于穩(wěn)定的精確的汽車(chē)導(dǎo)航定向,電子羅盤(pán)系統(tǒng)的市場(chǎng)需求也在我國(guó)日趨明顯,而且也初具規(guī)模。我認(rèn)為未來(lái)電子羅盤(pán)的發(fā)展的方向有以下幾點(diǎn):
(1)使電子羅盤(pán)導(dǎo)航系統(tǒng)科技含量更高,整個(gè)制造流程可以形成一個(gè)完整的產(chǎn)物鏈
(2)把GPS的技術(shù)和電子羅盤(pán)技術(shù)相結(jié)合,對(duì)于導(dǎo)航的精確性、實(shí)用性和穩(wěn)定性有提高。
(3)把電子羅盤(pán)做成信息技術(shù)服務(wù)的產(chǎn)業(yè),使其應(yīng)用到更多的行業(yè)里,加快電子羅盤(pán)研究與發(fā)展。
未來(lái)科技發(fā)展更加快速,相對(duì)磁場(chǎng)技術(shù)也會(huì)越來(lái)成熟,電子羅盤(pán)系統(tǒng)將朝著先進(jìn)性、經(jīng)濟(jì)性、實(shí)用性、功能型的成熟完善的系統(tǒng)!

第二章 總體方案設(shè)計(jì)
第2.1節(jié) 總體方案選擇
對(duì)于電子羅盤(pán)的設(shè)計(jì),經(jīng)查找資料結(jié)合所學(xué)知識(shí),我得到兩種方案。
方案一:采用Philips公司生產(chǎn)的KMZ52感應(yīng)磁場(chǎng)傳感器
KMZ52是Philips公司生產(chǎn)的一種磁阻傳感器,是利用坡莫合金薄片的磁阻效應(yīng)測(cè)量磁場(chǎng)的高靈敏度磁阻傳感器。該磁阻傳感器內(nèi)置兩個(gè)正交磁敏電阻橋、完整的補(bǔ)償線(xiàn)圈和設(shè)置/復(fù)位線(xiàn)圈。補(bǔ)償線(xiàn)圈的輸出與當(dāng)前測(cè)量結(jié)果形成閉環(huán)反饋,使傳感器的靈敏度不受地域限制。這種磁阻傳感器主要應(yīng)用于導(dǎo)航、通用地磁測(cè)量和交通檢測(cè)。該磁阻傳感器在金屬鋁的表面沉積了一定厚度的高磁導(dǎo)率的坡莫合金,在翻轉(zhuǎn)線(xiàn)圈和外界磁場(chǎng)兩個(gè)力的作用下,電子改變運(yùn)動(dòng)方向,使得磁敏電阻的阻值發(fā)生變化。同時(shí)KMZ52的斑馬條電阻成45°放置,這使得電子在正反向磁場(chǎng)力作用下有較好的對(duì)稱(chēng)性。由于加入了翻轉(zhuǎn)磁場(chǎng),KMZ52的變化曲線(xiàn)與普通的磁敏電阻不同,更加線(xiàn)性化。KMZ52磁阻傳感器的核心部分是惠斯通電橋,是由4個(gè)磁敏感元件組成的磁阻橋臂。磁敏感元件由長(zhǎng)而薄的坡莫合金薄膜制成。在外加磁場(chǎng)的作用下,磁阻的變化引起輸出電壓的變化。

圖2.1 KMZ52傳感器引腳圖

方案二:使用霍尼韋爾HMC5883L各向異性磁阻傳感電路
霍尼韋爾 HMC5883L 是一種表面貼裝的高集成模塊,并帶有數(shù)字接口的弱磁傳感器芯片,應(yīng)用于低成本羅盤(pán)和磁場(chǎng)檢測(cè)領(lǐng)域。HMC5883L 包括最先進(jìn)的高分辨率HMC118X系列磁阻傳感器,并附帶霍尼韋爾專(zhuān)利的集成電路包括放大器、自動(dòng)消磁驅(qū)動(dòng)器、偏差校準(zhǔn)、能使羅盤(pán)精度控制在1°-2°的12位模數(shù)轉(zhuǎn)換器。簡(jiǎn)易的I2C 系列總線(xiàn)接口。HMC5883L 是采用無(wú)鉛表面封裝技術(shù),帶有16 引腳,尺寸為3.0×3.0×0.9mm。HMC5883L 的所應(yīng)用領(lǐng)域有手機(jī)、筆記本電腦、消費(fèi)類(lèi)電子、汽車(chē)導(dǎo)航系統(tǒng)和個(gè)人導(dǎo)航系統(tǒng)。HMC5883L采用霍尼韋爾各向異性磁阻(AMR)技術(shù),該技術(shù)領(lǐng)先于其他磁傳感器技術(shù)。這些各向異性傳感器具有在軸向高靈敏度和線(xiàn)性高精度的特點(diǎn).傳感器具有的對(duì)正交軸的低靈敏度的固相結(jié)構(gòu)能用于測(cè)量地球磁場(chǎng)的方向和大小,其測(cè)量范圍從毫高斯到8高斯(gauss)。霍尼韋爾的磁傳感器在低磁場(chǎng)傳感器行業(yè)中是靈敏度最高和可靠性最好的傳感器。

圖2.2 HMC5883L傳感器引腳圖

通過(guò)對(duì)比各傳感器特點(diǎn)我們了解到它們的優(yōu)缺點(diǎn),HMC5883L三軸磁阻傳感器和ASIC都被封裝在一起了,不需要外接ASIC,而12-bit ADC與低干擾AMR傳感器,能在±8高斯的磁場(chǎng)中實(shí)現(xiàn)2毫高斯的分辨率,且內(nèi)置驅(qū)動(dòng)器,顯得更為優(yōu)越。霍尼韋爾的磁傳感器在低磁場(chǎng)傳感器行業(yè)中是靈敏度最高和可靠性最好的傳感器。
綜上結(jié)合所學(xué)知識(shí)我選擇傳感器方案二,使用霍尼韋爾HMC5883L各向異性磁阻傳感電路。

第2.2節(jié) 硬件方案
數(shù)字電子羅盤(pán)3大模塊分別是:傳感器模塊、數(shù)據(jù)采集模塊和MCU模塊。需要硬件有: 磁阻傳感器、 雙軸加速度傳感器、AD轉(zhuǎn)換器以及單片機(jī)的磁阻式電子羅盤(pán)。硬件總體框圖如下:
圖2.3系統(tǒng)硬件總體框圖
采用三軸磁阻傳感器進(jìn)行地球磁場(chǎng)矢量測(cè)量,雙軸加速傳感器可以傳感地球重力場(chǎng)中測(cè)量載體的姿態(tài),然后通過(guò)姿態(tài)坐標(biāo)變換將磁阻傳感器得到載體坐標(biāo)的測(cè)量信號(hào)變換到地平坐標(biāo)系。其磁阻式傳感器HMC5883包含輸出為3路的差分模擬電壓值,差分值大約為幾毫伏,信號(hào)經(jīng)過(guò)傳感器內(nèi)置的ASIC放大器把信號(hào)進(jìn)行放大,再進(jìn)行模數(shù)轉(zhuǎn)換器進(jìn)行放大和模數(shù)轉(zhuǎn)換;再由有單片機(jī)處理數(shù)字信號(hào),經(jīng)由處理后得到航向角由顯示屏來(lái)顯示;復(fù)位電路用于恢復(fù)磁阻傳感器在強(qiáng)磁干擾后的靈敏度;電源模塊分別為復(fù)位電路和信號(hào)處理電路供電。
第2.3節(jié) 軟件方案
系統(tǒng)軟件除了完成初始化、信號(hào)采集、信號(hào)調(diào)理、A/D轉(zhuǎn)換,再到單片機(jī)中進(jìn)行信號(hào)處理分析,然后判斷能否輸出。其框圖如下所示:
圖2.4 軟件總體框圖
單片機(jī)對(duì)傳感器失調(diào)、溫度漂移等干擾造成的誤差進(jìn)行調(diào)整。失調(diào)和溫度漂移會(huì)在傳感器敏感信號(hào)上面疊加一個(gè)直流偏置電路,單片機(jī)通過(guò)將傳感器在置位和復(fù)位情況下得到的信號(hào)進(jìn)行分析,算出平均值。就可以得到由于失調(diào)和漂移造成的直流偏置信號(hào),在方向角計(jì)算前對(duì)該偏置信號(hào)進(jìn)行補(bǔ)償即可消除其影響。再判斷能否輸出,如果不能輸出,則再采集一次;能輸出則把數(shù)據(jù)送到顯示屏顯示。

第三章 硬件系統(tǒng)設(shè)計(jì)

第3.1節(jié) 控制模塊設(shè)計(jì)
AT89S52是一種低功耗、高性能CMOS 8位微控制器,具有8K 在系統(tǒng)可編程Flash存儲(chǔ)器。使用Atmel 公司高密度非易失性存儲(chǔ)器技術(shù)制造,與工業(yè)80C51 產(chǎn)品指令和引腳完全兼容。片上Flash允許程序存儲(chǔ)器在系統(tǒng)可編程,亦適于常規(guī)編程器。在單芯片上,擁有靈巧的8 位CPU 和在系統(tǒng)可編程Flash,使得AT89S52在眾多嵌入式控制應(yīng)用系統(tǒng)中得到廣泛應(yīng)用。
AT89S52具有以下標(biāo)準(zhǔn)功能: 8k字節(jié)Flash,256字節(jié)RAM, 32 位I/O 口線(xiàn),看門(mén)狗定時(shí)器,2 個(gè)數(shù)據(jù)指針,三個(gè)16 位 定時(shí)器/計(jì)數(shù)器,一個(gè)6向量2級(jí)中斷結(jié)構(gòu),全雙工串行口, 片內(nèi)晶振及時(shí)鐘電路。另外,AT89S52 可降至0Hz 靜態(tài)邏 輯操作,支持2種軟件可選擇節(jié)電模式。空閑模式下,CPU 停止工作,允許RAM、定時(shí)器/計(jì)數(shù)器、串口、中斷繼續(xù)工 作。掉電保護(hù)方式下,RAM內(nèi)容被保存,振蕩器被凍結(jié),單片機(jī)一切工作停止,直到下一個(gè)中斷或硬件復(fù)位為止。

圖3.1 AT89S52引腳圖 DIP封裝

圖3.2 AT89S52電路連接圖

第3.2節(jié) 傳感器模塊設(shè)計(jì)
1.工作原理
霍尼韋爾HMC5883L磁阻傳感器電路是三軸傳感器并應(yīng)用特殊輔助電路來(lái)測(cè)量磁場(chǎng)。通過(guò)施加供電電源,傳感器可以將量測(cè)軸方向上的任何入射磁場(chǎng)轉(zhuǎn)變成一種差分電壓輸出。磁阻傳感器是由一個(gè)鎳鐵(坡莫合金)薄膜放置在硅片上,并構(gòu)成一個(gè)帶式電阻元件。在磁場(chǎng)存在的情況下,橋式電阻元件的變化將引起跨電橋輸出電壓的相應(yīng)變化。這些磁阻元件兩兩對(duì)齊,形成一個(gè)共同的感應(yīng)軸,隨著磁場(chǎng)在感應(yīng)方向上不斷增強(qiáng),電壓也會(huì)正向增長(zhǎng)。因?yàn)檩敵鲋慌c沿軸方向上的磁阻元件成比例,其他磁阻電橋也放置在正交方向上,就能精密測(cè)量其他方向的磁場(chǎng)強(qiáng)度。
2.電源管理
該器件可有兩種不同的供電模式。第一個(gè)是內(nèi)部運(yùn)作的VDD供電電源,第二個(gè)是為IO接口供電的VDDIO電源,當(dāng)然VDDIO的電壓可以與VDD電源相近;單電源模式,或在VDDIO 電壓低于VDD 的情況下,HMC5883L都能正常運(yùn)作并能與其他裝置兼容。

圖3.3 HMC5883L內(nèi)部示意圖

3.I2C接口
控制該裝置可以通過(guò)I2C總線(xiàn)來(lái)實(shí)現(xiàn)。該裝置將作為從機(jī)在一個(gè)主機(jī)(例如:處理器)的控制下連接總線(xiàn)。該裝置必須符合I2C-Bus SpecificationI2C-總線(xiàn)技術(shù)規(guī)格標(biāo)準(zhǔn)),作為一個(gè)I2C 兼容裝置,該裝置包含一個(gè)7-bit串行地址,并支持I2C 協(xié)議。這一裝置可以支持標(biāo)準(zhǔn)和快速模式,分別為100kHz和400kHz,但不支持高速模式(Hs)。還需要外接電阻才能支持這些標(biāo)準(zhǔn)和快速模式。要求主機(jī)的活動(dòng)(寄存器的讀取和寫(xiě)入)優(yōu)先于內(nèi)部活動(dòng),例如:測(cè)量。這一優(yōu)先次序的安排是為了不讓主機(jī)等待,同時(shí)I2C總線(xiàn)占用的時(shí)間比必需的時(shí)間長(zhǎng)。
4.置位/復(fù)位帶驅(qū)動(dòng)的H-橋式電路
ASIC包含大型開(kāi)關(guān)FETs,可以傳輸大而短的脈沖到傳感器的置位/復(fù)位帶。這一置位/復(fù)位帶在很大程度上是一種電阻性負(fù)載。并不需要外部去增加外部置位/復(fù)位回路。每次測(cè)量時(shí),ASIC會(huì)自動(dòng)完成置位/復(fù)位。首先一次置位脈沖產(chǎn)生后進(jìn)行測(cè)量,然后,一次復(fù)位脈沖產(chǎn)生后進(jìn)行測(cè)量,兩次測(cè)量的差值的一半將會(huì)被放置在三軸上每根軸的數(shù)據(jù)輸出寄存器上。這樣,在所有測(cè)量中傳感器的內(nèi)部偏差和溫度漂移差值就可以被移除/抵消了。
5.寄存器訪(fǎng)問(wèn)
下面表格列出了寄存器及其訪(fǎng)問(wèn)。所有地址為8 bits。
表3.1 寄存器列表
地址
名稱(chēng)
訪(fǎng)問(wèn)
00
配置寄存器 A
讀/寫(xiě)
01
配置寄存器 B
讀/寫(xiě)
02
模式寄存器
讀/寫(xiě)
03
數(shù)據(jù)輸出 X MSB 寄存器
04
數(shù)據(jù)輸出 X LSB 寄存器
05
數(shù)據(jù)輸出 Z MSB寄存器
06
數(shù)據(jù)輸出 Z LSB 寄存器
07
數(shù)據(jù)輸出 Y MSB 寄存器
08
數(shù)據(jù)輸出 Y LSB 寄存器
09
狀態(tài)寄存器
10
識(shí)別寄存器 A
11
識(shí)別寄存器 B
12
識(shí)別寄存器 C

這里介紹讀取和寫(xiě)入此裝置的過(guò)程。該裝置使用地址指針來(lái)顯示該寄存器地點(diǎn)是被讀取或?qū)懭搿_@些指針位置從主機(jī)發(fā)出到從機(jī)并成功獲得的7位地址加1 位讀/寫(xiě)標(biāo)識(shí)符。為了盡量減少主機(jī)和裝置之間的通信,無(wú)主機(jī)干預(yù)下地址指針自動(dòng)更新。寄存器指示器被讀取后將自動(dòng)的在目前被成功讀取的寄存器的地址上加1。地址指針本身不能通過(guò)I2C總線(xiàn)被讀取。任何試圖去讀取不存在的地址返回為0s,任何去寫(xiě)不存在的地址或者是未定義的bit寫(xiě)入定義的地址都將會(huì)被該裝置予以忽略。為將地址指針移到隨機(jī)存儲(chǔ)器位置,首先發(fā)出一個(gè)“寫(xiě)”到寄存器地址,在指令后不帶數(shù)據(jù)位。
HMC5883L的串行總線(xiàn)與兩個(gè)上拉電阻相連,再與電源連接,傳感器字節(jié)連接單片機(jī)引腳,這個(gè)引腳需要加一個(gè)上拉電阻,為單片機(jī)提供灌電流。
連接電路如下:
圖3.4 HMC5883電路連接

第3.3節(jié) 顯示模塊設(shè)計(jì)
1602液晶也叫1602字符型液晶它是一種專(zhuān)門(mén)用來(lái)顯示字母、數(shù)字、符號(hào)等的點(diǎn)陣型液晶模塊它有若干個(gè)5×7或者5×11等點(diǎn)陣字符位組成,每個(gè)點(diǎn)陣字符位都可以顯示一個(gè)字符。每位之間有一個(gè)點(diǎn)距的間隔每行之間也有間隔起到了字符間距和行間距的作用,正因?yàn)槿绱怂运荒茱@示圖形。1602LCD是指顯示的內(nèi)容為16×2,即可以顯示兩行,每行16個(gè)字符液晶模塊(顯示字符和數(shù)字)。其引腳圖和引腳說(shuō)明如下:

圖3.5 LCD1602引腳圖

1602采用標(biāo)準(zhǔn)的16腳接口,其中:
第1腳:VSS為電源地
第2腳:VCC接5V電源正極
第3腳:V0為液晶顯示器對(duì)比度調(diào)整端,接正電源時(shí)對(duì)比度最弱,接地電源時(shí)對(duì)比度最高(對(duì)比度過(guò)高時(shí)會(huì) 產(chǎn)生“鬼影”,使用時(shí)可以通過(guò)一個(gè)10K的電位器調(diào)整對(duì)比度)。
第4腳:RS為寄存器選擇,高電平1時(shí)選擇數(shù)據(jù)寄存器、低電平0時(shí)選擇指令寄存器。
第5腳:RW為讀寫(xiě)信號(hào)線(xiàn),高電平(1)時(shí)進(jìn)行讀操作,低電平(0)時(shí)進(jìn)行寫(xiě)操作。
第6腳:E(或EN)端為使能(enable)端,高電平(1)時(shí)讀取信息,負(fù)跳變時(shí)執(zhí)行指令。
第7~14腳:D0~D7為8位雙向數(shù)據(jù)端。
第15~16腳:空腳或背燈電源。15腳背光正極,16腳背光負(fù)極。
圖3.6 LCD1602模塊連線(xiàn)圖
第3.4節(jié) 總體電路設(shè)計(jì)
電路如圖:
圖3.7電路整體結(jié)構(gòu)圖
此電路采用排阻,排阻就是封裝在一起的若干電阻,可以是串聯(lián),也可1端并接,只是簡(jiǎn)化了PCB的設(shè)計(jì)、安裝,減小空間,保證焊接質(zhì)量。
對(duì)于晶振,單片機(jī)系統(tǒng)里都有晶振,在單片機(jī)系統(tǒng)里晶振作用非常大,全程叫晶體振蕩器,他結(jié)合單片機(jī)內(nèi)部電路產(chǎn)生單片機(jī)所需的時(shí)鐘頻率,單片機(jī)晶振提供的時(shí)鐘頻率越高,那么單片機(jī)運(yùn)行速度就越快,單片接的一切指令的執(zhí)行都是建立在單片機(jī)晶振提供的時(shí)鐘頻率。
在通常工作條件下,普通的晶振頻率絕對(duì)精度可達(dá)百萬(wàn)分之五十。高級(jí)的精度更高。有些晶振還可以由外加電壓在一定范圍內(nèi)調(diào)整頻率,稱(chēng)為壓控振蕩器(VCO)。晶振用一種能把電能和機(jī)械能相互轉(zhuǎn)化的晶體在共振的狀態(tài)下工作,以提供穩(wěn)定,精確的單頻振蕩。
單片機(jī)晶振的作用是為系統(tǒng)提供基本的時(shí)鐘信號(hào)。通常一個(gè)系統(tǒng)共用一個(gè)晶振,便于各部分保持同步。有些通訊系統(tǒng)的基頻和射頻使用不同的晶振,而通過(guò)電子調(diào)整頻率的方法保持同步。
晶振通常與鎖相環(huán)電路配合使用,以提供系統(tǒng)所需的時(shí)鐘頻率。如果不同子系統(tǒng)需要不同頻率的時(shí)鐘信號(hào),可以用與同一個(gè)晶振相連的不同鎖相環(huán)來(lái)提供。
在電路設(shè)計(jì)中,我加入了DS1302時(shí)鐘芯片,確定系統(tǒng)年月日的時(shí)間。
DS1302的引腳排列,其中Vcc為后備電源,VCC2為主電源。在主電源關(guān)閉的情況下,也能保持時(shí)鐘的連續(xù)運(yùn)行。DS1302由Vcc或Vcc2兩者中的較大者供電。當(dāng)Vcc2大于Vcc+0.2V時(shí),Vcc2給DS1302供電。當(dāng)Vcc2小于Vcc時(shí),DS1302由Vcc供電。X1和X2是振蕩源,外接32.768kHz晶振。RST是復(fù)位/片選線(xiàn),通過(guò)把RST輸入驅(qū)動(dòng)置高電平來(lái)啟動(dòng)所有的數(shù)據(jù)傳送。RST輸入有兩種功能:首先,RST接通控制邏輯,允許地址/命令序列送入移位寄存器;其次,RST提供終止單字節(jié)或多字節(jié)數(shù)據(jù)傳送的方法。當(dāng)RST為高電平時(shí),所有的數(shù)據(jù)傳送被初始化,允許對(duì)DS1302進(jìn)行操作。如果在傳送過(guò)程中RST置為低電平,則會(huì)終止此次數(shù)據(jù)傳送,I/O引腳變?yōu)楦咦钁B(tài)。上電運(yùn)行時(shí),在Vcc>2.0V之前,RST必須保持低電平。只有在SCLK為低電平時(shí),才能將RST置為高電平。I/O為串行數(shù)據(jù)輸入輸出端(雙向)。電路連接如下:
圖3.8 DS1302電路連接圖


第四章 軟件系統(tǒng)設(shè)計(jì)

第4.1節(jié) 主程序設(shè)計(jì)
軟件設(shè)計(jì)流程圖如下:先對(duì)系統(tǒng)進(jìn)行初始化,然后再?zèng)Q定是否進(jìn)行采集測(cè)量,然后對(duì)信號(hào)處理,然后對(duì)其補(bǔ)償。方向進(jìn)行校正。不用測(cè)量則直接進(jìn)行校正,計(jì)算偏移量,保存到單片機(jī)中。還設(shè)置了休眠模式,有定時(shí)中斷等功能。

圖 4.1系統(tǒng)主程序圖

第4.2節(jié) 傳感器模塊程序設(shè)計(jì)
由復(fù)位置位電路的電流帶的特性,在 S/R+端給一個(gè)脈沖,則元件能找到準(zhǔn)確的方向與其對(duì)準(zhǔn)。而此脈沖只能加在一個(gè)方向。羅盤(pán)在工作時(shí), PA1 口每隔 1 秒鐘對(duì)傳感器置位一次。程序流程圖:

圖4.2電橋偏置電壓流程圖

void reset_HMC1022()

{

PORTA &=~(1<<1);PA1 口產(chǎn)生下降沿

_NOP(); //延時(shí) 15us

……

PORTA |=(1<<1); PA1 口產(chǎn)生上升沿

return;

}

第4.3節(jié) 顯示模塊程序設(shè)計(jì)
本設(shè)計(jì)采用LCD1602作為顯示設(shè)備,顯示的信息包括當(dāng)前方位信息與與地理南極的夾角信息(角度制)。我們從HMC5883L得出地磁方向在X與Y軸上的磁場(chǎng)強(qiáng)度分量,采用atan2( )這個(gè)函數(shù)得出其與地理北極之間的夾角(弧度),再通過(guò)弧度到角度的轉(zhuǎn)換,得到角度值,最后加上180°,使其變?yōu)榕c南極之間的夾角,而且所有值變?yōu)檎龜?shù),方便處理。得到度數(shù)后,根據(jù)我們預(yù)先設(shè)定好的角度范圍,判斷當(dāng)前所在哪個(gè)方位,并在LCD1602上顯示,然后將其乘以10倍,變?yōu)檎麛?shù),通過(guò)轉(zhuǎn)換,在LCD1602上顯示與南極夾角的值,具體設(shè)計(jì)思路如下:

圖4.3 LCD1602流程圖


第五章 系統(tǒng)調(diào)試
該電子羅盤(pán)基本達(dá)到實(shí)驗(yàn)研究所想要的結(jié)果AT89S52低功耗單片機(jī)的正常電壓為4.5V-5.5V,LCD1602液晶的正常工作電壓也為4.5V-5.5V,所以采用3節(jié)干電池4.5V作為電源。經(jīng)測(cè)試液晶顯示屏正常顯示,測(cè)試過(guò)程中所顯示的方位度數(shù)與實(shí)際方向大致相同,方位度數(shù)時(shí)常跳動(dòng),應(yīng)該是傳感器靈敏度過(guò)強(qiáng)。
電子羅盤(pán)是測(cè)量方位的儀器,為了測(cè)試其功能效果,我將其與一指南針對(duì)比,測(cè)試出8組數(shù)據(jù),記錄如下:
表5.1測(cè)試數(shù)據(jù)表
測(cè)量角度
實(shí)際角度
誤差
測(cè)量角度
實(shí)際角度
誤差
1.4
0
1.4
168.9
170
1.1
47.2
46
1.2
244.6
237
13.6
81.5
90
8.5
282.6
270
12.6
124.5
135
11.5
346.4
340
6.4
通過(guò)以上數(shù)據(jù),設(shè)計(jì)實(shí)物存在一定誤差,在正南正北方向誤差較小,在其他方向誤差較大,經(jīng)計(jì)算:平均誤差為7.0375,最大誤差為13.6,所以本實(shí)物誤差在10°以?xún)?nèi)。作為指南針,誤差在10°內(nèi),可以說(shuō)正常。
  誤差存在原因主要是本設(shè)計(jì)中沒(méi)有設(shè)計(jì)防干擾設(shè)置,由于我們周邊存在磁場(chǎng),電子羅盤(pán)在工作時(shí)會(huì)受到干擾,誤差是不可避免的。

      
                   圖5.1測(cè)試實(shí)物圖                        圖5.2指南針圖

總結(jié)
本次設(shè)計(jì)主要任務(wù)是以AT89S52單片機(jī)為核心,HMC5883為輔而制作的電子羅盤(pán),該電子羅盤(pán)基本完成任務(wù)。整個(gè)制作過(guò)程包括硬件和軟件的設(shè)計(jì)。在經(jīng)查找資料確立總體方案,從而選擇哪種硬件的過(guò)程中,讓我對(duì)51單片機(jī)和磁阻式傳感器有了更為深切的認(rèn)知。同時(shí)我也知道了對(duì)于電路硬件的選擇并不是很容易,必須考慮好幾個(gè)硬件的功能及搭配,有絲毫誤差電路就不能工作。 之后的軟件設(shè)計(jì)和系統(tǒng)調(diào)試是一個(gè)枯燥的過(guò)程,但是在成功的時(shí)候使我非常欣慰。在這次畢業(yè)設(shè)計(jì)中我學(xué)到了很多,從自己一點(diǎn)一滴地查找積累資料到最后焊接電路調(diào)試,我的搜集資料能力和系統(tǒng)總體思考能力有所提升,同時(shí)讓我對(duì)KEIL這個(gè)軟件更加熟知,使我的動(dòng)手能力有所提高。
本次設(shè)計(jì)在某些方面仍有不足,電路未加防干擾的設(shè)計(jì),使精準(zhǔn)度有所缺陷。磁傳感器受到磁性物質(zhì)的影響,從而產(chǎn)生的誤差是磁阻式羅盤(pán)誤差最大的來(lái)源。對(duì)于這種誤差,我認(rèn)為將羅盤(pán)固定在干擾較弱的方向?qū)ζ溥M(jìn)行校正,羅盤(pán)的誤差將有所減小。我相信硬件方面優(yōu)化的話(huà),這種誤差情況會(huì)有所改善。

參考文獻(xiàn)
[1] 催嵐波.船舶通信與導(dǎo)航[M].哈爾濱:哈爾濱工程大學(xué)出版社,2007:35-37
[2] 高光天.傳感器與信號(hào)調(diào)理器件應(yīng)用技術(shù)[M].北京:科學(xué)出版社.2002.7:168-170
[3] TAMARA BRATLAND ROBERT BICKING 和 BHARAT B. PANT.為什么選擇磁性傳感器.
[4] 孫希延,紀(jì)元法,施滸立.卡爾曼濾實(shí)現(xiàn)車(chē)載GPS/DR組合導(dǎo)航[J]. 現(xiàn)代電子技術(shù). 2006.11
[5] 王勇軍、李智、李翔. 車(chē)載電子羅盤(pán)中的一種新型抗干擾設(shè)計(jì)[J],單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2010,5:8-10
[6] 姜益民. 基于單片機(jī)與可編程邏輯控制器的控制系統(tǒng)的分析與設(shè)計(jì)[D].北京郵電大學(xué),2007
[7] 文樺.單片機(jī)教學(xué)與應(yīng)用平臺(tái)的研究[D].同濟(jì)大學(xué)軟件學(xué)院,2009
[8] 丁保華、張有忠、陳軍.單片機(jī)原理與接口技術(shù)實(shí)驗(yàn)教學(xué)改革與實(shí)踐[J]. 實(shí)驗(yàn)技術(shù)與管理,2010,27(1)
[9] 施利春、肖海梅. 基于磁阻傳感器的二維電子羅盤(pán)設(shè)計(jì)[J],價(jià)值工程,2011,25(10):37-38
[10] 鄭玉冰、章雪挺、劉敬彪. 磁阻式電子羅盤(pán)的設(shè)計(jì)[J],計(jì)算機(jī)測(cè)量與控制,2008,16(7):1027-1029
[11] 楊惠鋒、周奇.基于單片機(jī)和磁阻傳感器的新型車(chē)輛檢測(cè)器[J].重慶工學(xué)院學(xué)報(bào)(自然科學(xué))2008.11
[12] 李希勝、劉洪毅、郭曉霞.車(chē)用磁電子羅盤(pán)的研制[J].微計(jì)算機(jī)信息2006.22(10):308-310
[13]胡寧博、李劍、趙櫸云.基于HMC5883的電子羅盤(pán)設(shè)計(jì)[J].傳感器世界2011.6(8):35-39
[14]常青、楊東凱、寇艷紅.車(chē)輛導(dǎo)航定位方法及應(yīng)用[M].北京:機(jī)械工業(yè)出版社,2005:20-21
[15] Robert Pacz, Christia Schott,Samuel Huber*Electronic Compass Sensor [J].IEEE Magazine 2004 2(4):1446-1449

致謝
本論文是在曲輝導(dǎo)師的悉心指導(dǎo)完成的,歷時(shí)三個(gè)月之久。導(dǎo)師平易近人,和藹可親有著深厚的學(xué)術(shù)造詣。在做論文的這一個(gè)學(xué)期,遇到的問(wèn)題,曲輝老師都會(huì)指導(dǎo)我怎么去解決問(wèn)題,授人以魚(yú),不如授人以漁。曲老師教給我們的是方法,是精髓!在做論文的時(shí)候。我學(xué)會(huì)了基本的研究方法,還使我學(xué)會(huì)了處理問(wèn)題的能力。
在此,衷心感謝曲老師的悉心教導(dǎo)!

附錄2:部分源程序
  1. #include  <REG51.H>            
  2. #include  <math.h>    //Keil library
  3. #include  <stdio.h>   //Keil library            
  4. #include  <INTRINS.H>
  5. #include "DS1302.H"
  6. #define   uchar unsigned char
  7. #define   uint unsigned int            
  8. #define SYSTIM 20
  9. //使用的端口,請(qǐng)按照以下接線(xiàn)
  10. #define   DataPort P0              //LCD1602數(shù)據(jù)端口
  11. sbit              SCL=P3^7;      //IIC時(shí)鐘引腳定義
  12. sbit              SDA=P3^6;      //IIC數(shù)據(jù)引腳定義
  13. sbit    LCM_RS=P1^0;   //LCD1602命令端口                           
  14. sbit    LCM_RW=P1^1;   //LCD1602命令端口                           
  15. sbit    LCM_EN=P1^2;   //LCD1602命令端口

  16. //按鍵端口定義
  17. sbit KEY_SET=P3^2;
  18. sbit KEY_ADD=P3^3;
  19. sbit KEY_MIN=P3^4;

  20. //蜂鳴器端口定義
  21. //sbit BEEP=P2^7;

  22. #define              SlaveAddress   0x3C                //定義器件在IIC總線(xiàn)中的從地址
  23. typedef unsigned char BYTE;
  24. typedef unsigned short WORD;

  25. BYTE BUF[8];                         //接收數(shù)據(jù)緩存區(qū)                  
  26. uchar ge,shi,bai,qian,wan;           //顯示變量
  27. //uint start_A=50,stop_A=80;                                          //報(bào)警區(qū)間
  28. uchar SET_FLAG=0;
  29. uchar sys_time=0;
  30. uint angle1=0;
  31. int  dis_data;                       //變量
  32. bit dis_flag=0;
  33. unsigned char data TIME_Buffer[6]={0};                            // 時(shí)間數(shù)據(jù)暫存數(shù)組
  34. unsigned char LCD1602_Table[]="0123456789:-";

  35. void delayms(unsigned int k);
  36. void InitLcd();
  37. void Init_HMC5883(void);            //初始化5883

  38. void WriteDataLCM(uchar dataW);
  39. void WriteCommandLCM(uchar CMD,uchar Attribc);
  40. void DisplayOneChar(uchar X,uchar Y,uchar DData);
  41. void conversion(uint temp_data);

  42. void  Single_Write_HMC5883(uchar REG_Address,uchar REG_data);   //單個(gè)寫(xiě)入數(shù)據(jù)
  43. uchar Single_Read_HMC5883(uchar REG_Address);                   //單個(gè)讀取內(nèi)部寄存器數(shù)據(jù)
  44. void  Multiple_Read_HMC5883();                                  //連續(xù)的讀取內(nèi)部寄存器數(shù)據(jù)
  45. //以下是模擬iic使用函數(shù)-------------
  46. void Delay5us();
  47. void Delay5ms();
  48. void HMC5883_Start();
  49. void HMC5883_Stop();
  50. void HMC5883_SendACK(bit ack);
  51. bit  HMC5883_RecvACK();
  52. void HMC5883_SendByte(BYTE dat);
  53. BYTE HMC5883_RecvByte();
  54. void HMC5883_ReadPage();
  55. void HMC5883_WritePage();
  56. //-----------------------------------

  57. //*********************************************************
  58. void conversion(uint temp_data)
  59. {
  60.     wan=temp_data/10000+0x30 ;
  61.     temp_data=temp_data%10000;   //取余運(yùn)算
  62.               qian=temp_data/1000+0x30 ;
  63.     temp_data=temp_data%1000;    //取余運(yùn)算
  64.     bai=temp_data/100+0x30   ;
  65.     temp_data=temp_data%100;     //取余運(yùn)算
  66.     shi=temp_data/10+0x30    ;
  67.     temp_data=temp_data%10;      //取余運(yùn)算
  68.     ge=temp_data+0x30;              
  69. }

  70. /*******************************/
  71. void delayms(unsigned int k)            
  72. {                                                                                   
  73. unsigned int i,j;                                                      
  74. for(i=0;i<k;i++)
  75. {                                         
  76. for(j=0;j<121;j++)                                         
  77. {;}}                                                                                   
  78. }

  79. /********************************/
  80. void KEYSCAN()
  81. {
  82.               if(!KEY_SET)
  83.               {
  84.                             delayms(5);
  85.                             if(!KEY_SET)
  86.                             {
  87.                                           SET_FLAG++;
  88.                                           if(SET_FLAG==6)
  89.                                           {
  90.                                                         SET_FLAG=0;
  91.                                                         WRITE_DS1302(DS1302_WRITE_PROTECT,DS1302_WRITE_PROTECT_NO);              //禁止寫(xiě)保護(hù)
  92.                                                         WRITE_DS1302(WRITE_DS1302_YEAR,TIME_Buffer[0]);                                                                           //年
  93.                                                         WRITE_DS1302(WRITE_DS1302_MONTH,TIME_Buffer[1]);                                                                      //月份
  94.                                                         WRITE_DS1302(WRITE_DS1302_DAY,TIME_Buffer[2]);                                                                           //日期
  95.                                                         WRITE_DS1302(WRITE_DS1302_HOUR,TIME_Buffer[3]);                                                             //小時(shí)            
  96.                                                         WRITE_DS1302(WRITE_DS1302_MINUTE,TIME_Buffer[4]);                                                        //分
  97.                                               WRITE_DS1302(WRITE_DS1302_SECOND,TIME_Buffer[5]);                                      //秒
  98.                                               WRITE_DS1302(DS1302_WRITE_PROTECT,DS1302_WRITE_PROTECT_OFF);  //允許寫(xiě)保護(hù)            
  99.                                           }
  100.                                          
  101.                                           while(!KEY_SET);
  102.                             }            
  103.               }

  104.               if(!KEY_ADD)
  105.               {
  106.                             delayms(5);
  107.                             if(!KEY_ADD)
  108.                             {
  109.                                           switch(SET_FLAG)
  110.                                 {
  111.                                                            case 1:
  112.                                                                         if(TIME_Buffer[0]<99)
  113.                                                                         TIME_Buffer[0]++;
  114.                                                         break;
  115.                                                         case 2:
  116.                                                                         if(TIME_Buffer[1]<12)
  117.                                                                         TIME_Buffer[1]++;
  118.                                                         break;
  119.                                                         case 3:
  120.                                                                         if(TIME_Buffer[2]<31)
  121.                                                                         TIME_Buffer[2]++;
  122.                                                         break;
  123.                                                         case 4:
  124.                                                                         if(TIME_Buffer[3]<23)
  125.                                                                         TIME_Buffer[3]++;
  126.                                                         break;
  127.                                                         case 5:
  128.                                                                         if(TIME_Buffer[4]<59)
  129.                                                                         TIME_Buffer[4]++;
  130.                                                         break;
  131.                                                         default: break;
  132.                                 }
  133.                                           while(!KEY_ADD);
  134.                             }            
  135.               }

  136.               else if(!KEY_MIN)
  137.               {
  138.                             delayms(5);
  139.                             if(!KEY_MIN)
  140.                             {
  141.                                           switch(SET_FLAG)
  142.                                {
  143.                                                            case 1:
  144.                                                                         if(TIME_Buffer[0]>0)
  145.                                                                         TIME_Buffer[0]--;
  146.                                                         break;
  147.                                                         case 2:
  148.                                                                         if(TIME_Buffer[1]>1)
  149.                                                                         TIME_Buffer[1]--;
  150.                                                         break;
  151.                                                         case 3:
  152.                                                                         if(TIME_Buffer[2]>1)
  153.                                                                         TIME_Buffer[2]--;
  154.                                                         break;
  155.                                                            case 4:
  156.                                                                         if(TIME_Buffer[3]>0)
  157.                                                                         TIME_Buffer[3]--;
  158.                                                         break;
  159.                                                         case 5:
  160.                                                                         if(TIME_Buffer[4]>0)
  161.                                                                         TIME_Buffer[4]--;
  162.                                                         break;
  163.                                                         default: break;
  164.                                }
  165.                                           while(!KEY_MIN);
  166.                             }            
  167.               }
  168. }
  169. /*******************************/
  170. void WaitForEnable(void)            
  171. {                                                                     
  172. DataPort=0xff;                           
  173. LCM_RS=0;LCM_RW=1;_nop_();
  174. LCM_EN=1;_nop_();_nop_();
  175. while(DataPort&0x80);            
  176. LCM_EN=0;                                                      
  177. }                                                                     
  178. /*******************************/
  179. void WriteCommandLCM(uchar CMD,uchar Attribc)
  180. {                                                                     
  181. if(Attribc)WaitForEnable();            
  182. LCM_RS=0;LCM_RW=0;_nop_();
  183. DataPort=CMD;_nop_();            
  184. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  185. }                                                                     
  186. /*******************************/
  187. void WriteDataLCM(uchar dataW)
  188. {                                                                     
  189. WaitForEnable();                           
  190. LCM_RS=1;LCM_RW=0;_nop_();
  191. DataPort=dataW;_nop_();            
  192. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  193. }                           
  194. /***********************************/
  195. void InitLcd()                                                      
  196. {                                         
  197. WriteCommandLCM(0x38,1);            
  198. WriteCommandLCM(0x08,1);            
  199. WriteCommandLCM(0x01,1);            
  200. WriteCommandLCM(0x06,1);            
  201. WriteCommandLCM(0x0c,1);   //Angel  time
  202. DisplayOneChar(0,1,'A');
  203. DisplayOneChar(1,1,'n');
  204. DisplayOneChar(2,1,'g');
  205. DisplayOneChar(3,1,'e');
  206. DisplayOneChar(4,1,'l');
  207. DisplayOneChar(5,1,':');
  208. }                                         
  209. /***********************************/
  210. void DisplayOneChar(uchar X,uchar Y,uchar DData)
  211. {                                                                                   
  212. Y&=1;                                                                                   
  213. X&=15;                                                                                   
  214. if(Y)X|=0x40;                                                                     
  215. X|=0x80;                                         
  216. WriteCommandLCM(X,0);                           
  217. WriteDataLCM(DData);                           
  218. }                                                                                   

  219. /**************************************
  220. 延時(shí)5微秒(STC90C52RC@12M)
  221. 不同的工作環(huán)境,需要調(diào)整此函數(shù),注意時(shí)鐘過(guò)快時(shí)需要修改
  222. 當(dāng)改用1T的MCU時(shí),請(qǐng)調(diào)整此延時(shí)函數(shù)
  223. **************************************/
  224. void Delay5us()
  225. {
  226.     _nop_();_nop_();_nop_();_nop_();
  227.     _nop_();_nop_();_nop_();_nop_();
  228.               _nop_();_nop_();_nop_();_nop_();
  229.               _nop_();_nop_();_nop_();_nop_();
  230.     _nop_();_nop_();_nop_();_nop_();
  231.               _nop_();_nop_();_nop_();_nop_();
  232.               _nop_();_nop_();_nop_();_nop_();
  233.     _nop_();_nop_();_nop_();_nop_();
  234.               _nop_();_nop_();_nop_();_nop_();
  235.               _nop_();_nop_();_nop_();_nop_();
  236.     _nop_();_nop_();_nop_();_nop_();
  237.               _nop_();_nop_();_nop_();_nop_();
  238.               _nop_();_nop_();_nop_();_nop_();
  239.     _nop_();_nop_();_nop_();_nop_();
  240.               _nop_();_nop_();_nop_();_nop_();
  241.               _nop_();_nop_();_nop_();_nop_();
  242.     _nop_();_nop_();_nop_();_nop_();
  243.               _nop_();_nop_();_nop_();_nop_();

  244. }

  245. void Delay5ms()
  246. {
  247.     WORD n = 560;

  248.     while (n--);
  249. }

  250. /**************************************
  251. 起始信號(hào)
  252. **************************************/
  253. void HMC5883_Start()
  254. {
  255.     SDA = 1;                    //拉高數(shù)據(jù)線(xiàn)
  256.     SCL = 1;                    //拉高時(shí)鐘線(xiàn)
  257.     Delay5us();                 //延時(shí)
  258.     SDA = 0;                    //產(chǎn)生下降沿
  259.     Delay5us();                 //延時(shí)
  260.     SCL = 0;                    //拉低時(shí)鐘線(xiàn)
  261. }

  262. /**************************************
  263. 停止信號(hào)
  264. **************************************/
  265. void HMC5883_Stop()
  266. {
  267.     SDA = 0;                    //拉低數(shù)據(jù)線(xiàn)
  268.     SCL = 1;                    //拉高時(shí)鐘線(xiàn)
  269.     Delay5us();                 //延時(shí)
  270.     SDA = 1;                    //產(chǎn)生上升沿
  271.     Delay5us();                 //延時(shí)
  272. }

  273. /**************************************
  274. 發(fā)送應(yīng)答信號(hào)
  275. 入口參數(shù):ack (0:ACK 1:NAK)
  276. **************************************/
  277. void HMC5883_SendACK(bit ack)
  278. {
  279.     SDA = ack;                  //寫(xiě)應(yīng)答信號(hào)
  280.     SCL = 1;                    //拉高時(shí)鐘線(xiàn)
  281.     Delay5us();                 //延時(shí)
  282.     SCL = 0;                    //拉低時(shí)鐘線(xiàn)
  283.     Delay5us();                 //延時(shí)
  284. }

  285. /**************************************
  286. 接收應(yīng)答信號(hào)
  287. **************************************/
  288. bit HMC5883_RecvACK()
  289. {
  290.     SCL = 1;                    //拉高時(shí)鐘線(xiàn)
  291.     Delay5us();                 //延時(shí)
  292.     CY = SDA;                   //讀應(yīng)答信號(hào)
  293.     SCL = 0;                    //拉低時(shí)鐘線(xiàn)
  294.     Delay5us();                 //延時(shí)

  295.     return CY;
  296. }

  297. /**************************************
  298. 向IIC總線(xiàn)發(fā)送一個(gè)字節(jié)數(shù)據(jù)
  299. **************************************/
  300. void HMC5883_SendByte(BYTE dat)
  301. {
  302.     BYTE i;

  303.     for (i=0; i<8; i++)         //8位計(jì)數(shù)器
  304.     {
  305.         dat <<= 1;              //移出數(shù)據(jù)的最高位
  306.         SDA = CY;               //送數(shù)據(jù)口
  307.         SCL = 1;                //拉高時(shí)鐘線(xiàn)
  308.         Delay5us();             //延時(shí)
  309.         SCL = 0;                //拉低時(shí)鐘線(xiàn)
  310.         Delay5us();             //延時(shí)
  311.     }
  312.     HMC5883_RecvACK();
  313. }

  314. /**************************************
  315. 從IIC總線(xiàn)接收一個(gè)字節(jié)數(shù)據(jù)
  316. **************************************/
  317. BYTE HMC5883_RecvByte()
  318. {
  319.     BYTE i;
  320.     BYTE dat = 0;

  321.     SDA = 1;                    //使能內(nèi)部上拉,準(zhǔn)備讀取數(shù)據(jù),
  322.     for (i=0; i<8; i++)         //8位計(jì)數(shù)器
  323.     {
  324.         dat <<= 1;
  325.         SCL = 1;                //拉高時(shí)鐘線(xiàn)
  326.         Delay5us();             //延時(shí)
  327.         dat |= SDA;             //讀數(shù)據(jù)              
  328.         SCL = 0;                //拉低時(shí)鐘線(xiàn)
  329.         Delay5us();             //延時(shí)
  330.     }
  331.     return dat;
  332. }

  333. //***************************************************

  334. void Single_Write_HMC5883(uchar REG_Address,uchar REG_data)
  335. {
  336.     HMC5883_Start();                  //起始信號(hào)
  337.     HMC5883_SendByte(SlaveAddress);   //發(fā)送設(shè)備地址+寫(xiě)信號(hào)
  338.     HMC5883_SendByte(REG_Address);    //內(nèi)部寄存器地址,請(qǐng)參考中文pdf
  339.     HMC5883_SendByte(REG_data);       //內(nèi)部寄存器數(shù)據(jù),請(qǐng)參考中文pdf
  340.     HMC5883_Stop();                   //發(fā)送停止信號(hào)
  341. }

  342. //********單字節(jié)讀取內(nèi)部寄存器*************************
  343. uchar Single_Read_HMC5883(uchar REG_Address)
  344. {  uchar REG_data;
  345.     HMC5883_Start();                          //起始信號(hào)
  346.     HMC5883_SendByte(SlaveAddress);           //發(fā)送設(shè)備地址+寫(xiě)信號(hào)
  347.     HMC5883_SendByte(REG_Address);                   //發(fā)送存儲(chǔ)單元地址,從0開(kāi)始            
  348.     HMC5883_Start();                          //起始信號(hào)
  349.     HMC5883_SendByte(SlaveAddress+1);         //發(fā)送設(shè)備地址+讀信號(hào)
  350.     REG_data=HMC5883_RecvByte();              //讀出寄存器數(shù)據(jù)
  351.               HMC5883_SendACK(1);  
  352.               HMC5883_Stop();                           //停止信號(hào)
  353.     return REG_data;
  354. }
  355. //******************************************************
  356. //
  357. //連續(xù)讀出HMC5883內(nèi)部角度數(shù)據(jù),地址范圍0x3~0x5
  358. //
  359. //******************************************************
  360. void Multiple_read_HMC5883(void)
  361. {   uchar i;
  362.     HMC5883_Start();                          //起始信號(hào)
  363.     HMC5883_SendByte(SlaveAddress);           //發(fā)送設(shè)備地址+寫(xiě)信號(hào)
  364.     HMC5883_SendByte(0x03);                   //發(fā)送存儲(chǔ)單元地址,從0x32開(kāi)始            
  365.     HMC5883_Start();                          //起始信號(hào)
  366.     HMC5883_SendByte(SlaveAddress+1);         //發(fā)送設(shè)備地址+讀信號(hào)
  367.               for (i=0; i<6; i++)                      //連續(xù)讀取6個(gè)地址數(shù)據(jù),存儲(chǔ)中BUF
  368.     {
  369.         BUF[i] = HMC5883_RecvByte();          //BUF[0]存儲(chǔ)0x32地址中的數(shù)據(jù)
  370.         if (i == 5)
  371.         {
  372.            HMC5883_SendACK(1);                //最后一個(gè)數(shù)據(jù)需要回NOACK
  373.         }
  374.         else
  375.         {
  376.           HMC5883_SendACK(0);                //回應(yīng)ACK
  377.        }
  378.    }
  379.     HMC5883_Stop();                          //停止信號(hào)
  380.     Delay5ms();
  381. }

  382. //顯示區(qū)間子程序
  383. void DISPLAY()
  384. {
  385.               sys_time++;
  386.               if(sys_time>=SYSTIM)
  387.               {
  388.                             sys_time=0;
  389.                             dis_flag=~ dis_flag;
  390.               }
  391.               if(SET_FLAG==0)
  392.               {
  393.                             TIME_Buffer[0]=READ_DS1302(READ_DS1302_YEAR);
  394.                             TIME_Buffer[1]=READ_DS1302(READ_DS1302_MONTH);
  395.                             TIME_Buffer[2]=READ_DS1302(READ_DS1302_DAY);
  396.                             TIME_Buffer[3]=READ_DS1302(READ_DS1302_HOUR);
  397.                             TIME_Buffer[4]=READ_DS1302(READ_DS1302_MINUTE);
  398.                             TIME_Buffer[5]=READ_DS1302(READ_DS1302_SECOND);
  399.               }
  400.               if(SET_FLAG==1&&dis_flag)
  401.               {
  402.                             DisplayOneChar(1,0,' ');
  403.                             DisplayOneChar(2,0,' ');            
  404.               }
  405.               else
  406.               {
  407.                             DisplayOneChar(1,0,LCD1602_Table[TIME_Buffer[0]/10]);
  408.                             DisplayOneChar(2,0,LCD1602_Table[TIME_Buffer[0]%10]);
  409.               }
  410.               DisplayOneChar(3,0,'/');
  411.               if(SET_FLAG==2&&dis_flag)
  412.               {
  413.                             DisplayOneChar(4,0,' ');
  414.                             DisplayOneChar(5,0,' ');            
  415.               }
  416.               else
  417.               {
  418.                             DisplayOneChar(4,0,LCD1602_Table[TIME_Buffer[1]/10]);
  419.                             DisplayOneChar(5,0,LCD1602_Table[TIME_Buffer[1]%10]);
  420.               }
  421.               DisplayOneChar(6,0,'/');
  422.               if(SET_FLAG==3&&dis_flag)
  423.               {
  424.                             DisplayOneChar(7,0,' ');
  425.                             DisplayOneChar(8,0,' ');            
  426.               }
  427.               else
  428.               {
  429.                             DisplayOneChar(7,0,LCD1602_Table[TIME_Buffer[2]/10]);
  430.                             DisplayOneChar(8,0,LCD1602_Table[TIME_Buffer[2]%10]);
  431.               }
  432.               DisplayOneChar(9,0,' ');
  433.               if(SET_FLAG==4&&dis_flag)
  434.               {
  435.                             DisplayOneChar(10,0,' ');
  436.                             DisplayOneChar(11,0,' ');            
  437.               }
  438.               else
  439.               {
  440.                             DisplayOneChar(10,0,LCD1602_Table[TIME_Buffer[3]/10]);
  441.                             DisplayOneChar(11,0,LCD1602_Table[TIME_Buffer[3]%10]);
  442.               }
  443.               if((TIME_Buffer[5]%2)==0)            
  444.               DisplayOneChar(12,0,':');
  445. ……………………

  446. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

完整論文下載(word格式 可編輯):
電子羅盤(pán)的設(shè)計(jì)-畢業(yè)設(shè)計(jì).doc (3.46 MB, 下載次數(shù): 150)





分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:347453 發(fā)表于 2018-12-7 20:23 | 只看該作者
感謝分享                     
回復(fù)

使用道具 舉報(bào)

板凳
ID:429621 發(fā)表于 2018-12-11 10:42 | 只看該作者
感謝分享
回復(fù)

使用道具 舉報(bào)

地板
ID:167387 發(fā)表于 2018-12-25 15:13 | 只看該作者
非常好用,謝謝分享
回復(fù)

使用道具 舉報(bào)

5#
ID:167387 發(fā)表于 2018-12-25 15:14 | 只看該作者
要是能把.c文件直接分享一下就更好了
回復(fù)

使用道具 舉報(bào)

6#
ID:491382 發(fā)表于 2019-3-16 11:46 | 只看該作者
非常好用,謝謝分享
回復(fù)

使用道具 舉報(bào)

7#
ID:29032 發(fā)表于 2019-4-4 09:13 | 只看該作者
感謝分享!!
回復(fù)

使用道具 舉報(bào)

8#
ID:789448 發(fā)表于 2021-4-29 16:42 | 只看該作者
資料齊全,感謝樓主的無(wú)私分享。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表