摘 要:文章介紹了用AT89S8252單片機(jī)的串行接口與智能溫度巡回檢測(cè)儀(XJ-08S)通過(guò)RS—485總線相互通訊實(shí)現(xiàn)熱水溫度遠(yuǎn)程顯示的一種低成本解決方案,內(nèi)容涉及RS—485總線通訊、單片機(jī)驅(qū)動(dòng)數(shù)碼管顯示、數(shù)據(jù)轉(zhuǎn)換以及鍵盤(pán)處理軟硬件設(shè)計(jì)等內(nèi)容。
關(guān)鍵詞:?jiǎn)纹瑱C(jī) RS—485總線 數(shù)碼管顯示 數(shù)據(jù)轉(zhuǎn)換 鍵盤(pán)處理
一、前 言 目前檢測(cè)溫度一般采用熱電偶或熱敏電阻作為傳感器,這種傳感器至儀表之間一般都要用專(zhuān)用的溫度補(bǔ)償導(dǎo)線,而溫度補(bǔ)償導(dǎo)線價(jià)格很貴,并且線路太長(zhǎng)也會(huì)影響測(cè)量精度。在實(shí)際應(yīng)用中往往需要對(duì)較遠(yuǎn)處(1KM左右)的溫度信號(hào)進(jìn)行監(jiān)視,F(xiàn)有的解決方案有很多,例如:
1、 在現(xiàn)場(chǎng)用智能儀表對(duì)溫度信號(hào)進(jìn)行測(cè)量,用計(jì)算機(jī)作上位機(jī)與智能儀表進(jìn)行通訊來(lái)實(shí)現(xiàn)遠(yuǎn)程溫度監(jiān)測(cè)(采用這種方案要增加計(jì)算機(jī)設(shè)備及相關(guān)計(jì)算機(jī)軟件)。
2、 NCU+DDC實(shí)現(xiàn)遠(yuǎn)程溫度監(jiān)測(cè)。用兩個(gè)DDC,一個(gè)安裝在現(xiàn)場(chǎng)測(cè)量溫度,另一個(gè)安裝在監(jiān)視地,兩個(gè)DDC通過(guò)NCU進(jìn)行通訊從而實(shí)現(xiàn)遠(yuǎn)程溫度監(jiān)測(cè)。
但以上方案都存在成本高的問(wèn)題,有沒(méi)有低成本的解決方案呢?其實(shí),在單片機(jī)應(yīng)用日益廣泛的今天,完全可以用單片機(jī)以極低的成本來(lái)實(shí)現(xiàn)遠(yuǎn)程溫度監(jiān)測(cè)。
二、問(wèn)題的提出 我單位管理的鍋爐房同時(shí)給兩棟建筑物內(nèi)的兩家酒店供應(yīng)蒸汽,由安裝在兩棟建筑物地下室的熱交換器進(jìn)行熱交換后產(chǎn)生熱水送給客房。從鍋爐房至兩個(gè)熱交換站的距離分別約600米,值班人員要不停地奔波于兩個(gè)熱交換站與鍋爐房之間進(jìn)行設(shè)備巡視,檢查熱水溫度是否控制在規(guī)定的范圍,這樣不僅增加了值班人員的勞動(dòng)強(qiáng)度,同時(shí)也使鍋爐房經(jīng)常無(wú)人(因每班1人值班)。如果能在鍋爐房顯示兩個(gè)熱交換站內(nèi)各熱交換器的熱水溫度,則值班人員僅在熱水溫度異常時(shí)才需到各熱交換站檢查設(shè)備,這樣便可解決上述問(wèn)題。我公司曾就此問(wèn)題找專(zhuān)業(yè)公司作過(guò)方案,其報(bào)價(jià)在人民幣10萬(wàn)元左右,后因種種原因該項(xiàng)目未實(shí)施。經(jīng)過(guò)分析,本人發(fā)現(xiàn)可以用單片機(jī)+智能儀表以低成本實(shí)現(xiàn)溫度遠(yuǎn)程顯示,并且經(jīng)過(guò)實(shí)驗(yàn)取得了成功,現(xiàn)將設(shè)計(jì)方案簡(jiǎn)述如下:
三、控制要求及解決方案選擇 1、 兩個(gè)熱交換站分高低區(qū)共安裝有8個(gè)熱交換器,正常水溫在45oC至65oC之間;兩個(gè)熱交換站與鍋爐房的距離分別為500米和600米左右。
2、 要求在鍋爐房能以巡回及定點(diǎn)兩種方式顯示8個(gè)熱交換器的熱水溫度,巡回方式以3秒為周期輪流更新及顯示各熱交換器熱水溫度。定點(diǎn)方式時(shí)每按上鍵或下鍵一次則顯示上或下一個(gè)熱交換器熱水溫度,每3秒自動(dòng)更新數(shù)據(jù)一次。
3、 根據(jù)控制要求選擇單片機(jī)+智能儀表的解決方案:用帶通訊接口的智能儀表安裝在現(xiàn)場(chǎng)測(cè)量溫度,設(shè)計(jì)制作一個(gè)單片機(jī)裝置完成與智能儀表的通訊及數(shù)據(jù)顯示。
四、通訊協(xié)議、智能儀表選擇及其參數(shù)介紹 因熱水溫度信號(hào)變化較慢,因而對(duì)通信的速度要求不高,對(duì)于這種低速率遠(yuǎn)距離的通訊選用RS-485總線適宜。RS-485是EIA(美國(guó)電子工業(yè)聯(lián)合會(huì))在1983年公布的新的平衡傳輸標(biāo)準(zhǔn),是工業(yè)界使用最為廣泛的雙向、平衡傳輸線標(biāo)準(zhǔn)接口,它以半雙工方式通信,支持多點(diǎn)連接,傳統(tǒng)驅(qū)動(dòng)器允許創(chuàng)建多達(dá)32個(gè)節(jié)點(diǎn)的網(wǎng)絡(luò),且其具有傳輸距離遠(yuǎn)(最大傳輸距離為1200M),傳輸速度快(1200M時(shí)為100KBPS)等優(yōu)點(diǎn)。其連接方法如下圖所示。
D T R R T D D-發(fā)送器
R-接收器
T-接收/發(fā)送器 120Ω 120Ω
為了滿(mǎn)足現(xiàn)場(chǎng)溫度檢測(cè)及與單片機(jī)裝置通訊的要求,必須選擇至少有5個(gè)溫度檢測(cè)點(diǎn)及具有RS—485通訊端口的智能儀表。經(jīng)過(guò)對(duì)市場(chǎng)上常用的溫度檢測(cè)儀進(jìn)行分析,選擇由重慶川儀十八廠生產(chǎn)的XJ-08S型巡回檢測(cè)儀作現(xiàn)場(chǎng)測(cè)量?jī)x表。
(一)該儀表主要特點(diǎn)如下:
1、 多量程方式,熱電偶、熱電阻,1-5V標(biāo)準(zhǔn)信號(hào)混合輸入,可通過(guò)鍵盤(pán)進(jìn)行設(shè)置;
2、 最多8個(gè)測(cè)量通道(能測(cè)量8個(gè)溫度信號(hào));
3、 采用RS-485通訊標(biāo)準(zhǔn),可將各通道最新數(shù)據(jù)向上位機(jī)傳送。
重要的是,該儀表的說(shuō)明書(shū)詳細(xì)介紹了與該儀表進(jìn)行數(shù)據(jù)交換的命令及格式,其通訊協(xié)議也相對(duì)較簡(jiǎn)單,這給我們用單片機(jī)實(shí)現(xiàn)溫度遠(yuǎn)程顯示降減低了難度(雖然有RS-485端口的儀表很多,但大多沒(méi)有通訊命令的詳細(xì)說(shuō)明,給我們用單片機(jī)編程增加了難度)。
(二)XJ-08S巡回檢測(cè)儀通訊協(xié)議
1、通訊口設(shè)置
l 通訊方式:RS-485標(biāo)準(zhǔn)電平
l 同步方式:起停同步方式
l 波特率:9600BPS
l 通訊距離:不大于1200M
l 通訊線:二線
l 數(shù)據(jù)代碼:ASCII碼
l 數(shù)據(jù)格式:每字符10位,1個(gè)起始位,8個(gè)數(shù)據(jù)位,1個(gè)停止位
2、 數(shù)據(jù)傳輸格式
l 地址:2字節(jié)(高字節(jié)在前,低字節(jié)在后);
l 數(shù)據(jù):按地址順序,儀表數(shù)據(jù)傳輸格式為十六進(jìn)制2字節(jié)定點(diǎn)數(shù);
2字節(jié)定點(diǎn)數(shù)=低字節(jié)高4位(ASCII碼)+低字節(jié)低4位(ASCII碼)
高字節(jié)高4位(ASCII碼)+高字節(jié)低4位(ASCII碼)
若數(shù)據(jù)為負(fù)數(shù),則采用補(bǔ)碼方式傳輸;
l 在傳輸實(shí)時(shí)測(cè)量值時(shí),傳輸完2字節(jié)定點(diǎn)數(shù)后,緊接著又傳輸2字節(jié)定點(diǎn)數(shù),其中高字節(jié)低4位為小數(shù)點(diǎn)位數(shù)。
例 :(50.0)10 表示為 46 34 30 31 30 30 30 31
低字節(jié) 高字節(jié) 小數(shù)位數(shù)
3、 儀表通訊格式:
@ DE 幀類(lèi)型 幀數(shù)據(jù) CRC CR
l @ :通訊起始符
l DE :儀表設(shè)備號(hào)(地址)
l 幀類(lèi)型 :操作命令
l 幀數(shù)據(jù) :各種操作命令所對(duì)應(yīng)的命令及數(shù)據(jù)
l CRC :校驗(yàn)字節(jié)(除@外CRC之前的其他幾個(gè)字節(jié)的異或值)
l CR :結(jié)束符(回車(chē)符)
4、應(yīng)用中用到的命令及數(shù)據(jù)格式:
l 讀儀表全部動(dòng)態(tài)數(shù)據(jù)命令幀 @ DE RD CRC CR
l 命令回送幀 正確 @DE RD 幀數(shù)據(jù) CRC CR
錯(cuò)誤 @DE * * CRC CR
例:讀28號(hào)儀表的全部動(dòng)態(tài)數(shù)據(jù)
命令:’@1CRD64’,0D(ASCII碼40 31 43 52 44 36 34 0d)
錯(cuò)誤返回碼 ‘@1C**72’,0D(ASCII碼40 31 43 2A 2A 37 32 0D)
正確返回?cái)?shù)據(jù)’@ 1C RD XXXX XXXX XXXX XXXX XXXX XXXX
第0通道 第1通道 第2通道
XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
第3通道 第4通道 第5通道 第6通道
XXXX XXXX XX’,0D
第7通道 校驗(yàn)
五、單片機(jī)選擇及硬件電路設(shè)計(jì) 1、 選用ATMEL公司生產(chǎn)的AT89S8252-24PC單片機(jī),其主要參數(shù)及特點(diǎn)如下:
l 與MCS-51產(chǎn)品兼容(其引腳圖見(jiàn)原理圖)
l 具有8K字節(jié)可擦寫(xiě)的FLASH內(nèi)部程序存儲(chǔ)器,可擦寫(xiě)1000次;2K字節(jié)EEPROM,可擦寫(xiě)100,000次,SPI口(用PC機(jī)的并口連接5條線即可通過(guò)SPI口下載程序,下載軟件可從網(wǎng)上下載,這樣可節(jié)省購(gòu)買(mǎi)編程器的費(fèi)用;)。
注:筆者現(xiàn)已制作成了ISP2000三合一燒寫(xiě)器,詳情見(jiàn)http://www.mcudiy.com
l 256字節(jié)RAM,32根可編程I/O線,可編程串行口,內(nèi)置看門(mén)狗。
與看門(mén)狗有關(guān)的特殊功能寄存器WMCON 地址= 96H,與看門(mén)狗有關(guān)的控制位為96h第0、1、5、6、7位,第5、6、7位用于設(shè)置看門(mén)狗定時(shí)時(shí)間(具體見(jiàn)第5頁(yè)表格),本應(yīng)用中第5、6、7位均置1,設(shè)置看門(mén)狗溢出時(shí)間為2048ms,第0位為看門(mén)狗使能控制位,該位置1將使能看門(mén)狗,其第1位為復(fù)用位,向第1位寫(xiě)1將復(fù)位看門(mén)狗定時(shí)器,具體操作如下:
a,使能看門(mén)狗,并將其溢出時(shí)間設(shè)定為2048ms:ORL 96H, #0E1H;
b,看門(mén)狗定時(shí)器清0:ORL 96H, #2
2、按鍵設(shè)計(jì):
為方便使用,設(shè)計(jì)了三個(gè)按鍵,分別為巡回/定點(diǎn)切換鍵、上鍵、下鍵。切換鍵用于巡檢與定點(diǎn)模式的切換,上鍵向上切換通道,下鍵向下切換通道;其中巡檢/定點(diǎn)切換鍵通過(guò)外部中斷1以中斷方式工作,中斷程序?qū)⒀不?定點(diǎn)標(biāo)志取反后直接跳到主程序中巡回/定點(diǎn)標(biāo)志判斷程序前運(yùn)行,由判斷程序完成巡回/定點(diǎn)的切換。按鍵信號(hào)由單片機(jī)P3.3,P3.4,P3.5引腳輸入。
3、顯示電路設(shè)計(jì)
為方便觀察,選用三個(gè)二位共陽(yáng)級(jí)8段數(shù)碼顯示管(TOD5201AE)動(dòng)態(tài)顯示,一位顯示儀表地址(從A至F),一位顯示通道號(hào)(從0至7通道),其余四位用來(lái)顯示實(shí)時(shí)溫度值;用單片機(jī)P1口驅(qū)動(dòng)一片74HC244以吸收電流的方式控制段碼,用單片機(jī)P0.0至P0.5引腳驅(qū)動(dòng)六個(gè)PNP三極管(9012)控制位選。
4、電源選用5V/1A市售成品開(kāi)關(guān)電源。
巡回/定點(diǎn) 下 儀表
地址 通道號(hào) 實(shí)時(shí)溫度 巡回/定點(diǎn) 下 儀表
地址 通道號(hào) 實(shí)時(shí)溫度 A B Gnd 上 熱水溫度遠(yuǎn)程顯示器 A B Gnd
120Ω XJ-08S 巡回檢測(cè)儀A A B Gnd
120Ω XJ-08S 巡回檢測(cè)儀B 5、 根據(jù)智能儀表通訊協(xié)議的要求,串行口定義為方式1工作,一幀10位:1個(gè)起始位、8個(gè)數(shù)據(jù)位、一個(gè)停止位;用一片75176完成數(shù)據(jù)的發(fā)送與接收,由于RS-485為半雙工,故用單片機(jī)P3.2引腳控制發(fā)送與接收的切換;兩個(gè)智能儀表處于RS-485總線的兩個(gè)端點(diǎn),為提高可靠性,在RS-485總線的兩個(gè)端點(diǎn)上分別并聯(lián)一個(gè)120Ω、1/4W終端電阻。
l 系統(tǒng)方框圖如右示:
l 單片機(jī)裝置電原理圖見(jiàn)下頁(yè):
7 6 5 定時(shí)值
0 0 0 16ms
0 0 1 32ms
0 1 0 64ms
0 1 1 128ms
1 0 0 256ms
1 0 1 512ms
1 1 0 1024ms
1 1 1 2048ms 看門(mén)狗溢出時(shí)間表
六、單片機(jī)軟件設(shè)計(jì)說(shuō)明及程序流程圖 為方便調(diào)試,采用模塊化編程,共分1個(gè)主模塊及5個(gè)子模塊,各模塊功能說(shuō)明及流程圖如下(源程序見(jiàn)附錄):
1、主模塊(rand_main.a51)
上電后程序顯示初始化標(biāo)志并等待3秒,然后進(jìn)入巡回模式,自動(dòng)檢測(cè)地址為A(10)至F(15)的智能儀表,對(duì)在線的儀表及已使用通道以3秒為周期自動(dòng)巡回讀取實(shí)時(shí)溫度并送數(shù)碼管顯示,儀表未在線或未用通道則自動(dòng)跳過(guò);定點(diǎn)模式時(shí)根據(jù)上、下按鍵情況自動(dòng)向前或向后移動(dòng)一個(gè)通道后等待下一次按鍵(向上至最高通道號(hào)時(shí)跳到上一個(gè)儀表的最低在用通道,向下至最低通道號(hào)時(shí)跳到下一個(gè)儀表的最高在用通道);等待期間以3秒為周期讀取當(dāng)前儀表當(dāng)前通道實(shí)時(shí)溫度并送數(shù)碼管顯示,另外,為了區(qū)分巡回、定點(diǎn)工作模式,定點(diǎn)工作模式時(shí)最低位數(shù)碼管以約0.5Hz的頻率閃爍顯示。當(dāng)檢測(cè)到巡回/定點(diǎn)切換鍵按下時(shí)自動(dòng)在巡回及定點(diǎn)模式間轉(zhuǎn)換,當(dāng)檢測(cè)到溫度值低于-199.9度時(shí)顯示-199.9度。
主模塊流程圖見(jiàn)下頁(yè):
YD_N100=儀表地址
TD_N=通道號(hào) Y N 開(kāi)始 上電初始化 置SP 巡回/定點(diǎn)標(biāo)志=1? #0ah=>yd_n100,#0=>td_n 清閃爍、調(diào)用命令發(fā)送模塊 接收正確嗎? 調(diào)用數(shù)據(jù)轉(zhuǎn)換程序 正常嗎? Y N 送顯示并延時(shí)3秒 Td_n+1=>td_n Td_n=8? Y N 0=>Td_n N Y Yd_n100+1=>yd_n100 Yd_n100=10h? 0ah=>yd_n100 start Td_n=0? 開(kāi)外部中斷1并置最低位閃爍 清軟硬看門(mén)狗 2秒定時(shí)到? 下鍵? 上鍵? N N N Y Y Y 調(diào)用命令發(fā)送程序 調(diào)用數(shù)據(jù)轉(zhuǎn)換程序 正確嗎? 正確嗎? 送顯示 Y N N Y 7=>td_n Yd_n100-1=>yd_100 Yd_n100=9? 0fh=>yd_100 N N Y Y Td_n-1=>td_n 調(diào)用命令發(fā)送程序 正確嗎? 正確嗎? 調(diào)用數(shù)據(jù)轉(zhuǎn)換程序 N Y Y N 送顯示、置2S定時(shí)初值 上鍵處理流程與下鍵相似,此處從略。 N Y
2、數(shù)據(jù)轉(zhuǎn)換子模塊(rand_data.a51)
功能: 本模塊先將ASCII碼轉(zhuǎn)換成BIN碼,然后將BIN碼轉(zhuǎn)換成BCD碼并將數(shù)據(jù)轉(zhuǎn)換成可直接顯示的格式
入口: a=通道號(hào)
出口: r1=個(gè)位,r2=十位,r3=百位,r4=千位(顯示數(shù)據(jù))
a=非0表示該通道未用
注:本子模塊中直接將小數(shù)點(diǎn)信息加到相應(yīng)位數(shù)據(jù)上,如需在某位顯示小數(shù)點(diǎn),則將該位數(shù)據(jù)加10H,顯示子模塊根據(jù)此信息顯示小數(shù)點(diǎn)。
各子程序功能介紹:
l bcd2_bcd1:將r3,r4中的4位bcd碼由低至高分別存入r1,r2,r3,r4中;
l ascii4_bcd3:將(r0)為首地址的4字節(jié)ascii碼轉(zhuǎn)換成bcd碼并將bcd碼由低至高依次存放在r3,r4,r5中,r3,r4中各存放2位bcd碼,r5中存放一位bcd碼;
l bin_bcd:將r1,r2中的bin碼轉(zhuǎn)換成bcd碼并將bcd碼由低至高依次存放在r3,r4,r5中,r3,r4中各存放2位bcd碼,r5中存放一位bcd碼;
l ascii4_bin2:將(r0)為首地址的4字節(jié)ascii碼轉(zhuǎn)換成2位bin碼存放在r1(低字節(jié)),r2(高字節(jié))中;
注:[(r0)指r0中內(nèi)容]
l ascii_bin:將(r0)為地址的一位ascii碼轉(zhuǎn)換成bin碼存A中。
(高級(jí)子程序調(diào)用低級(jí)子程序以實(shí)現(xiàn)更強(qiáng)的功能,源程序中對(duì)各子程序有較詳細(xì)的注釋?zhuān)蚀颂巸H畫(huà)出主流程圖)
開(kāi)始 計(jì)算通道數(shù)據(jù)首地址 調(diào)用數(shù)據(jù)轉(zhuǎn)換程序 還原小數(shù)位數(shù)存R6 BCD碼超過(guò)5位嗎? 該通道數(shù)據(jù)為0X0ffff嗎? 返回該通道未用信息 Y Y N N 退出 轉(zhuǎn)換成可顯示數(shù)據(jù)存R1-R4 有效位前的零消除處理
返回?cái)?shù)據(jù)正確信息 負(fù)數(shù)處理,當(dāng)數(shù)據(jù)小于-199.9時(shí)顯示-199.9
3、顯示、軟件看門(mén)狗、20ms定時(shí)器子程序(rand_disp.a51)
功能: 通過(guò)定時(shí)器0以1MS為周期動(dòng)態(tài)顯示緩沖區(qū)中的內(nèi)容;同時(shí)完成20ms定時(shí)器及軟件看門(mén)狗計(jì)數(shù);當(dāng)軟件看門(mén)狗定時(shí)器溢出時(shí)自動(dòng)復(fù)位。
入口: 以disp_buf為首地址依次存放從個(gè)位至十萬(wàn)位待顯示數(shù)據(jù),以disp_wc為首地址(位地址)依次存放個(gè)位至千位閃爍控制位信息,為'0'常亮,為'1'閃爍.
T0中斷入口 保護(hù)現(xiàn)場(chǎng) 顯示碼表地址=>dptr Disp_s_c取反 Disp_c+1=>disp_c
Disp_c=>R0 Disp_s-1=>disp_s,Disp_s=0? Y N 個(gè)位數(shù)據(jù)及閃爍信息=>A,C a
閃閃爍 N R0=1? Y 十位數(shù)據(jù)及閃爍信息=>A,C a
閃閃爍 百位數(shù)據(jù)及閃爍信息=>A,C a
閃閃爍 千位數(shù)據(jù)及閃爍信息=>A,C a
閃閃爍 萬(wàn)位數(shù)據(jù)=>A a
閃閃爍 十萬(wàn)位數(shù)據(jù)=>A a
閃閃爍 百萬(wàn)位數(shù)據(jù)=>A (未用) a
閃閃爍 千萬(wàn)位數(shù)據(jù)=>A (未用) a
閃閃爍 N R0=2? Y N R0=3? Y N R0=4? Y N R0=5? Y N R0=6? Y N R0=7? Y N R0=8? Y
Disp_s:閃爍控制計(jì)數(shù)器
Disp_s_c:閃爍控制標(biāo)志
Disp_c:顯示控制計(jì)數(shù)器 出口: wdt中存放軟件看門(mén)狗計(jì)數(shù)值,time_20ms中存放20ms的計(jì)數(shù)值。Wdt溢出時(shí)跳至程序存儲(chǔ)器0000H單元
l 輸出處理 a
閃閃爍 Disp_c=10? N Y 0=>disp_c
20ms計(jì)數(shù)處理 軟看門(mén)狗計(jì)數(shù)溢出
Y N 跳至0000H a
閃閃爍 恢復(fù)現(xiàn)場(chǎng)
閃閃爍 T0中斷返回 將定時(shí)器0設(shè)定為模式1定時(shí)工作,每ms產(chǎn)生一次中斷,即顯示一位,每10ms 6位數(shù)據(jù)輪流顯示1ms;為進(jìn)一步提高可靠性,在該模塊中設(shè)計(jì)了軟件看門(mén)狗,實(shí)現(xiàn)方法見(jiàn)源程序。
模塊流程圖如本頁(yè)所示:
4、命令發(fā)送及接收控制子模塊(rand_send.a51)
功能: 發(fā)送命令緩沖區(qū)中命令并等待接收完畢,然后檢查接收到的數(shù)據(jù),接收錯(cuò)誤則重發(fā)命令,達(dá)到設(shè)定的次數(shù)仍錯(cuò)則存入錯(cuò)誤碼后退出.
入口: A=儀表地址
開(kāi)始 清除命令及接收緩沖區(qū) 設(shè)置允許錯(cuò)誤次數(shù) 計(jì)算儀表命令偏移地址,取出命令及送入命令緩沖區(qū) 校驗(yàn)通過(guò)? Y N 發(fā)送命令 在80ms內(nèi)檢測(cè)到正在接收標(biāo)志? Y N 在200ms內(nèi)檢測(cè)到接收結(jié)束標(biāo)志? Y N 接收到命令錯(cuò)信息? Y N 返回命令錯(cuò)信息 允許錯(cuò)誤次數(shù)-1
允許錯(cuò)誤次數(shù)=0?
Y N 緩沖區(qū)結(jié)束標(biāo)志符正確? Y N 清正在接收標(biāo)志 返回錯(cuò)誤信息 校驗(yàn)接收緩沖區(qū)中數(shù)據(jù) 返回正確信息 退出 返回校驗(yàn)錯(cuò)信息
出口: A=0 表示接收正確 1 表示校驗(yàn)錯(cuò) '*'表示命令錯(cuò) 'N'表示無(wú)回應(yīng)
模塊流程圖如下:
5、串行接收子模塊(rand_rec.a51)
功能: 串行接收模塊通過(guò)中斷自動(dòng)執(zhí)行,程序檢測(cè)到@時(shí)置ri_f標(biāo)志并開(kāi)始接收,檢測(cè)到回車(chē)符時(shí)清ri_f后退出,接收到的數(shù)據(jù)存放在以rec_buf為首地址的緩沖區(qū)中。
外部中斷1入口
斷 按鍵釋放? N Y 延時(shí)40ms去抖
延時(shí)40ms去抖
清看門(mén)狗定時(shí)器 關(guān)中斷
巡回/定點(diǎn)標(biāo)志取反
跳至主程序start處
斷 串行中斷入口
斷 接收中斷? 接收緩沖區(qū)首地址=>rec_buf_z Y RI_F:正在接收標(biāo)志
REC_BUF_Z:接收指針 中斷返回
斷返 N RI_F=0? 接收到@? 1=>RI_F 數(shù)據(jù)存入接收緩沖區(qū) 接收到0dh? Y Y Y N N N 0=>RI_F 接收緩沖區(qū)溢出? Y N 0=>RI_F 保護(hù)現(xiàn)場(chǎng) 恢復(fù)現(xiàn)場(chǎng) 清RI
串行中斷(rand_rec.a51)流程圖 巡回/定點(diǎn)鍵中斷(rand_key.a51)流程圖
6、巡回/定點(diǎn)轉(zhuǎn)換檢測(cè)模塊(rand_key.a51)
功能: 模塊通過(guò)外部中斷1自動(dòng)執(zhí)行,檢測(cè)到巡回/定點(diǎn)按鍵后先延時(shí)去抖動(dòng),并等待按鍵釋放后將巡回/定點(diǎn)標(biāo)志位取反,然后自動(dòng)跳至主模塊中start處,并不返回原中斷點(diǎn)。
模塊流程圖如見(jiàn)本頁(yè):
七、調(diào)測(cè)及運(yùn)行情況介紹 1、 調(diào)試步驟:
l 硬件連接:將各芯片插在面包板上并用導(dǎo)線按原理圖連接
l 軟件開(kāi)發(fā)環(huán)境:Keil uVision2 for Windows ,該軟件的模擬調(diào)試器支持C語(yǔ)言及匯編語(yǔ)言源代碼調(diào)試,其匯編程序支持宏匯編及模塊化編程,使用方便。
l 首先在模擬調(diào)試器中調(diào)試各子模塊,各子模塊調(diào)試正常后再將各子模塊及主模塊全部匯編連接成目標(biāo)文件,最后將目標(biāo)代碼下載到單片機(jī)中并連接智能儀表進(jìn)行統(tǒng)調(diào)。
2、 該系統(tǒng)軟件部分除報(bào)警子模塊外已全部開(kāi)發(fā)完成并實(shí)際測(cè)試通過(guò),測(cè)試時(shí)用一對(duì)長(zhǎng)度約1100M的0.5mm2 普通電話線作為單片機(jī)裝置與兩個(gè)智能儀表的通訊線,經(jīng)過(guò)一個(gè)多星期的連續(xù)運(yùn)行觀察,運(yùn)行可靠穩(wěn)定,完全滿(mǎn)足使用要求。
[注:報(bào)警子模塊的開(kāi)發(fā)及硬件制版工作正在進(jìn)行中。]
八、結(jié)束語(yǔ) 用單片機(jī)+智能儀表構(gòu)成的溫度遠(yuǎn)程顯示系統(tǒng)總造價(jià)約人民幣7000元(兩塊智能儀表+溫度傳感器約3500元,通訊電纜約2000元,單片機(jī)裝置及施工費(fèi)用約1500元),與采用其它方案的系統(tǒng)比較造價(jià)較低,其硬件及軟件的設(shè)計(jì)、制作都較簡(jiǎn)單,有一定的電子及單片機(jī)知識(shí)便可完成。同時(shí)對(duì)該裝置軟件稍加修改即可與其他帶有RS-485通訊端口的儀器儀表通訊(如變頻器、電路傳感器等),實(shí)現(xiàn)遠(yuǎn)程測(cè)量、監(jiān)視及控制。
與發(fā)達(dá)國(guó)家相比,我國(guó)單片機(jī)應(yīng)用的普及程度較低。通過(guò)該實(shí)例說(shuō)明,我們完全可以把我們學(xué)到的單片機(jī)知識(shí)應(yīng)用到實(shí)際工作中,直接創(chuàng)造經(jīng)濟(jì)效益。
九、參考資料 <<單片機(jī)高級(jí)語(yǔ)言C51Windows環(huán)境編程與應(yīng)用>> 電子工業(yè)出版社
徐愛(ài)鈞 彭秀華 編著
<<ATMEL89系列Flash單片機(jī)原理與應(yīng)用>> 電子工業(yè)出版社
余永權(quán) 主編
<<標(biāo)準(zhǔn)集成電路數(shù)據(jù)手冊(cè)高速CMOS電路>> 電子工業(yè)出版社
<<ATMEL AT89S8252數(shù)據(jù)手冊(cè)>> ATMEL公司
<<XJ-08H(S)巡回檢測(cè)儀使用說(shuō)明書(shū)>> 重慶川儀十八廠
<<工業(yè)控制計(jì)算機(jī)組成原理>> 清華大學(xué)出版社
孫廷才 王杰 孫中健 編著
<<電子技術(shù)>>2001年11期
十、附錄(源程序) 1、主模塊(rand_main.a51) ;------------1--------rand_main.a51----------------
name rand_main
EXTRN CODE(I_T0,send_order,rec_si,ascii_bcd,key)
extrn data (DISP_buf,disp_wc,time_20ms,wdt)
extrn idata (rec_buf)
public TH0_H,TL0_L,START,ri_f,wdt_time,key_work,key_f
prog SEGMENT CODE ;定義代碼段
byte_buff segment data ;定義字節(jié)數(shù)據(jù)段1
byte_buffI segment idata ;定義字節(jié)數(shù)據(jù)段2
bit_buff segment data bitaddressable ;定義位數(shù)據(jù)段
bit_flag segment bit
stack segment idata ;定義堆棧數(shù)據(jù)段
rseg stack ;為堆棧保留20個(gè)字節(jié)
ds 20
CSEG AT 00H ;定義絕對(duì)代碼段
USING 0 ;選擇工作寄存器組第0組
lJMP rand ;復(fù)位時(shí)程序執(zhí)行執(zhí)行點(diǎn)
CSEG AT 03H ;外部中斷0
RETI
CSEG AT 0BH ;定時(shí)器0中斷
lJMP I_T0
CSEG AT 13H ;外部中斷1
ljmp key
RETI
CSEG AT 1BH ;定時(shí)器1中斷
RETI
CSEG AT 23H ;串行中斷
ljmp rec_si
RSEG BYTE_BUFF
td_temp: ds 1
TD_n: DS 1 ;通道號(hào)
YD_n100: ds 1 ;儀表地址
;----------------------------------
rseg bit_flag
key_work:dbit 1
ri_f: dbit 1 ;串行口正在接收標(biāo)志
;----主程序
RSEG prog
;------------------------------符號(hào)定義
key_f equ p3.3
key_up equ p3.4
key_down equ p3.5
wdt_time equ 100 ;軟件看門(mén)狗定時(shí)器計(jì)數(shù)值
scon_c equ 01010000b ;串行口設(shè)置為10位UART,允許接收
th1_h equ 0fdh ;晶振為11.0592M,波特率為9600時(shí)初值
tmod_n equ 21h ;設(shè)置定時(shí)器(T1作為波特率發(fā)生器工作在模式2,T0為模式1)
ie_n equ 82h ;設(shè)置串行,定時(shí)器0中斷
ip_n equ 12h ;設(shè)置串行,定時(shí)器0中斷為高級(jí)中斷
TH0_H EQU 0FCH
TL0_L EQU 06BH ;設(shè)定定時(shí)器0為1MS中斷初值
;------------------初始化代碼
clear_wdt macro ;清硬看門(mén)狗宏定義
orl 96h,#2
ENDM
rand: ORL 96H,#0E1H ;啟動(dòng)硬件看門(mén)狗
mov p0,#0ffh
mov r0,#20h
mov a,#0
start_300:mov @r0,a
inc r0
cjne r0,#128,start_300
setb key_work ;置巡回/定點(diǎn)標(biāo)志
mov p3,#0ffh
mov p2,#0ffh
mov disp_wc,#0 ;初始化閃爍控制位
mov ip,#ip_n ;設(shè)置串行,定時(shí)器0中斷為高級(jí)中斷
mov scon,#scon_c
MOV TMOD,#tmod_n
MOV TH0,#TH0_H ;設(shè)定定時(shí)器初值
MOV TL0,#TL0_L
mov th1,#th1_h
mov tl1,#th1_h
mov ie,#ie_n
mov pcon,#0
SETB tr1
SETB TR0
;-------顯示初始化提示
acall chuhao
CLEAR_WDT
start: clr ea
mov sp,#stack-1
setb ea
clr ri_f ;清接收中標(biāo)志
clr p3.2 ;置75176為接收狀態(tài)
jnb key_work,db_work
;-----------------------------------
setb ex1
mov yd_n100,#0ah
mov td_n,#0
s_0: anl disp_wc,#0f0h
mov wdt,#0 ;清看門(mén)狗定時(shí)器
clear_wdt
mov a,yd_n100
lcall send_order
JNZ s_1
mov disp_buf+5,yd_n100
mov a,td_n
lcall ascii_bcd
jnz s_2
mov disp_buf+4,td_n
acall mov_to_disp
mov wdt,#0
clear_wdt
mov a,#75
add a,time_20ms
cjne a,time_20ms,$
mov wdt,#0
clear_wdt
mov a,#75
add a,time_20ms
cjne a,time_20ms,$
s_2: inc td_n
mov a,td_n
cjne a,#8,s_0
mov td_n,#0
s_1: inc yd_n100
MOV A,YD_N100
cjne a,#10h,s_0
mov yd_n100,#0ah
ajmp s_0
;-----------------------------
db_work:setb ex1
orl disp_wc,#01h
d_3: mov wdt,#0 ;清看門(mén)狗定時(shí)器
clear_wdt
jb key_up,d_4
mov a,#2
add a,time_20ms
cjne a,time_20ms,$
jb key_up,d_4
d_5: mov wdt,#0
clear_wdt
jnb key_up,d_5 ;等待向上鍵松開(kāi)
;------------------------------------------------
d_53: mov a,td_n
cjne a,#7,d_50
mov td_n,#0
d_52: inc yd_n100
mov a,yd_n100
cjne a,#10h,d_51
mov yd_n100,#0ah
ajmp d_51
d_50: inc td_n
d_51: mov a,yd_n100
lcall send_order
JNZ d_52
mov disp_buf+5,yd_n100
mov a,td_n
lcall ascii_bcd
jnz d_53
mov disp_buf+4,td_n
acall mov_to_disp
mov a,#100 ;2秒鐘定時(shí)設(shè)定
add a,time_20ms
ajmp d_3
;------------------------------------------------
d_4: jb key_down,d_10
mov a,#2
add a,time_20ms
cjne a,time_20ms,$
jb key_down,d_3
d_6: mov wdt,#0
clear_wdt
jnb key_down,d_6 ;等待向下鍵松開(kāi)
;-----------------------------------------------
d_43: mov a,td_n
cjne a,#0,d_40
mov td_n,#7
d_42: dec yd_n100
mov a,yd_n100
cjne a,#9h,d_41
mov yd_n100,#0fh
ajmp d_41
d_40: dec td_n
d_41: mov a,yd_n100
lcall send_order
JNZ d_42
mov disp_buf+5,yd_n100
mov a,td_n
lcall ascii_bcd
jnz d_43
mov disp_buf+4,td_n
acall mov_to_disp
mov a,#100 ;2秒鐘定時(shí)設(shè)定
add a,time_20ms
ajmp d_3
;----------------------------------
d_10: cjne a,time_20ms,d_30
mov a,yd_n100
lcall send_order
jnz d_30
mov a,td_n
lcall ascii_bcd
jnz d_30
acall mov_to_disp
mov a,#100
add a,time_20ms
d_30:ajmp d_3
;----------------------------------
mov_to_disp:mov disp_buf,r1
mov disp_buf+1,r2
mov disp_buf+2,r3
mov disp_buf+3,r4
ret
chuhao: mov r1,#1eh ;初始化等待提示
mov r2,#22h
mov r3,#21h
mov r4,#1fh
mov disp_buf+4,#21h
mov disp_buf+5,#20h
acall mov_to_disp
mov a,#75
add a,time_20ms
cjne a,time_20ms,$
mov wdt,#0
clear_wdt
mov a,#75
add a,time_20ms
cjne a,time_20ms,$
ret
end
2、數(shù)據(jù)轉(zhuǎn)換子模塊(rand_data.a51) ;-----------2-------rand_data.a51----------------
name rand_data
extrn idata (rec_buf)
public ascii_bcd
prog SEGMENT CODE ;定義代碼段
byte_buff segment data ;定義字節(jié)數(shù)據(jù)段1
byte_buffI segment idata ;定義字節(jié)數(shù)據(jù)段2
bit_buff segment data bitaddressable ;定義位尋址區(qū)字節(jié)數(shù)據(jù)段
rseg prog
using 0
;-------------------------------------
ASCII_BCD:mov b,#8 ;計(jì)算該通道數(shù)據(jù)偏移首地址
mul ab
add a,#5
mov r0,#rec_buf
add a,r0
mov b,a
mov r0,a
acall ascii4_bcd3
mov a,b ;還原小數(shù)位數(shù)
add a,#7
mov r0,a
acall ascii_bin
mov r6,a ;小數(shù)位數(shù)暫存在R6中
mov a,r5
jz asc_oK
mov a,dpl
cpl a
clr c
inc a
mov dpl,a
mov a,dph
cpl a
addc a,#0
mov dph,a
jnz asc_b
asc_0: mov a,dpl
dec a
jnz asc_b
mov r1,#0fh
mov r2,#0fh
mov r3,#0fh
mov r4,#0fh
mov a,#0fh
ajmp asc_out
asc_b: mov r1,dpl ;為負(fù)數(shù)處理
mov r2,dph
acall bin_bcd
mov a,b ;還原小數(shù)位數(shù)
add a,#7
mov r0,a
acall ascii_bin
mov r6,a ;小數(shù)位數(shù)暫存r6
acall bcd2_bcd1
mov a,r4
dec a
jnz asc_100 ;數(shù)據(jù)小于-199.9時(shí)顯示-199.9
mov r4,#23h
ajmp asc_sw
asc_100:mov r4,#23h
mov r3,#9
mov r2,#19h
mov r1,#9
ajmp asc_sw_1
asc_ok: acall bcd2_bcd1 ;正常數(shù)據(jù)處理程序
asc_sw: mov a,r4 ;清除有效位前面的0
jnz asc_sw_1
mov r4,#1ch
mov a,r3
jnz asc_sw_1
mov r3,#1ch
asc_sw_1:clr a
asc_out:ret
;------------每字節(jié)兩位BCD碼轉(zhuǎn)換為每字節(jié)一位BCD碼子程序
;入口:r3=個(gè)位及十位BCD碼,r4=百位及千位BCD碼,r6=小數(shù)位數(shù)
;出口:r1=個(gè)位BCD碼,r2=十位BCD碼,r3=百位BCD碼,r4=千位BCD碼
bcd2_bcd1:mov a,r3 ;個(gè)位及十位BCD數(shù)處理
anl a,#0fh
mov r1,a
mov a,r3
anl a,#0f0h
swap a
mov r2,a
mov a,r4 ;百位及千位BCD數(shù)處理
anl a,#0fh
mov r3,a
mov a,r4
anl a,#0f0h
swap a
mov r4,a
mov a,r6 ;加入小數(shù)點(diǎn)信息
jz bcd2_out
add a,#ar1
mov r0,a
mov a,@r0
add a,#10h
mov @r0,a
bcd2_out:ret
;---------------ASCii4_BCD3轉(zhuǎn)換子程序
;入口:r0=四字節(jié)ASCII碼首地址
;出口:r5,r4,r3從高至低依次存放BCD碼(r3,r4各存2位,r5存1位)
ascii4_bcd3:acall ascii4_bin2
mov dpl,r1
mov dph,r2
acall bin_bcd
ret
;---------------BIN_BCD轉(zhuǎn)換子程序
;入口:r1=BIN低字節(jié),r2=BIN高字節(jié) 共2字節(jié)
;出口:r3=低2位BCD碼,r4=高2位BCD碼,r5=可能的最高位BCD碼
bin_bcd:PUSH ACC
PUSH PSW
mov r3,#0 ;BCD單元清0
mov r4,#0
mov r5,#0
mov r6,#16 ;設(shè)置二進(jìn)制數(shù)位數(shù)
clr c
bin_0: mov a,r1
rlc a
mov r1,a
mov a,r2
rlc a
mov r2,a
mov r0,#ar3
mov r7,#3 ;設(shè)置BCD字節(jié)數(shù)
bin_1: mov a,@r0
addc a,@r0
da a
mov @r0,a
inc r0
djnz r7,bin_1
djnz r6,bin_0
POP PSW
POP ACC
ret
;---------------ASCII4_BIN2轉(zhuǎn)換子程序
;入口:R0=ASCII碼首地址(共四字節(jié)ASCII碼)
;出口:r1=BIN碼低字節(jié),R2=BIN碼高字節(jié)
ascii4_bin2:PUSH ACC
acall ascii_bin
anl a,#0fh
swap a
mov r1,a
inc r0
acall ascii_bin
anl a,#0fh
orl ar1,a
inc r0
acall ascii_bin
anl a,#0fh
swap a
mov r2,a
inc r0
acall ascii_bin
anl a,#0fh
orl ar2,a
POP ACC
ret
;---------------ASCII_BIN轉(zhuǎn)換子程序
;入口:R0=ASCII地址
;出口:A=BIN碼
ascii_bin:mov a,@r0
clr c
subb a,#3ah
jnc ascii_0
add a,#7
ascii_0:add a,#3
ret
end
3、顯示、軟件看門(mén)狗及20ms定時(shí)器子模塊(rand_disp.a51) ;--------3--------rand_disp.a51-------------------------
name rand_disp
extrn number(TH0_H,TL0_L,wdt_time)
PUBLIC I_T0,disp_buf,disp_wc,time_20ms,wdt
prog SEGMENT CODE ;定義代碼段
BYTE_BUFF segment data ;定義字節(jié)數(shù)據(jù)段1
byte_buffI segment idata ;定義字節(jié)數(shù)據(jù)段2
bit_buff segment data bitaddressable ;定義位數(shù)據(jù)段
RSEG BYTE_BUFF
wdt: ds 1
time_s_c: ds 1
time_20ms: ds 1
DISP_C: ds 11 ;顯示位
disp_buf data disp_c+1 ;個(gè)位緩沖區(qū),此個(gè)位并非真正的個(gè)位,指最右一位,以下類(lèi)推
disp_2 data disp_c+2 ;十個(gè)位緩沖區(qū)
disp_3 data disp_c+3 ;百位緩沖區(qū)
disp_4 data disp_c+4 ;千位緩沖區(qū)
disp_5 data disp_c+5 ;通道位緩沖區(qū)
disp_6 data disp_c+6 ;地址位緩沖區(qū)
disp_7 data disp_c+7 ;無(wú)
disp_8 data disp_c+8 ;無(wú)
disp_s data disp_c+9 ;閃爍計(jì)數(shù)器
rseg bit_buff
disp_wc: ds 1
disp_c_1 bit disp_wc.0 ;個(gè)位閃爍標(biāo)志位 1-閃爍
disp_c_2 bit disp_wc.1 ;十位閃爍標(biāo)志位
disp_c_3 bit disp_wc.2 ;百位閃爍標(biāo)志位
disp_c_4 bit disp_wc.3 ;千位閃爍標(biāo)志位
disp_s_c bit disp_wc.4 ;閃爍控制位 1-閃爍
RSEG PROG
using 0
dsb equ p3.4
cr_not equ p3.5
cp equ p3.6
I_T0: push acc
push ar0
push dph
push dpl
push psw
mov th0,#th0_h
mov tl0,#tl0_l
mov dptr,#tab
;---------------------------------------------
djnz disp_s,d_20
cpl disp_s_c
;---------------------------------------------
d_20: INC DISP_C
MOV R0,DISP_C
CJNE R0,#1,DISP2 ;r0=1顯示個(gè)位
mov c,disp_c_1
mov A,disp_buf
mov p1,#0FFH
mov p0,#0feh
ajmp d_10
DISP2: CJNE R0,#2,DISP3 ;顯示十位
setb p0.0
mov c,disp_c_2
mov A,disp_2
mov p1,#0FFH
mov p0,#0fdh
ajmp d_10
DISP3: CJNE R0,#3,DISP4 ;顯示百位
mov c,disp_c_3
mov A,disp_3
mov p1,#0FFH
mov p0,#0fbh
ajmp d_10
DISP4: CJNE R0,#4,DISP5 ;顯示千位
mov c,disp_c_4
mov A,disp_4
mov p1,#0FFH
mov p0,#0f7h
ajmp d_10
DISP5: CJNE R0,#5,DISP6 ;顯示通道號(hào)
mov A,disp_5
mov p1,#0FFH
mov p0,#0efh
ajmp d_10
DISP6: CJNE R0,#6,DISP7 ;顯示儀表地址
mov A,disp_6
mov p1,#0FFH
mov p0,#0dfh
ajmp d_10
DISP7: CJNE R0,#7,DISP8 ;無(wú)
mov A,disp_7
mov p1,#0FFH
mov p0,#0bfh
ajmp d_10
DISP8: CJNE R0,#8,d_10 ;無(wú)
mov A,disp_8
mov p1,#0FFH
mov p0,#7fh
d_10: acall disp_w
mov r0,disp_c
cjne r0,#10,d_12 ;若disp_c=10則清disp_c
mov disp_c,#0
inc time_s_c ;MS,S計(jì)數(shù)處理程序
mov a,time_s_c
cjne a,#2,d_12
mov time_s_c,#0
inc time_20ms
inc wdt ;軟看門(mén)狗處理程序
mov a,wdt
cjne a,#wdt_time,d_12
mov wdt,#0
mov a,#0
push acc
push acc
reti
;-----------------------
d_12: pop psw
pop dpl
pop dph
pop ar0
pop acc
RETI
disp_w: jnc d_0
jnb disp_s_c,d_0
mov p1,#0FFH
ajmp d_1
d_0: movc a,@a+dptr
cpl a
mov p1,a
D_1: ret
;---------------------------------------------------------
TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
; 0 1 2 3 4 5 6 7 8 9
db 77H,7CH,39H,5EH,79H,71H
; A B C D E F
DB 0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,87H,0FFH,0EFH
; 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.
db 40H,80H,00H,37h,5ch,1ch,58h,74h,0dch,46h
; - . 空 n o u c h a -1
; 1a 1b 1c 1d 1e 1f 20 21 22 23
END
4、命令發(fā)送及接收控制子模塊(rand_send.a51) ;----------4--------rand_send.a51----------------
name send_order
extrn idata (rec_buf) ;rec_buff 接收緩沖區(qū)
extrn data (time_20ms)
extrn bit (ri_f) ;ri_f 正在接收標(biāo)志
PUBLIC send_order
prog SEGMENT CODE ;定義代碼段
byte_buff segment data ;定義字節(jié)數(shù)據(jù)段1
byte_buffI segment idata ;定義字節(jié)數(shù)據(jù)段2
bit_buff segment data bitaddressable ;定義位數(shù)據(jù)段
rseg byte_buff
send_n:ds 1
order_buf:ds 10
rseg prog
dd_c equ 4 ;等待回應(yīng)20m數(shù)
cw_n equ 7 ;設(shè)置允許錯(cuò)誤次數(shù)
using 0
;---------------------清命令緩沖區(qū)
send_order:
mov dpl,#8
mov r0,#order_buf
send_0: mov @r0,#0
inc r0
djnz dpl,send_0
MOV DPL,#72 ;清接收緩沖區(qū)
MOV R0,#REC_BUF
SEND_A: MOV @R0,#0
INC R0
DJNZ DPL,SEND_A
;----------------------發(fā)送命令控制程序
mov send_n,#cw_n ;設(shè)置允許錯(cuò)誤次數(shù)
mov b,#10
clr c
subb a,b
mov b,#8
mul ab
mov dptr,#a_order
mov r0,#order_buf-1
mov r1,#10
start_mov:inc r0
push acc
movc a,@a+dptr
mov @r0,a
inc dptr
pop acc
cjne @r0,#0dh,start_mov
;----------------------發(fā)送命令子程序
send_start:setb p3.2 ;切換75176至發(fā)送狀態(tài)
mov r0,#order_buf-1
send_10:inc r0
mov sbuf,@r0
jnb ti,$ ;等待一幀數(shù)據(jù)發(fā)完
CLR TI
cjne @r0,#0dh,send_10 ;檢測(cè)到結(jié)束標(biāo)志退出
;------------------------檢測(cè)接收標(biāo)志
mov r0,#30 ;延時(shí)60uS等待停止位發(fā)送完畢
djnz r0,$
setb es
clr p3.2 ;切換75176至接收狀態(tài)
mov a,#dd_c ;延時(shí)檢測(cè)儀表有無(wú)回應(yīng)
add a,time_20ms
send_21:jb ri_f,send_20
cjne a,time_20ms,send_21
mov a,#'N'
ajmp send_23
;-------------------------檢測(cè)接收是否正確
send_20:mov a,#10 ;延時(shí)200MS等待接收結(jié)束
add a,time_20ms
send_28:jnb ri_f,send_29
cjne a,time_20ms,send_28
clr ri_f ;200MS仍未結(jié)束清接收中標(biāo)志
send_29:mov r0,#rec_buf+4
cjne @r0,#'*',send_22
mov a,#'*'
send_23:djnz send_n,send_start ;達(dá)到允許錯(cuò)誤次數(shù)退出
ajmp send_out
send_22:mov r0,#rec_buf+71
cjne @r0,#0dh,send_23 ;接收緩沖區(qū)第72字節(jié)不為回車(chē)符轉(zhuǎn)出錯(cuò)處理
;------------------------------還原校驗(yàn)碼
mov r0,#rec_buf+70
mov a,@r0
clr c
subb a,#3ah
jnc SEND_25
add a,#7
send_25:add a,#3
mov @r0,a
dec r0
mov a,@r0
clr , c
subb a,#3ah
jnc SEND_26
add a,#7
send_26:ADD A,#3
swap a
inc r0
xchd a,@r0
dec r0
xch a,@r0
inc r0
mov @r0,#0dh ;檢驗(yàn)碼后加回車(chē)符
;------------------------------檢驗(yàn)接收緩沖區(qū)數(shù)據(jù)
mov r0,#rec_buf+1
mov a,@r0
inc r0
send_24:xrl a,@r0
inc r0
cjne @r0,#0dh,send_24
cjne a,#0,send_200 ;接收校驗(yàn)未通過(guò)轉(zhuǎn)出錯(cuò)處理
send_out:clr es
ret
send_200:mov a,#1
ajmp send_23
;----------------------------------------------------
a_order: db '@0ARD67',0DH ;讀A表全部動(dòng)態(tài)數(shù)據(jù)命令
b_order: db '@0BRD64',0DH ;讀B表全部動(dòng)態(tài)數(shù)據(jù)命令
c_order: db '@0CRD65',0DH ;讀c表全部動(dòng)態(tài)數(shù)據(jù)命令
d_order: db '@0DRD62',0DH ;讀d表全部動(dòng)態(tài)數(shù)據(jù)命令
e_order: db '@0ERD63',0DH ;讀e表全部動(dòng)態(tài)數(shù)據(jù)命令
f_order: db '@0FRD60',0DH ;讀f表全部動(dòng)態(tài)數(shù)據(jù)命令
END
5、串行接收子模塊(rand_rec.a51) ;-------5----------rand_rec.a51
name rec_si
extrn bit (ri_f)
public rec_si,rec_buf
prog SEGMENT CODE ;定義代碼段
byte_buff segment data ;定義字節(jié)數(shù)據(jù)段1
byte_buffI segment idata ;定義字節(jié)數(shù)據(jù)段2
bit_buff segment data bitaddressable ;定義位數(shù)據(jù)段
rseg byte_buff
rec_buf_z: ds 1 ;接收區(qū)指針
rec_err: ds 1 ;接收緩沖區(qū)溢出計(jì)數(shù)器
rseg byte_buffi
rec_buf: ds 75
rseg prog
using 0
rec_si: PUSH PSW
push ar0
push acc
JNB RI,REC_OUT ;為發(fā)送中斷跳出
clr ri
jb ri_f,rec_0
mov a,sbuf
cjne a,#'@',rec_out ;無(wú)效命令過(guò)濾處理
setb ri_f ;置接收中標(biāo)志
mov rec_buf_z,#rec_buf ;接收緩沖區(qū)首地址給接收指針
mov rec_err,#73 ;設(shè)置最大接收字節(jié)數(shù)
ajmp rec_1
rec_0: mov a,sbuf
cjne a,#0dh,rec_1
clr ri_f
rec_1: mov r0,rec_buf_z
mov @r0,a
inc rec_buf_z
djnz rec_err,rec_out ;接收溢出清接收標(biāo)志
clr ri_f
rec_out:pop acc
pop ar0
POP PSW
reti
end
6、巡回/定點(diǎn)轉(zhuǎn)換檢測(cè)子模塊(rand_key.a51) ;-----------6----rand_key.a51
name key
EXTRN CODE(START)
extrn bit(key_work,key_f)
EXTRN DATA(DISP_buf,disp_wc,time_20ms,wdt)
PUBLIC KEY
prog SEGMENT CODE ;定義代碼段
RSEG PROG
;-------------------------------------
KEY: mov a,#2
add a,time_20ms
cjne a,time_20ms,$
key_1: mov wdt,#0
orl 96h,#0e1h
jnb key_f,key_1
mov a,#2
add a,time_20ms
cjne a,time_20ms,$
jnb key_f,key_1
clr ea
clr ex1
cpl key_work
;--------------------------------------
key_out:mov dptr,#start
push dpl
push dph
reti
end
7、 rand_js.hex
:100026007582087823760008D582FA75824878406A
:10003600760008D582FA75220775F00AC395F07521
:10004600F008A49000D07822790A08C0E093F6A3BD
:10005600D0E0B60DF5D2B278220886993099FDC265
:1000660099B60DF5781ED8FED2ACC2B27404252F0F
:10007600200907B52FFA744E0193740A252F30090B
:1000860005B52FFAC2097844B62A07742AD522C5BF
:1000960001C97887B60DF67886E6C3943A500224ED
:1000A600072403F618E6C3943A500224072403C42F
:1000B60008D618C608760D7841E6086608B60DFB20
:1000C600B40003C2AC22740101934030415244365D
:1000D600370D403042524436340D40304352443698
:1000E600350D403044524436320D40304552443688
:0A00F600330D403046524436300D01
:10010000C0E0C000C083C082C0D0758CFC758A6B13
:100110009001CDD53902B2040530A830B8010CA247
:1001200000E5317590FF7580FE218CB8020ED280FB
:10013000A201E5327590FF7580FD218CB8030CA2F9
:1001400002E5337590FF7580FB218CB8040CA20387
:10015000E5347590FF7580F7218CB8050AE5357593
:1001600090FF7580EF218CB8060AE5367590FF7513
:1001700080DF218CB8070AE5377590FF7580BF21B5
:100180008CB80808E5387590FF75807F31BEA830BF
:10019000B80A20753000052EE52EB40216752E0023
:1001A000052F052DE52DB4640A752D007400C0E0FF
:1001B000C0E032D0D0D082D083D000D0E03250081E
:1001C0003004057590FF21CC93F4F590223F065B37
:1001D0004F666D7D077F6F777C395E7971BF86DBF7
:1001E000CFE6EDFD87FFEF408000375C1C5874DCE4
:0101F00046C8
:1001F1007402252FB52FFD752D004396E130B3F71D
:100201007402252FB52FFD30B3EDC2AFC2AAB208DB
:08021100900257C082C0833245
:03000000020219E0
:0100030032CA
:03000B00020100EF
:040013000201F132C3
:01001B0032B2
:0300230002039E37
:100219004396E17580FF78207400F608B880FBD218
:100229000875B0FF75A0FF75200075B81275985054
:10023900758921758CFC758A6B758DFD758BFD75BE
:10024900A882758700D28ED28C7179439602C2AF8B
:10025900758107D2AFC209C2B2300857D2AA753D1B
:100269000A753C005320F0752D00439602E53D12B6
:1002790000267033853D36E53C1203D3701F853C5B
:10028900357170752D00439602744B252FB52FFDDE
:10029900752D00439602744B252FB52FFD053CE5BE
:1002A9003CB408C0753C00053DE53DB410B6753D4C
:1002B9000A416DD2AA432001752D0043960220B44C
:1002C900457402252FB52FFD20B43B752D004396AB
:1002D9000230B4F7E53CB4070F753C00053DE53D38
:1002E900B41007753D0A41F3053CE53D120026703F
:1002F900EB853D36E53C1203D370D9853C357170E9
:100309007464252F41C120B5457402252FB52FFDF1
:1003190020B5A5752D0043960230B5F7E53CB4002C
:100329000F753C07153DE53DB40907753D0F613B68
:10033900153CE53D12002670EB853D36E53C120380
:10034900D370D9853C3571707464252F41C1B52F9F
:1003590014E53D120026700DE53C1203D3700671B9
:10036900707464252F41C189318A328B338C3422D0
:10037900791E7A227B217C1F753521753620717093
:10038900744B252FB52FFD752D00439602744B250F
:050399002FB52FFD222D
:10039E00C0D0C000C0E0309825C29820090FE59962
:1003AE00B4401BD209753E40753F4961C2E599B410
:1003BE000D02C209A83EF6053ED53F02C209D0E0A5
:0503CE00D000D0D03288
:1003D30075F008A42405784028F5F0F8915AE5F063
:1003E3002407F891A8FEED6043E582F4C304F58287
:1003F300E583F43400F5837011E58214700C790FF2
:100403007A0F7B0F7C0F740F813CA982AA839163BF
:10041300E5F02407F891A8FE913DEC1470047C23C9
:1004230081317C237B097A197909813B913DEC70F9
:10043300077C1CEB70027B1CE422EB540FF9EB549A
:10044300F0C4FAEC540FFBEC54F0C4FCEE60072448
:1004530001F8E62410F622918889828A8391632227
:10046300C0E0C0D07B007C007D007E10C3E933F97F
:10047300EA33FA78037F03E636D4F608DFF9DEEDD4
:10048300D0D0D0E022C0E091A8540FC4F90891A8BD
:10049300540F42010891A8540FC4FA0891A8540FAD
:1004A3004202D0E022E6C3943A50022407240322F6
:00000001f
參考鏈接:http://www.picavr.com/news/2008-01/2748.htm
|