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

QQ登錄

只需一步,快速開始

搜索
查看: 46506|回復(fù): 33
收起左側(cè)

自制智能型ICL7135四位半表頭

  [復(fù)制鏈接]
ID:223055 發(fā)表于 2017-7-28 17:16 | 顯示全部樓層 |閱讀模式
本文作者:Edward

本文已在《無(wú)線電》2012年12期發(fā)表。轉(zhuǎn)載請(qǐng)注明出處。這里發(fā)表的是原文,和雜志上略有不同。

這個(gè)制作以前發(fā)過(guò)一次帖子:《最近完工的智能型ICL7135四位半表頭》這次在這里將詳細(xì)內(nèi)容發(fā)上來(lái),是想在網(wǎng)絡(luò)上留個(gè)印記,方便自己引用,也是希望和大家分享一下。

正文開始:

       最近需要一個(gè)精度比較高的電壓表頭,但網(wǎng)上賣的表頭多是三位半的,精度不夠,也有一些四位半表頭但性價(jià)比不高。正好手里有幾片ICL7135,以前也有做過(guò)四位半表頭的嘗試,而且去年也學(xué)習(xí)了單片機(jī),于是就有了做一個(gè)智能型ICL7135四位半表頭的想法。歷經(jīng)2個(gè)月的學(xué)習(xí)、設(shè)計(jì)和修改,最終做出了這樣一款表頭。
       表頭使用ICL7135作為ADC,其是一款高精度的單片4½位ADC,擁有多路復(fù)用的BCD輸出以及與單片機(jī)兼容的控制信號(hào)接口,可以很容易的與單片機(jī)連接,實(shí)現(xiàn)智能化。生產(chǎn)其兼容芯片的廠家有很多,我手里是Maxim和TI生產(chǎn)的。ICL7135應(yīng)用電路由模擬部分和數(shù)字部分組成,表頭整體設(shè)計(jì)思路是:模擬部分采用典型電路和推薦元件參數(shù),數(shù)字部分采用單片機(jī)提供ICL7135所需時(shí)鐘、采集輸出、驅(qū)動(dòng)數(shù)碼管。后來(lái),考慮到只做一個(gè)簡(jiǎn)單功能的表頭實(shí)在是無(wú)趣,所以就將單片機(jī)的部分IO口和串口引出以便實(shí)現(xiàn)與上位機(jī)通信或自動(dòng)控制等功能。
       確定好整體思路和預(yù)期功能后就開始進(jìn)行電路設(shè)計(jì)了。ICL7135模擬部分典型電路如圖1所示。

174436gwdtd7vdgngfgguf.png

圖1 ICL7135電路模擬部分

       模擬部分元件沒(méi)什么可說(shuō)的,基本都采用推薦值。其中比較關(guān)鍵的是積分電容的選擇和基準(zhǔn)電壓的提供。積分電容對(duì)于ICL7135這類雙積分ADC是至關(guān)重要的,它直接影響積分非線性、翻轉(zhuǎn)、比例誤差,即它的好壞直接決定了表頭的準(zhǔn)確性。而ICL7135對(duì)積分電容的要求尤為嚴(yán)格。積分電容必須具有低的電介質(zhì)吸收特性(亦稱浸潤(rùn)或電介質(zhì)遲滯)。將基準(zhǔn)輸入(REF)接至IN HI可以檢測(cè)積分電容介質(zhì)吸收(此法一般稱為自檢),良好的積分電容讀數(shù)將會(huì)是9999,與這個(gè)讀數(shù)之間的任何偏差都可能是由于電介質(zhì)吸收引起的。一般來(lái)說(shuō),特氟龍(聚四氟乙烯)、聚苯乙烯和聚丙烯的電介質(zhì)吸收特性低至0.02%,一般陶瓷和聚碳酸酯電容的典型值為0.2%,銀云母和鉭電容為1.0%-5.0%,鋁電解電容高達(dá)10%或以上。ICL7135手冊(cè)上建議積分電容最好使用特氟龍和聚丙烯電容,要求不高時(shí)可以使用聚苯乙烯和聚碳酸酯電容。在實(shí)際選擇時(shí),優(yōu)質(zhì)高耐壓的CBB21或CBB22電容效果不錯(cuò),一般自檢讀數(shù)能夠達(dá)到9996或以上,但是買到能有9999自檢讀數(shù)的電容是挺不容易的。我挑選了幾批電容測(cè)試,讀數(shù)從9994-9996都有,就是沒(méi)有9997以上的,比較遺憾。
       開始的時(shí)候,想使用LM385作為基準(zhǔn),但是LM385本身參數(shù)并不很好,不同廠家的溫漂從20~150ppm/℃都有,而且買到正品LM385不太容易。后來(lái)在網(wǎng)上搜索了一段時(shí)間,發(fā)現(xiàn)拆機(jī)的Linear公司產(chǎn)電壓基準(zhǔn)LT1009很好。LT1009是具有0.2%初始精度,15ppm典型溫漂,25ppm最大溫漂的2.5V并聯(lián)型基準(zhǔn),它有一個(gè)調(diào)節(jié)引腳,可以在±5%范圍內(nèi)調(diào)整輸出電壓。LT1009的性能超過(guò)了一般的LM385,而且拆機(jī)件能夠保證芯片是真品也廉價(jià);鶞(zhǔn)電壓電路如圖2所示,Rref1和Rref2將LT1009輸出的電壓分壓,通過(guò)調(diào)節(jié)電位器Rref3將分壓之后的電壓調(diào)整到準(zhǔn)確的1.000V。1.000V電壓的微調(diào)還有另一種比較常見(jiàn)的方式,即只微調(diào)分壓電阻,由于種種原因我沒(méi)選擇這種方式。調(diào)整電位器要使用如3/8寸Square Trimpot.®微調(diào)電位器(3296電位器)等這類精密多圈電位器,以保證精確性和穩(wěn)定性。

174437zt2m1cpo1ichpw0n.png

圖2  基準(zhǔn)電壓電路

       傳統(tǒng)的ICL7135表頭很多是使用4MHz晶振經(jīng)CD4060分頻獲得125kHz頻率,BCD輸出用74LS48之類譯碼,最后再用三極管或達(dá)林頓驅(qū)動(dòng)器驅(qū)動(dòng)數(shù)碼管,電路復(fù)雜不說(shuō),成本還高。既然要使用單片機(jī),那么就要讓其完成所有功能。STC10F04XE是增強(qiáng)型的8051單片機(jī),擁有4kB的ROM,512B的RAM,5kB的EEPROM以及獨(dú)立波特率發(fā)生器, IO口可設(shè)置為多種輸出模式;可以實(shí)現(xiàn)時(shí)鐘信號(hào)、數(shù)據(jù)讀取、數(shù)碼管驅(qū)動(dòng)、狀態(tài)指示、按鍵控制和串口通信等全部功能。其引腳定義如圖3所示。
174438hqvavmeeppqmhcvy.png

圖3  STC10F04XE引腳圖

       考慮程序的復(fù)雜度,決定采用比較簡(jiǎn)單的讀取BCD方式采集ICL7135數(shù)據(jù)。以前我也嘗試使用Busy信號(hào)來(lái)采集數(shù)據(jù),但并不成功,所以這次并不打算采用這種方式。ICL7135輸出數(shù)據(jù)有5位數(shù)字,D5-D1端按順序分別輸出高電平脈沖進(jìn)行不間斷的掃描。B8、B4、B2、B1端輸出當(dāng)前位的BCD值。當(dāng)一次正常的數(shù)據(jù)轉(zhuǎn)換結(jié)束后,D5-D1重新開始不斷掃描(超量程時(shí)不是)。每次數(shù)據(jù)轉(zhuǎn)換后的D5-D1的第一遍掃描過(guò)程中的每個(gè)脈沖的中間, 185631qi2x9x29rkbyirtd.png 端都會(huì)有一個(gè)很短的低電平脈沖,之后直到下次轉(zhuǎn)換結(jié)束前都沒(méi)有額外的脈沖。該脈沖能幫助及時(shí)采集ADC結(jié)果,防止重復(fù)采集,簡(jiǎn)化程序。上述過(guò)程的時(shí)序如圖4所示。

184151fh5ff9y1yddrn5tp.png

圖4  數(shù)字掃描和輸出時(shí)序

       將BCD輸出端和D1-D4按順序連接在單片機(jī)的P0口(D5懸空即可),用于采集ICL7135數(shù)據(jù),端接到單片機(jī)中斷0端(P3.2)。單片機(jī)的P1.0口是獨(dú)立波特率發(fā)生器的可編程輸出時(shí)鐘端口,用該端口輸出穩(wěn)定的時(shí)鐘信號(hào)給ICL7135。為了良好的抑制50Hz工頻干擾,ICL7135的信號(hào)積分階段周期應(yīng)是工頻周期的整數(shù)倍,信號(hào)積分階段周期為10000個(gè)時(shí)鐘周期,則最佳時(shí)鐘頻率=50×10000/N,N為整數(shù)。所以可選的時(shí)鐘頻率可為100kHz、125kHz等。STC10F04XE是1T單片機(jī),所以可以選擇4MHz、6Mhz等較低頻率的晶振以減小功耗和干擾,但選擇晶振頻率要注意保證P1.0口能輸出所需的時(shí)鐘頻率。使用6MHz的晶振能產(chǎn)生100kHz、120kHz、125kHz等多種頻率,但4MHz晶振無(wú)法產(chǎn)生120kHz等頻率。本來(lái)我是想選擇4MHz晶振的,但是考慮到程序中要能設(shè)定多種時(shí)鐘頻率,所以最終使用了6MHz晶振。為了能夠直接驅(qū)動(dòng)數(shù)碼管和8個(gè)LED,所以選擇了這種IO口可設(shè)為推挽輸出的單片機(jī)。數(shù)碼管各段需要用電阻限流,以防燒壞數(shù)碼管和單片機(jī)。ICL7135的其余端口根據(jù)PCB布線的方便性接在單片機(jī)的不同IO口上,在P4.0口設(shè)置一輕觸開關(guān),同時(shí)單片機(jī)引出串口、中斷1、部分IO口以供通信、控制之用。
       ICL7135通常需要±5V供電,提供雙電源實(shí)在是不方便,所以采用手冊(cè)推薦的ICL7660電荷泵負(fù)壓電路,簡(jiǎn)單穩(wěn)定。供電電路還額外增加了AMS1117-5.0穩(wěn)壓芯片,除使用5V外還可以使用6V-15V電壓供電,擴(kuò)展了供電范圍,同時(shí)還設(shè)計(jì)了超壓保護(hù)和反接保護(hù)電路,以保護(hù)芯片安全。不要小看這個(gè)超壓保護(hù)和反接保護(hù),在平時(shí)做一些實(shí)驗(yàn)調(diào)試時(shí),各種線會(huì)很多很亂,各種電壓也會(huì)有很多,接錯(cuò)線是很正常的事,如果沒(méi)有這些保護(hù),接錯(cuò)的后果往往很嚴(yán)重。我在修改測(cè)試這個(gè)表頭的過(guò)程中,就有過(guò)將13V電源誤接入5V供電輸入上,幸好當(dāng)時(shí)沒(méi)偷懶,保護(hù)電路也焊上了,不然芯片肯定不保了。

180239zbusquo43qs22363.png

圖5  整機(jī)電路(清晰大圖請(qǐng)下載本貼附件)

       整機(jī)電路圖見(jiàn)圖5。將電路畫好檢查無(wú)誤之后就開始進(jìn)行電路板布線了。布線主要看個(gè)人的學(xué)習(xí)和經(jīng)驗(yàn)了。各元件優(yōu)先選擇貼片元件以減小體積和成本,為了便于更換積分電容,我特意制作了能兼容多種腳距的封裝。布線時(shí)要注意元件的合理布局,數(shù)字模擬要分開,模擬地和數(shù)字地要單點(diǎn)接地。如果想使用洞洞板搭建電路,那就要注意不要使用紙基的洞洞板,紙基的洞洞板很容易受潮,漏電大,會(huì)嚴(yán)重影響ICL7135模擬電路的工作。我曾經(jīng)使用過(guò)紙基板搭電路,工作很不穩(wěn)定。這也是我選擇PCB打樣的原因之一。經(jīng)歷兩次打樣和修改后,最終的PCB如下:

174443ff1zkuc8zfkf1yfd.jpg

174447ms520ujupoqqajq5.jpg

圖6  PCB空板

       焊接元件時(shí)要注意首先將所有貼片元件焊接好,仔細(xì)檢查已焊接元件有無(wú)錯(cuò)誤,LED、1N4148和穩(wěn)壓二極管的極性不能接反。然后將除數(shù)碼管、ICL7135和排針以外的直插元件焊接好,再次檢查已焊接元件有無(wú)錯(cuò)誤。最后依次焊接ICL7135、數(shù)碼管和排針,數(shù)碼管和ICL7135方向一定不要裝反。如果想日后能夠更換積分電容,可使用28Pin的IC插座來(lái)安裝ICL7135。元件焊接好后,可以通電試一下機(jī),如果沒(méi)有下載過(guò)程序,LED1-8會(huì)不斷閃爍。將元件焊接好之后是這樣的:

174450ebjvb1bdbjau2mzf.jpg

174453m3rork66ms3srmzt.jpg

圖7  焊接好元件之后

       設(shè)計(jì)工作的最后一步自然是程序設(shè)計(jì)了。其實(shí)程序設(shè)計(jì)、測(cè)試和電路板打樣、修改是交互進(jìn)行的。第一次打樣出的PCB很可能有很多問(wèn)題,如設(shè)計(jì)不合理等等。在寫程序和測(cè)試時(shí)發(fā)現(xiàn)問(wèn)題就要修改電路板,然后再編程再打樣再測(cè)試,如此反復(fù),最后設(shè)計(jì)出成品?梢哉f(shuō),程序是整個(gè)作品的靈魂,因?yàn)楸眍^的全部功能都體現(xiàn)在程序上,程序的好壞直接決定了作品的成敗。我花了很長(zhǎng)時(shí)間來(lái)設(shè)計(jì)這個(gè)程序,也嘗試使用了一些以前未曾用過(guò)的程序結(jié)構(gòu),得到了比較好的效果。整個(gè)程序最關(guān)鍵的自然是ADC數(shù)據(jù)的讀取和顯示。最初我沒(méi)有使用信號(hào)和中斷,結(jié)果數(shù)據(jù)讀取不及時(shí),有時(shí)還會(huì)丟字或者是重復(fù)讀取,而且還不好與顯示函數(shù)協(xié)調(diào)。經(jīng)過(guò)反復(fù)嘗試和研讀ICL7135手冊(cè),最后利用的電平脈沖信號(hào)產(chǎn)生中斷來(lái)讀取和更新數(shù)據(jù)。讀取ADC數(shù)據(jù)后結(jié)束中斷返回正常運(yùn)行,由于讀取數(shù)據(jù)過(guò)程很短,能夠不影響顯示正常的顯示、通信和控制,同時(shí)也節(jié)省了單片機(jī)資源,簡(jiǎn)化了程序。把主要的做好,其他的功能逐步添加就可以了。由于單片機(jī)的功能很強(qiáng),同時(shí)也有EEPROM,可以方便的存儲(chǔ)數(shù)據(jù),所以我設(shè)計(jì)了一個(gè)菜單來(lái)方便功能的設(shè)置,設(shè)置數(shù)據(jù)存儲(chǔ)在EEPROM中實(shí)現(xiàn)掉電不丟失,F(xiàn)在功能菜單也有了,就可以完全任憑自己的想象力來(lái)發(fā)揮了,因?yàn)镸CU無(wú)限可能。我目前實(shí)現(xiàn)的功能有數(shù)據(jù)保持、串口發(fā)送測(cè)量值設(shè)定、工作頻率設(shè)定、小數(shù)點(diǎn)位置設(shè)定、菜單超時(shí)退出和還原出廠設(shè)置等。未來(lái)要實(shí)現(xiàn)的功能有:開關(guān)短按功能設(shè)置,電壓超閾值報(bào)警,平均值計(jì)算,差值計(jì)算,軟件校準(zhǔn),自動(dòng)控制等等。板子上只設(shè)計(jì)了一個(gè)輕觸開關(guān),基本夠用了。長(zhǎng)按按鍵進(jìn)入設(shè)置菜單,短按按鍵數(shù)據(jù)保持。以后要增加短按功能設(shè)置,可以更改短按的功能。這個(gè)程序也是我第一次使用定時(shí)器來(lái)進(jìn)行按鍵按檢測(cè)。我沒(méi)有使用常用的軟件延時(shí)和中斷檢測(cè)法。因?yàn)閱纹瑱C(jī)要不斷掃描數(shù)碼管,不能打斷掃描太長(zhǎng)時(shí)間,不然數(shù)字顯示會(huì)閃爍或中斷。不使用中斷的原因是單片機(jī)外部中斷資源比較有限,我想把中斷1端口預(yù)留給以后控制使用;另外程序編寫得循環(huán)很快,每次循環(huán)只掃描一個(gè)數(shù)碼管,這樣一次循環(huán)的時(shí)間就很短,不會(huì)影響到按鍵的判斷。程序也有向上位機(jī)發(fā)送測(cè)量結(jié)果的功能如果設(shè)置打開了串口發(fā)送數(shù)據(jù),那么每次測(cè)量結(jié)束就會(huì)將測(cè)量結(jié)果以BCD碼通過(guò)串口發(fā)送出去。多參考單片機(jī)的數(shù)據(jù)手冊(cè),再開動(dòng)腦筋就可以做出很多很有意思的功能。編寫程序的時(shí)候要注意IO口的工作模式,數(shù)據(jù)接收要設(shè)為開漏,數(shù)據(jù)發(fā)送和發(fā)送接收口要設(shè)為準(zhǔn)雙向口,數(shù)碼管段驅(qū)動(dòng)口要根據(jù)選取的數(shù)碼管類型(共陰或共陽(yáng))設(shè)為推挽或開漏,數(shù)碼管位驅(qū)動(dòng)口同樣,要設(shè)為開漏或推挽。
       當(dāng)程序編寫調(diào)試完成后,在投入使用前最后一個(gè)重要工作就是對(duì)表頭進(jìn)行校準(zhǔn),以保證測(cè)量的準(zhǔn)確性。原則上應(yīng)該使用4½及以上位數(shù)的數(shù)字電壓表或萬(wàn)用表,將其輸入端與表頭輸入端并聯(lián),并輸入一個(gè)1V左右穩(wěn)定的電壓,調(diào)節(jié)電位器使二者顯示一致的方式來(lái)調(diào)整。但是考慮可能沒(méi)有4½或以上位數(shù)的儀表,也可以用精度良好的3½或3¾位萬(wàn)用表來(lái)簡(jiǎn)單調(diào)整。方法是使用萬(wàn)用表200.0mV或400.0mV量程電壓檔,將其輸入端與本機(jī)輸入端并聯(lián),并輸入一個(gè)100-200mV穩(wěn)定的電壓,調(diào)節(jié)電位器,調(diào)整使二者顯示一致即可。
       最后就可以將表頭投入使用了。由于我沒(méi)有更好的積分電容,所以表頭精度略差,實(shí)際滿量程誤差是正負(fù)十幾個(gè)字左右。整機(jī)耗電在30mA左右。目前工作正常,與上位機(jī)通信也很穩(wěn)定。


174457uuu5r0i2iuquraro.jpg

圖8  工作中的表頭

電路圖大圖下載:
05.png
單片機(jī)的源程序:
4.5Digital Voltmeter MCU Program V1.0.rar (5.91 KB, 下載次數(shù): 408)

另外再補(bǔ)充一段工作時(shí)的視頻:(數(shù)據(jù)保持忘了拍了,是短按按鍵,藍(lán)色LED會(huì)亮。為了方便拍攝,是使用串口控制的表頭,如果按鍵,正常顯示時(shí)短按就是數(shù)據(jù)保持,長(zhǎng)按就是進(jìn)入菜單,長(zhǎng)按生效時(shí),全部LED都會(huì)亮起。)

單片機(jī)源程序如下:
  1. /**************************************************
  2. 4 1/2 Digital Voltmeter MCU Program

  3. Using MCU STC10F04XE with 6.000MHz Crystal
  4. With PCB v1.01

  5. UART Command
  6. 0xF1 Key Long
  7. 0xF2 Ket Short
  8. 0xF3 Erase EEPROM 0x0800
  9. 0xF4 Reboot(choosen)
  10. 0x00 Reboot

  11. Created By Edward
  12. Creation Date  14-Apr-2012
  13. Latest Version 27-May-2012

  14. Copyright 2012 Edward All rights reserved.
  15. **************************************************/

  16. #include
  17. #include
  18. /*Declare SFR associated*/
  19. sfr CLK_DIV = 0x97;//System clock divide
  20. sfr P4                = 0xC0;//P4 Port
  21. sfr P4SW    = 0xBB;//P4SW Register
  22. sfr P0M0    = 0x94;//IO Port Type Register
  23. sfr P0M1    = 0x93;
  24. sfr P1M0    = 0x92;
  25. sfr P1M1    = 0x91;
  26. sfr P2M0    = 0x96;
  27. sfr P2M1    = 0x95;
  28. sfr P3M0    = 0xB2;
  29. sfr P3M1    = 0xB1;
  30. sfr P4M0    = 0xB4;
  31. sfr P4M1    = 0xB3;
  32. sfr AUXR    = 0x8E;//Auxiliary register
  33. sfr BRT                = 0x9C;//Baud-Rate Timer register
  34. sfr WAKE_CLKO=0x8F;//Clock output and Power-down Wakeup Control register
  35. sfr IAP_CTRL = 0xC7;//ISP/IAP Control register
  36. /*Declare SFR associated with the IAP */
  37. sfr IAP_DATA = 0xC2; //Flash data register
  38. sfr IAP_ADDRH= 0xC3; //Flash address HIGH
  39. sfr IAP_ADDRL= 0xC4; //Flash address LOW
  40. sfr IAP_CMD  = 0xC5; //Flash command register
  41. sfr IAP_TRIG = 0xC6; //Flash command trigger
  42. sfr IAP_CONTR= 0xC7; //Flash control register

  43. /*Define ISP/IAP/EEPROM command*/
  44. #define CMD_IDLE 0 //Stand-By
  45. #define CMD_READ 1 //unsigned char-Read
  46. #define CMD_PROGRAM 2 //unsigned char-Program
  47. #define CMD_ERASE 3 //Sector-Erase
  48. /*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/
  49. #define ENABLE_IAP 0x84 //SYSCLK<6MHz

  50. /*Define Which Command that Received to Reboot System*/
  51. #define REBOOT_CMD 0xF4
  52. //#define REBOOT_CMD 0x00 //STC-ISP Default Download Command
  53. /*Define if the Sysytem will Reboot after Sent Command*/
  54. #define REBOOT_CTRL 1        //Rebot
  55. //#define REBOOT_CTRL 0        //not reboot
  56. /*Define the Different ways to reboot*/
  57. #define REBOOT_WAY 0x60          //From ISP
  58. //#define REBOOT_WAY 0x20 //

  59. sbit S1  = P4^0;//Key1
  60. sbit CLK = P1^0;//ICL7135 Clock
  61. sbit BSY = P1^1;//ICL7135 BUSY signal
  62. sbit POL = P1^2;//ICL7135 Polarity output
  63. sbit RH  = P1^3;//ICL7135 Run/Hold
  64. sbit STB = P3^2;//ICL7135 STROBE signal
  65. sbit OVR = P1^4;//ICL7135 Over Range signal
  66. sbit UNR = P1^5;//ICL7135 Under Range signal
  67. sbit LED = P1^6;//LEDs
  68. sbit D1  = P3^6;//Seven-Segment LED, the right the first
  69. sbit D2  = P3^7;
  70. sbit D3  = P3^5;
  71. sbit D4  = P3^4;
  72. sbit D5  = P1^7;

  73. /*For Seven segment LED display*/
  74. unsigned char code Led_Dsp[]={
  75. 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,//0-7
  76. 0x7F,0x6F,0x77,0x7C,0x58,0x5E,0x79,0x71,//8-F
  77. 0x39,0x3D,0x74,0x76,0x30,//0x39-C,0x3D-G,0x74-h,0x76-H,0x30-I
  78. //20
  79. 0x0E,0x38,0x54,0x5C,0x73,//0x0E-J,0x38-L,0x54-n,0x5C-o,0x73-P
  80. 0x67,0x50,0x6D,0x78,0x1C,//0x67-q,0x50-r,0x6D-S,0x78-t,0x1C-u
  81. //30
  82. 0x3E,0x6E,0x00,0x40,0x0C},//0x3E-U,0x6E-y,0x00-,0x40--,0x0C-
  83. /*Menu Display data*/
  84. MenuDat[][6]={
  85. 0x00,27,14,11,24,29,//rEbot LEDx                0
  86. 0x01,28,14,23,13,33,//SEnd        LED1                1
  87. 0x03,28, 1,28,14,29,//S1SEt LED1-2                2
  88. 0x07,13,25,28,14,29,//dpSEt LED1-3                3
  89. 0x0F,15,26,28,14,29,//FqSEt LED1-4                4
  90. 0x1F,28,34,28,14,29,//S-SEt LED1-5                5
  91. 0x3F,26,31,20,29,33,//qUIt  LED1-6                6
  92. 0x7F,27,14,28,14,29,//rESEt LED1-7                 7
  93. 0xAA,33, 0,15,15,33,// OFF        LED2,4,6,8        8
  94. 0x55,33, 0,23,33,33,// On        LED1,3,5,7  9
  95. 0x10,0x20,0x40,0x80,0,0x01,//For LED        10
  96. 0x11,15,33,33,33, 4,//F   4 LED1,5                11
  97. 0x22,15,33,33, 1, 0,//F  10 LED2,6
  98. 0x33,15,33,33, 5, 0,//F  50 LED
  99. 0x44,15,33, 1, 0, 0,//F 100 LED
  100. 0x55,15,33, 1, 2, 0,
  101. 0x66,15,33, 1, 2, 5,
  102. 0x77,15,33, 1, 5, 0,
  103. 0x88,15,33, 2, 5, 0,
  104. 0x99,15,33, 3, 0, 0,
  105. 0xAA,15,33, 5, 0, 0,
  106. 0xBB,15,33, 6, 0, 0,
  107. 0xCC,15, 1, 0, 0, 0,
  108. 0xDD,15, 1, 5, 0, 0,//F1500 LED                        23
  109. 0xFF,28,30,12,12,14,//SuccE LED1-8                24
  110. 0xA5,14,27,27,24,27 //Error LED1,3,6,8        25
  111. };

  112. unsigned char
  113. Dat[]={0,1,2,3,4,5,0},//ICL7135 Digital output with Polatity
  114. //Data formate: POL MSD ... LSD LED
  115. DatSend[]={0xFF,0xEE,0xEE,0xEE,0x00,0xAA},//Data for send
  116. //Data format:0xff H=POL/OVR L-MSB+0x0E ... L-LSB CRC8 0xAA
  117. DatRom[]={0,0,0},//Data for EEPROM
  118. //Data format H-Send,L-S1;H-Dp,L-CLK;CRC
  119. Dp,//Decimal point setting,0 is the left
  120. ADCLK,//ICL7135 Clock Settings
  121. i,
  122. countdwn0,//Use for timing or countdown
  123. sendjud,//Send Data        judgment and countdown
  124. Keyjud,//For key and menu
  125. dispmod,//Display Mode
  126. dispcnt,//For display
  127. S1Func;//S1 Func

  128. bit
  129. readjud,//Read ICL7135 data judgment
  130. KeyScanjud,//Key scan judgment
  131. KeyLong, //Key
  132. KeyShort,
  133. sendctrl,//Send data control
  134. sndctldsp,//Send data control for display
  135. readadctrl;//Read AD Status        control

  136. /*---------------------------------------------
  137. Software Delay Function

  138. Input  char        for different delay time
  139. Output void
  140. ---------------------------------------------*/
  141. void Delay(char xx)
  142. {
  143.         unsigned int y;
  144.         switch (xx)
  145.         {
  146.                 case 0:         //For Init Function and Key scan
  147.                         {
  148.                                 for(xx=0;xx++;xx<255)
  149.                                         for(y=0;y++;y<255);
  150.                         }break;
  151.                 case 1:          //For LED Display
  152.                         {
  153.                                 xx=1;
  154.                                 while(xx--)
  155.                                 {
  156.                                         y=65500;
  157.                                         while(++y);
  158.                                 }
  159.                         }break;
  160.                 case 2:         //For Reboot
  161.                         {
  162.                                 xx=8;
  163.                                 while(xx--)
  164.                                 {
  165.                                         y=0;
  166.                                         while(++y);
  167.                                 }
  168.                         }break;
  169.         }
  170. }

  171. /*----------------------------
  172. Disable ISP/IAP/EEPROM function

  173. Make MCU in a safe state
  174. ----------------------------*/
  175. void IapIdle()
  176. {
  177.         IAP_CONTR = 0; //Close IAP function
  178.         IAP_CMD = 0; //Clear command to standby
  179.         IAP_TRIG = 0; //Clear trigger register
  180.         IAP_ADDRH = 0x80; //Data ptr point to non-EEPROM area
  181.         IAP_ADDRL = 0; //Clear IAP address to prevent misuse
  182. }

  183. /*----------------------------
  184. Read one unsigned char from ISP/IAP/EEPROM area

  185. Input: addr (ISP/IAP/EEPROM address)
  186. Output:Flash data
  187. ----------------------------*/
  188. unsigned char IapReadByte(unsigned int addr)
  189. {
  190.         unsigned int dat1; //Data buffer
  191.         IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
  192.         IAP_CMD = CMD_READ; //Set ISP/IAP/EEPROM READ command
  193.         IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
  194.         IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
  195.         IAP_TRIG = 0x5a; //Send trigger command1 (0x5a)
  196.         IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
  197.         _nop_(); //MCU will hold here until ISP/IAP/EEPROM
  198.         //operation complete
  199.         dat1 = IAP_DATA; //Read ISP/IAP/EEPROM data
  200.         IapIdle(); //Close ISP/IAP/EEPROM function
  201.         return dat1; //Return Flash data
  202. }

  203. /*----------------------------
  204. Program one unsigned char to ISP/IAP/EEPROM area

  205. Input:  addr (ISP/IAP/EEPROM address)
  206.                 dat (ISP/IAP/EEPROM data)
  207. Output: void
  208. ----------------------------*/
  209. void IapProgramByte(unsigned int addr, unsigned char dat2)
  210. {
  211.         IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
  212.         IAP_CMD = CMD_PROGRAM; //Set ISP/IAP/EEPROM PROGRAM command
  213.         IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
  214.         IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
  215.         IAP_DATA = dat2; //Write ISP/IAP/EEPROM data
  216.         IAP_TRIG = 0x5a; //Send trigger command1 (0x5a)
  217.         IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
  218.         _nop_(); //MCU will hold here until ISP/IAP/EEPROM
  219.         //operation complete
  220.         IapIdle();
  221. }

  222. /*----------------------------
  223. Erase one sector area

  224. Input: addr (ISP/IAP/EEPROM address)
  225. Output:void
  226. ----------------------------*/
  227. void IapEraseSector(unsigned int addr)
  228. {
  229.         IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
  230.         IAP_CMD = CMD_ERASE; //Set ISP/IAP/EEPROM ERASE command
  231.         IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
  232.         IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
  233.         IAP_TRIG = 0x5a; //Send trigger command1 (0x5a)
  234.         IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
  235.         _nop_(); //MCU will hold here until ISP/IAP/EEPROM
  236.         //operation complete
  237.         IapIdle();
  238. }

  239. /*----------------------------
  240. CRC sector area

  241. Input: *p len
  242. Output:CRC
  243. ----------------------------*/
  244. unsigned char CRC8(unsigned char *ptr,unsigned char len)  
  245. {
  246.         unsigned char crc=0;
  247.         while(len--!=0)
  248.         {
  249.                 for(i=0x80;i!=0;i=i>>1)
  250.                 {
  251.                         if((crc&0x80)!=0)
  252.                         {
  253.                                 crc=crc<<1;
  254.                                 crc^=0x5E;
  255.                         } /* 余式CRC 乘以2 再求CRC */
  256.                         else crc=crc<<1;
  257.                         if((*ptr&i)!=0)crc^=0x5E; /* 再加上本位的CRC */
  258.                 }
  259.                 ptr++;
  260.         }
  261.         return crc;
  262. }
  263. /*---------------------------------------------
  264. Reboot Function

  265. Reboot the system

  266. Input  void
  267. Output void
  268. ---------------------------------------------*/
  269. void Reboot(void)
  270. {
  271.         P2=0x40;
  272.         D1=D3=D5=D2=D4=0;
  273.         Delay(2);
  274.         IAP_CTRL=REBOOT_WAY;        
  275. }
  276. /*---------------------------------------------
  277. Read AD Status Function

  278. Read Status for ICL7135, then write to Dat[]

  279. Input  unsigned char
  280. Output void
  281. ---------------------------------------------*/
  282. void ReadAD(bit yy)
  283. {
  284.         if (yy)
  285.         {
  286.                 Dat[0]=POL;
  287.                 if(BSY)Dat[6]=Dat[6]|0x01;
  288.                         else Dat[6]=Dat[6]&0xFE;
  289.                 if(OVR)                                                 //Over Range
  290.                 {
  291.                         Dat[6]=Dat[6]|0x10;
  292.                         DatSend[1]|=0xE0;
  293.                         dispmod=2;
  294.                 }
  295.                 else
  296.                 {
  297.                         Dat[6]=Dat[6]&0xEF;
  298.                         DatSend[1]&=0x0F;
  299.                         dispmod=0;
  300.                 }
  301.                 if(UNR)Dat[6]=Dat[6]|0x20;         //Under Range
  302.                         else Dat[6]=Dat[6]&0xDF;
  303.                 if(!RH)Dat[6]=Dat[6]|0x02;         //Run/Hold
  304.                         else Dat[6]=Dat[6]&0xFD;
  305.         }
  306. }

  307. /*---------------------------------------------
  308. Data Convert Function

  309. Convert ICL7135 output to an int number
  310. Directly use Dat[]

  311. Input  void
  312. Output int
  313. ---------------------------------------------*/
  314. void DataConvt(void)
  315. {
  316.         DatSend[1]=Dat[0]<<4;
  317.         DatSend[1]=DatSend[1]+Dat[1]+0x0E;
  318.         if(OVR)DatSend[1]|=0xE0; //Over Range
  319.         DatSend[2]=Dat[2]<<4;
  320.         DatSend[2]=DatSend[2]+Dat[3];
  321.         DatSend[3]=Dat[4]<<4;
  322.         DatSend[3]=DatSend[3]+Dat[5];
  323.         DatSend[4]=CRC8(&DatSend[0],4);
  324. }

  325. /*---------------------------------------------
  326. ICL7135 Clock Set Function

  327. MCU should run at 6MHz

  328. Input  unsigned char
  329. Output void
  330. ---------------------------------------------*/
  331. void AD_Clock(unsigned char clk)
  332. {
  333.         AUXR&=0xEF;//Stop the Independent Baud Rate Generator
  334.         AUXR|=0x04;//SysCLK divide by 1
  335.         switch (clk)
  336.         {
  337.                 case 1://4kHz
  338.                 {
  339.                         AUXR&=0xF3;//SysCLK divide by 12
  340.                         BRT=0xFA;//250
  341.                 }break;
  342.                 case 2://10kHz
  343.                 {
  344.                         AUXR&=0xFB;//SysCLK divide by 12
  345.                         BRT=0xE7;//231
  346.                 }break;
  347.                 case  3:BRT=0xC4;break;//   50kHz 196
  348.                 case  4:BRT=0xE2;break;//  100kHz 226
  349.                 case  5:BRT=0xE7;break;//  120kHz 231
  350.                 case  6:BRT=0xE8;break;//  125kHz 232
  351.                 case  7:BRT=0xEC;break;//  150kHz 236
  352.                 case  8:BRT=0xF4;break;//  250kHz 244
  353.                 case  9:BRT=0xF6;break;//  300kHz 246
  354.                 case 10:BRT=0xFA;break;//  500kHz 250
  355.                 case 11:BRT=0xFB;break;//  600kHz 251
  356.                 case 12:BRT=0xFD;break;//1,000kHz 253
  357.                 case 13:BRT=0xFE;break;//1,500kHz 254
  358.         }
  359.         AUXR|=0x10;//Run the Independent Baud Rate Generator
  360. }

  361. /*---------------------------------------------
  362. Display Function

  363. Dynamic scanning of the digital

  364. Input  char display mode
  365. Output void
  366. ---------------------------------------------*/
  367. void Display(char k)
  368. {
  369.         D5=D4=D3=D2=D1=LED=1;
  370.         switch (k)
  371.         {
  372.                 case 0://Normal display
  373.                 {
  374.                         P2=Led_Dsp[Dat[dispcnt]];
  375.                         switch (dispcnt)
  376.                         {
  377.                         case 0:
  378.                         {
  379.                                 P2=Dat[6];//LED
  380.                                 LED=0;
  381.                         }break;
  382.                         case 1:
  383.                         {
  384.                                 if(!Dat[1])P2=0x00;//The Left Digit
  385.                                 if(!Dat[0])P2=P2+0x40;
  386.                                 D5=0;
  387.                         }break;
  388.                         case 2:D4=0;break;
  389.                         case 3:D3=0;break;
  390.                         case 4:D2=0;break;
  391.                         case 5:D1=0;break;
  392.                         case 6:
  393.                         {
  394.                                 P2=0x80;                           //Decimal point
  395.                                 switch (Dp)
  396.                                 {
  397.                                         case 0:D5=0;break;
  398.                                         case 1:D4=0;break;
  399.                                         case 2:D3=0;break;
  400.                                         case 3:D2=0;break;
  401.                                         case 4:D1=0;break;
  402.                                 }
  403.                         }break;
  404.                         }
  405.                 }break;
  406.                 case 1://Menu display
  407.                 {
  408.                         if(countdwn0>80)Reboot();//Quite Menu if timeout
  409.                         P2=Led_Dsp[Dat[dispcnt]];
  410.                         if(!dispcnt)P2=Dat[0];
  411.                         switch (dispcnt)
  412.                         {
  413.                         case 0:LED=0;break;
  414.                         case 1:D5=0;break;
  415.                         case 2:D4=0;break;
  416.                         case 3:D3=0;break;
  417.                         case 4:D2=0;break;
  418.                         case 5:D1=0;break;
  419.                         case 6:
  420.                         {
  421.                                 P2=0x80;                           //Decimal point
  422.                                 switch (Keyjud)
  423.                                 {
  424.                                         case 1:D2=0;break;
  425.                                         case 2:D4=0;break;
  426.                                         case 3:D4=0;break;
  427.                                         case 4:D4=0;break;
  428.                                         case 5:D5=0;break;
  429.                                         case 6:D2=0;break;
  430.                                         case 7:D1=0;break;
  431.                                         case 0xF3:
  432.                                         {
  433.                                                 switch (Dp)
  434.                                                 {
  435.                                                         case 0:D5=0;break;
  436.                                                         case 1:D4=0;break;
  437.                                                         case 2:D3=0;break;
  438.                                                         case 3:D2=0;break;
  439.                                                         case 4:D1=0;break;
  440.                                                 }
  441.                                         }break;
  442.                                         case 0xF4:D5=0;break;
  443.                                 }
  444.                         }break;
  445.                         }
  446.                 }break;
  447.                 case 2://O.L. display
  448.                 {
  449.                         switch(dispcnt)
  450.                         {
  451.                                 case 1:
  452.                                 {
  453.                                         P2=Dat[6];
  454.                                         LED=0;
  455.                                 }break;
  456.                                 case 2:
  457.                                 {
  458.                                         P2=Led_Dsp[0]+0x80;
  459.                                         D2=0;
  460.                                 }break;
  461.                                 case 3:
  462.                                 {
  463.                                         P2=Led_Dsp[22]+0x80;
  464.                                         D1=0;
  465.                                         dispcnt=0;
  466.                                 }break;
  467.                         }
  468.                 }break;
  469.         }
  470.         Delay(1);
  471.         dispcnt++;
  472.         if(dispcnt>6)dispcnt=0;
  473. }

  474. /*---------------------------------------------
  475. Display Menu Function

  476. Write Menu display data to Dat[]

  477. Input  void
  478. Output void
  479. ---------------------------------------------*/
  480. void DispMenu(void)
  481. {
  482.         if(Keyjud>0&&Keyjud<0x10)for(i=0;i<7;i++)Dat[i]=MenuDat[Keyjud][i];//For Display
  483.         else
  484.         {
  485.                 switch (Keyjud)
  486.                 {
  487.                 case 0xF1://Send or not
  488.                         {
  489.                                 for(i=0;i<7;i++)
  490.                                 {
  491.                                         if(sndctldsp)Dat[i]=MenuDat[9][i];
  492.                                                 else Dat[i]=MenuDat[8][i];
  493.                                 }
  494.                         }break;
  495.                 case 0xF2:;break;//S1.Set Func is reserved for future use
  496.                 case 0xF3://Dp position
  497.                         {
  498.                                 for(i=0;i<7;i++)Dat[i]=33;
  499.                                 Dat[Dp+1]=35;
  500.                                 Dat[0]=MenuDat[10][Dp];
  501.                         }break;
  502.                 case 0xF4:for(i=0;i<7;i++)Dat[i]=MenuDat[ADCLK+10][i];break;//CLK
  503.                 }
  504.         }
  505. }
  506. /*---------------------------------------------
  507. Serial communication Function

  508. Send One Byte Data using UART

  509. Input  unsigned char
  510. Output void
  511. ---------------------------------------------*/
  512. void SendOneByte(unsigned char xx)
  513. {
  514.         SBUF=xx;
  515.         while(!TI);
  516.         TI=0;
  517. }

  518. /*---------------------------------------------
  519. Data Send Function

  520. Send AD Data using UART

  521. Input  void
  522. Output void
  523. ---------------------------------------------*/
  524. void SendData(bit y)
  525. {
  526.         if(y)
  527.         {
  528.                 if(!BSY&&sendjud)
  529.                 {
  530.                         DataConvt();
  531.                         SendOneByte(DatSend[sendjud-1]);
  532.                         sendjud++;        //send only one byte per scan
  533.                         if(sendjud>6)sendjud=0;
  534.                 }
  535.                 if(BSY)sendjud=1;
  536.                 if(!RH&&!dispcnt)SendOneByte(0xF0);
  537.         }
  538. }

  539. /*---------------------------------------------
  540. Reset Settings Function

  541. Just reset the settings in EEPROM

  542. Input  unsigned char MenuDat[?][]
  543. Output void
  544. ---------------------------------------------*/
  545. void Reset(unsigned char y)
  546. {
  547.         countdwn0=0;
  548.         IapEraseSector(0x0800);
  549.         DatRom[0]=0x01;//Default not Send data, S1Func reserved for future use
  550.         DatRom[1]=0x04;//Default decimal point at the most significant digit
  551.                                    //ICL7135 default run at 100kHz
  552.         DatRom[2]=CRC8(&DatRom[0],2);
  553.         for(i=0;i<4;i++)IapProgramByte(0x0800+i,DatRom[i]);
  554.         for(i=0;i<7;i++)Dat[i]=MenuDat[y][i];
  555.         Keyjud=7;
  556.         while(countdwn0<20)
  557.         {
  558.                 Display(1);
  559.         }
  560.         Reboot();
  561. }
  562. /*---------------------------------------------
  563. Settings Function

  564. Read, check, Save or reset settings
  565. or reboot(Quit Menu) the System

  566. Input  unsigned char
  567. Output void
  568. ---------------------------------------------*/
  569. void Settings(unsigned char yy)
  570. {
  571.         switch (yy)
  572.         {
  573.                 case 0://Check settings while Init
  574.                 {
  575.                         for(i=0;i<3;i++)DatRom[i]=IapReadByte(0x0800+i);
  576.                         if(DatRom[2]!=CRC8(&DatRom[0],2))
  577.                         {
  578.                                 Reset(25);
  579.                         }
  580.                         else
  581.                         {
  582.                                 S1Func=DatRom[0]&0x0F;
  583.                                 sendctrl=DatRom[0]>>4;
  584.                                 ADCLK=DatRom[1]&0x0F;
  585.                                 Dp=DatRom[1]>>4;
  586.                         }
  587.                 }break;
  588.                 case 1://Save settings
  589.                 {
  590.                         countdwn0=0;
  591.                         IapEraseSector(0x0800);
  592.                         if(sndctldsp)DatRom[0]=0x10;
  593.                                 else DatRom[0]=0x00;
  594.                         DatRom[0]|=S1Func;
  595.                         DatRom[1]=Dp<<4;
  596.                         DatRom[1]|=ADCLK;
  597.                         DatRom[2]=CRC8(&DatRom[0],2);
  598.                         for(i=0;i<4;i++)IapProgramByte(0x0800+i,DatRom[i]);
  599.                         for(i=0;i<7;i++)Dat[i]=MenuDat[24][i];
  600.                         Keyjud=7;
  601.                         while(countdwn0<20)
  602.                         {
  603.                                 Display(1);
  604.                         }
  605.                         Reboot();
  606.                 }break;
  607.                 case 2://Quit(Reboot Sysytem)
  608.                 {
  609.                         Reboot();
  610.                 }break;
  611.                 case 3://Reset settings
  612.                 {
  613.                         Reset(24);
  614.                 }break;
  615.         }
  616. }
  617. /*---------------------------------------------
  618. Key Scan Function

  619. Input  void
  620. Output void
  621. ---------------------------------------------*/
  622. void KeyScan(void)
  623. {
  624.         if(!S1)
  625.         {
  626.                 Delay(0);
  627.                 if(!S1)                   //>2s Long time
  628.                 {
  629.                         if(!KeyScanjud)
  630.                         {
  631.                                 countdwn0=0;
  632.                                 KeyScanjud=1;
  633.                         }
  634.                 }
  635.                 if(countdwn0>12)  //Light a LED
  636.                 {
  637.                         switch (dispmod)
  638.                         {
  639.                         case 0:Dat[6]=0xFF;break;
  640.                         case 1:Dat[0]=0xFF;break;
  641.                         }
  642.                 }
  643.         }
  644.         else                   //<2S Short time
  645.         {
  646.                 if(KeyScanjud)
  647.                 {
  648.                         if(countdwn0>12)KeyLong=1;
  649.                                 else KeyShort=1;
  650.                         KeyScanjud=0;
  651.                 }
  652.         }
  653. }

  654. /*---------------------------------------------
  655. Key Function

  656. Input  void
  657. Output void
  658. ---------------------------------------------*/
  659. void KeyFunc(void)
  660. {
  661.         if(KeyLong)                        //For Long Key
  662.         {
  663.                 if(!Keyjud)
  664.                 {
  665.                         Keyjud=1;
  666.                         EX0=0;//STOP read data from AD
  667.                         readadctrl=0;//Stop read status from AD
  668.                         dispmod=1;//Change Display Mode to Menu
  669.                         sndctldsp=sendctrl;
  670.                         sendctrl=0;
  671.                 }
  672.                 else
  673.                 {
  674.                         if(Keyjud<5)Keyjud|=0xF0;
  675.                         else if(Keyjud>0xF0){if(Keyjud<0xF5)Keyjud&=0x0F;}
  676.                         else if(Keyjud<0x10)Settings(Keyjud-4);
  677.                         if(Keyjud==0xF2)Keyjud=0x02;//S1.Set Func is reserved for future use
  678.                 }
  679.                 DispMenu();
  680.                 KeyLong=0;
  681.         }
  682.         
  683.         if(KeyShort)                   //For Short Key
  684.         {
  685.                 if(!Keyjud)RH=!RH;
  686.                 else if(Keyjud<0x10)
  687.                 {
  688.                         Keyjud++;
  689.                         if(Keyjud>7)Keyjud=1;
  690.                 }
  691.                 else if(Keyjud>0xF0)
  692.                 {
  693.                         switch (Keyjud)
  694.                         {
  695.                         case 0xF1:sndctldsp=!sndctldsp;break;//Send dat or not
  696.                         case 0xF2:;break;//S1.Set Func is reserved for future use
  697.                         case 0xF3:{Dp++;if(Dp>4)Dp=0;}break;//Dp position
  698.                         case 0xF4:{ADCLK++;if(ADCLK>13)ADCLK=1;}break;//AD CLK
  699.                         }
  700.                 }
  701.                 DispMenu();
  702.                 KeyShort=0;
  703.         }
  704. }

  705. /*---------------------------------------------
  706. Initialization Function

  707. Input  void
  708. Output void
  709. ---------------------------------------------*/
  710. void Init(void)
  711. {
  712.         CLK_DIV=0x00;//System run at 6MHz
  713.         WAKE_CLKO=0x04;//Set the P1.0 pin as the independent Baud Rate Generator clock output
  714.         P4SW =0x70;//Set P4.4 P4.5 P4.6 to IO Prot
  715.         P0M1 =0xFF;//Set P0 Prot to HZ input
  716.         P0M0 =0x00;
  717.         P1M1 =0XF6;//Set P1.0 P1.3 to IO, P1.6-P1.7 to Open Drain, others to HZ
  718.         P1M0 =0XC0;
  719.         P2M1 =0x00;//Set P2 Port to Pull Push Output
  720.         P2M0 =0xFF;
  721.         P3M1 =0xF4;//Set P3.4-P3.7 to Open Drain, P3.2 to HZ, others to IO
  722.         P3M0 =0xF0;
  723.         P4M1 =0xE6;//Set P1.0 P4.3 P4.4 Prot to IO, others to HZ
  724. ……………………

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

所有資料51hei提供下載:



回復(fù)

使用道具 舉報(bào)

ID:47634 發(fā)表于 2017-8-3 07:06 | 顯示全部樓層
很好很好,學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:249545 發(fā)表于 2017-11-26 22:09 | 顯示全部樓層
用英特希爾的ICL7135制做4位電壓電流表,比ICL7107的3位高端了10倍!
回復(fù)

使用道具 舉報(bào)

ID:249545 發(fā)表于 2017-11-26 22:10 | 顯示全部樓層
感謝樓主老師分享ICL7135 4位表制做資料!
回復(fù)

使用道具 舉報(bào)

ID:283207 發(fā)表于 2018-2-9 13:01 | 顯示全部樓層
感謝樓主分享ICL7135 4位表制做資料,程序已下載,仔細(xì)學(xué)習(xí)。
回復(fù)

使用道具 舉報(bào)

ID:289512 發(fā)表于 2018-3-9 09:32 | 顯示全部樓層
很好的方案,謝謝樓主分享。
回復(fù)

使用道具 舉報(bào)

ID:320325 發(fā)表于 2018-5-17 17:45 | 顯示全部樓層
好東西,已收藏;
回復(fù)

使用道具 舉報(bào)

ID:52915 發(fā)表于 2018-7-6 11:58 | 顯示全部樓層
太好了,謝謝分享!
回復(fù)

使用道具 舉報(bào)

ID:61493 發(fā)表于 2018-11-19 08:09 | 顯示全部樓層
感謝樓主分享ICL7135 4位表制做資料,學(xué)習(xí)學(xué)習(xí)。
回復(fù)

使用道具 舉報(bào)

ID:428400 發(fā)表于 2018-11-24 19:46 | 顯示全部樓層
有去做PCB嗎?
回復(fù)

使用道具 舉報(bào)

ID:74143 發(fā)表于 2018-12-10 21:49 | 顯示全部樓層
謝謝樓主分享。
回復(fù)

使用道具 舉報(bào)

ID:162957 發(fā)表于 2018-12-11 17:33 | 顯示全部樓層

謝謝樓主分享。
回復(fù)

使用道具 舉報(bào)

ID:103151 發(fā)表于 2018-12-25 22:06 | 顯示全部樓層
非常好的資料
回復(fù)

使用道具 舉報(bào)

ID:205532 發(fā)表于 2019-1-18 09:41 | 顯示全部樓層
好資料,感謝樓主分享啊
回復(fù)

使用道具 舉報(bào)

ID:73762 發(fā)表于 2019-1-29 09:49 | 顯示全部樓層
能分享PCB文件嗎,手頭有7135,向做一個(gè)
回復(fù)

使用道具 舉報(bào)

ID:474288 發(fā)表于 2019-1-31 10:36 | 顯示全部樓層
多謝樓主分享  辛苦
回復(fù)

使用道具 舉報(bào)

ID:467275 發(fā)表于 2019-3-28 15:09 | 顯示全部樓層
很好很好,學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:168038 發(fā)表于 2019-4-11 08:38 | 顯示全部樓層
如果能分享PCB文件就好了,剛好手頭有7135
回復(fù)

使用道具 舉報(bào)

ID:42468 發(fā)表于 2019-9-12 17:04 | 顯示全部樓層
學(xué)習(xí)了,單獨(dú)用TCL7135可以做數(shù)顯4位半電壓電流表嗎
回復(fù)

使用道具 舉報(bào)

ID:618416 發(fā)表于 2019-10-5 06:25 | 顯示全部樓層
非常感謝學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:149799 發(fā)表于 2019-10-8 13:41 | 顯示全部樓層
學(xué)習(xí)了,程序好復(fù)雜啊
回復(fù)

使用道具 舉報(bào)

ID:491577 發(fā)表于 2019-10-11 17:59 | 顯示全部樓層
樓主的數(shù)碼管都是單片機(jī)IO直接驅(qū)動(dòng),8個(gè)LED全亮?xí)r電流大于50mA,樓主不擔(dān)心單片機(jī)會(huì)掛掉嗎?
回復(fù)

使用道具 舉報(bào)

ID:491577 發(fā)表于 2019-10-11 18:06 | 顯示全部樓層
樓主的電源用料差了點(diǎn)吧,模擬、數(shù)字部分公用一個(gè)電源想要達(dá)到4位半的精度有點(diǎn)難,起碼用兩塊穩(wěn)壓芯片分開供電。
回復(fù)

使用道具 舉報(bào)

ID:11393 發(fā)表于 2019-11-15 20:22 | 顯示全部樓層
很好很好,學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:106489 發(fā)表于 2019-12-24 10:11 | 顯示全部樓層
謝謝分享!正好需要學(xué)習(xí)這個(gè)芯片!
回復(fù)

使用道具 舉報(bào)

ID:671776 發(fā)表于 2019-12-30 15:14 | 顯示全部樓層
多謝樓主分享,學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:60026 發(fā)表于 2020-1-22 16:23 | 顯示全部樓層
看看學(xué)習(xí)下!謝謝分享!
回復(fù)

使用道具 舉報(bào)

ID:361863 發(fā)表于 2020-4-18 20:17 | 顯示全部樓層
好好學(xué)習(xí)研究一下
回復(fù)

使用道具 舉報(bào)

ID:507641 發(fā)表于 2020-7-1 22:03 | 顯示全部樓層
做電子需要高精度電壓表,謝謝分享!學(xué)習(xí)又可以有工具。強(qiáng)!
回復(fù)

使用道具 舉報(bào)

ID:413201 發(fā)表于 2021-6-9 00:31 | 顯示全部樓層
沒(méi)有圖紙?zhí)峁┫螺d嗎?
回復(fù)

使用道具 舉報(bào)

ID:97023 發(fā)表于 2021-6-29 10:59 | 顯示全部樓層
hhh402 發(fā)表于 2019-10-11 17:59
樓主的數(shù)碼管都是單片機(jī)IO直接驅(qū)動(dòng),8個(gè)LED全亮?xí)r電流大于50mA,樓主不擔(dān)心單片機(jī)會(huì)掛掉嗎?

動(dòng)態(tài)掃描LED,任意時(shí)刻只有一個(gè)在工作。
回復(fù)

使用道具 舉報(bào)

ID:1013588 發(fā)表于 2022-9-23 20:40 | 顯示全部樓層
要做一個(gè)電壓實(shí)時(shí)顯示,做一個(gè)試試,樓主牛
回復(fù)

使用道具 舉報(bào)

ID:1052903 發(fā)表于 2022-12-29 12:00 | 顯示全部樓層
感謝樓主分享ICL7135 4位表
回復(fù)

使用道具 舉報(bào)

ID:1083475 發(fā)表于 2023-6-12 08:30 | 顯示全部樓層
提示: 作者被禁止或刪除 內(nèi)容自動(dòng)屏蔽
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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