第一篇:FPGA編程經(jīng)驗(yàn)
整個(gè)verilog中是以module為編寫基本單元的,module不宜過大,目標(biāo)是實(shí)現(xiàn)一些基本功能即可,module的層次不宜太深,一般3-5層即可,給module劃分層次原則:實(shí)現(xiàn)最基本功能的為底層module,然后中層是調(diào)用這些基本module,實(shí)現(xiàn)大的功能,最高層是系統(tǒng)級(jí)模塊,統(tǒng)籌各大塊之間端口連接,時(shí)序關(guān)系等。
在module內(nèi)部編寫中,最基本塊是initial,always,以及assign塊(此外還有一些UDP原語,在行為級(jí)暫且不談),其他語句都要包含在這些塊里面。這其中,initial塊是不可綜合語句,可以用來編寫testbench,這里面的內(nèi)容在程序運(yùn)行時(shí)只執(zhí)行一次;assign語句是在不用寄存器的情況下直接編寫組合邏輯;always塊是最常用的塊,其語法格式是always @(*);其中括號(hào)里稱為敏感列表,即對(duì)于組合邏輯而言,必須是所實(shí)現(xiàn)邏輯的所有輸入變量,意思是當(dāng)組合邏輯的每一個(gè)變量發(fā)生變化,結(jié)果立刻發(fā)生變化(這與實(shí)際情況一致,對(duì)于任何組合邏輯,輸入變化,輸出立刻變化)。對(duì)于時(shí)序邏輯,常為
always@(posedge/negedge clk),指在時(shí)鐘上升沿/下降沿到來時(shí),輸出才根據(jù)那一時(shí)刻的輸入來決定輸出結(jié)果。
編程思想:
這一部分是我的心得體會(huì),一般講verilog的書肯定不會(huì)講這個(gè),因?yàn)檫@部分感覺的東西比較多,完全靠理解應(yīng)用,沒什么固定模式,呵呵,玄了點(diǎn)。不廢話了,開始切入正題。Verilog歸根到底還是編程,同時(shí)它是對(duì)電路的編程,所以就可以利用這兩個(gè)特點(diǎn),充分利用高級(jí)語言編程(例如C)的思想和數(shù)字電路的知識(shí),就會(huì)很大程度上幫助你。首先牢記,編寫verilog依據(jù)的是時(shí)間軸,根據(jù)時(shí)間順序確定各種信號(hào)何時(shí)進(jìn)入你的電路,可以在編寫時(shí)先把幾個(gè)主流信號(hào)(即貫穿于整個(gè)系統(tǒng)的信號(hào),比如數(shù)據(jù)流信號(hào))用always寫出來,這些信號(hào)就是你的基準(zhǔn),其他控制信號(hào)根據(jù)所處的位置在介入這些主流信號(hào),分別用 always
模塊寫入。這樣,這種時(shí)間軸順序跟C的編程思想就一致,在編寫這種順序性信號(hào)時(shí),帶著C的思想,基本就容易的多。同時(shí),verilog有個(gè)很重要的電路特點(diǎn),就是在每一時(shí)刻,同時(shí)會(huì)有多個(gè)電路有信號(hào)(即在運(yùn)行),這樣就必須從傳統(tǒng)的順序語言中跳出來(跳出C的思想),然后進(jìn)入數(shù)字電路的思想,即你的編程要時(shí)刻跟實(shí)際電路模型聯(lián)系到一起,比如A<=B,C<=A,即可以想象成兩個(gè)D觸發(fā)器,其中C的輸入就是A的輸出,這樣當(dāng)時(shí)鐘沿到來時(shí),兩個(gè)D觸發(fā)器同時(shí)運(yùn)行,B的值就給了A,而A的輸出就給了C,不考慮電路延時(shí),就可以認(rèn)為二者在時(shí)間軸的同一時(shí)刻運(yùn)行成功,A在此時(shí)刻的值為B,C 在此時(shí)刻的值就是A前一時(shí)刻的值。這里只是舉了簡單的例子,但是時(shí)間軸的思路、高級(jí)語言編程思想和數(shù)字電路模型化思想以及這幾個(gè)思想的轉(zhuǎn)換對(duì)于編程來說幫助很大,幫你在編程時(shí)頭腦時(shí)刻冷靜,即使有很多信號(hào),也會(huì)讓你從全局把握整個(gè)電路,避免頭腦一團(tuán)糟。
關(guān)于復(fù)用:
復(fù)用對(duì)于硬件設(shè)計(jì)來說,尤為重要,在實(shí)現(xiàn)功能的前提下,電路比的就是主頻和資源,而資源的減少思路就是復(fù)用。比如多次調(diào)用一個(gè)子函數(shù)A,如果直接寫,在結(jié)構(gòu)上就是這個(gè)子函數(shù)電路塊A的復(fù)制,電路完成后就會(huì)看到你調(diào)用了幾次A函數(shù),你的結(jié)構(gòu)中就有幾個(gè)一模一樣的A電路,當(dāng)你的A電路本身資源很大,而且你調(diào)用的次數(shù)很多時(shí),就很少有FPGA能裝的下了。這當(dāng)然跟我們的思想不符,我們只是想讓整個(gè)電路中只有一塊電路A,只不過把A電路在不同時(shí)刻用了幾次而已,這時(shí)就要用到電路復(fù)用的思想。電路復(fù)用并不神秘,簡單來講,就是把控制端放在A電路兩邊,用計(jì)數(shù)器之類的東西,控制在時(shí)間軸的不同時(shí)刻把值寫入A和從A輸出端讀取值。補(bǔ)充一點(diǎn),對(duì)于電路的同步,計(jì)數(shù)器是一個(gè)很好的東西,因?yàn)楸旧碛?jì)數(shù)器資源并不很大,用它來對(duì)于相差多個(gè)周期的信號(hào)進(jìn)行同步,非常實(shí)用。但是,當(dāng)信號(hào)相差的時(shí)間過于大,計(jì)數(shù)器的計(jì)數(shù)規(guī)模
就變的不可接受,這時(shí)就要用到狀態(tài)機(jī)劃分狀態(tài)的方法進(jìn)行同步了。有了同步,復(fù)用就變得簡單的多。
關(guān)于task:
這是前段時(shí)間論壇里討論比較熱的東西。語法上說,task是比always低個(gè)等級(jí),即task必須在always里面調(diào)用,task本身可以調(diào)用 task,但不能調(diào)用module(module的調(diào)用是與always,initial,assign語句并列的,所以在這些語句中均不能直接調(diào)用 module,只能采用給module端口送值的方法達(dá)到調(diào)用的目的)。Task有什么用呢,個(gè)人覺得,用task來封裝大的邏輯語句不錯(cuò),使代碼顯得簡單明了,這個(gè)對(duì)于testbench尤為有用,但在實(shí)際電路中用處不大,因?yàn)轫樞蛘{(diào)用task對(duì)于電路來說就是電路塊的復(fù)制,順序多次調(diào)用就是多次復(fù)制電路,資源會(huì)成倍增加,不能達(dá)到電路復(fù)用的目的,同時(shí)用task封裝的純邏輯代碼會(huì)使得電路的周期變大,主頻降低,不利于為了提高主頻而采用的大邏輯切分的方法!
第二篇:LabVIEW FPGA編程小結(jié)
LabVIEW FPGA編程小結(jié)
NI PXI-7813R為FPGA卡,板卡上引出4個(gè)端口,每個(gè)端口有40路引腳,共160路DIO,使用LabVIEW FPGA模塊進(jìn)行編程控制。當(dāng)FPGA程序復(fù)雜度變大或是使用的DIO端口數(shù)增多時(shí),可能面臨的主要問題包括FPGA空間不夠用以及實(shí)際循環(huán)時(shí)間過長等。之前編寫的 FPGA程序示意圖如下,采集循環(huán)與輸出循環(huán)獨(dú)立,均采用控件形式與RT程序通訊,兩塊板卡均使用了近120路DIO口。基于7813R板卡編程實(shí)踐及涉及到的幾個(gè)瓶頸問題,簡要做了一下總結(jié):
1)使用FIFO還是使用控件?
FPGA與RT通訊時(shí),常用的方法是使用讀寫FIFO或是使用輸入輸出控件。這兩者的特點(diǎn)是:
a)兩者在速度上無明顯差別。這是建立在不使用For循環(huán)的基礎(chǔ)上的,但實(shí)際中FIFO通常都要配合For循環(huán)來使用,F(xiàn)or循環(huán)相當(dāng)于串行操作,當(dāng)同類端口較多時(shí),使用for將導(dǎo)致循環(huán)時(shí)間變長,故運(yùn)行速度上FIFO并沒有多少優(yōu)勢(shì)。b)FIFO使用合理時(shí)不丟數(shù),而控件不能保證。
通過配置FPGA與RT中讀寫FIFO的超時(shí)以及FIFO大小,讀寫方式等手段,通??杀WCFIFO傳遞數(shù)據(jù)不丟數(shù)(可能要經(jīng)過多次嘗試);而使用控件則可能會(huì)有丟數(shù)的情況。當(dāng)不嚴(yán)格要求每次while循環(huán)都不丟數(shù)時(shí),可考慮使用控件,例如對(duì)DO輸出的配置,用戶可能很久才會(huì)去配置一次,而且配置后不會(huì)要求馬上生效,稍微晚幾個(gè)循環(huán)周期(us級(jí))再使配置生效也不會(huì)有很大影響,這種時(shí)候使用讀取控件值是合理的。c)FIFO可使用的數(shù)據(jù)類型有限,而控件幾乎無限制。
就7813R而言,F(xiàn)IFO只能傳遞指定的幾種類型的數(shù)據(jù),而使用控件時(shí),可使用包括簇?cái)?shù)組在內(nèi)的自定義控件。
所以,還是根據(jù)實(shí)際需要來選擇吧,雖然這句話跟沒說一樣~ 2)用不用For循環(huán)?
端口較多時(shí),很容易就遇到連續(xù)幾個(gè)都是要求采集脈寬的,而另外連續(xù)幾個(gè)要求采集電平即可。這時(shí)候很自然想到使用For循環(huán)對(duì)多個(gè)端口一起進(jìn)行操作,例如下圖:
如上面所說,使用FOR循環(huán)相當(dāng)于使端口操作(上圖中所說的操作是指將采集到的布爾轉(zhuǎn)成U32數(shù)值)變?yōu)榇?;另外,要使用For,通常就得配合數(shù)組操作,例如上圖中創(chuàng)建數(shù)組等,這樣就更加導(dǎo)致循環(huán)時(shí)間變長。當(dāng)發(fā)現(xiàn)循環(huán)時(shí)間不滿足使用要求時(shí),這種處理方法可能就不能使用了,每一路單獨(dú)處理就省掉了創(chuàng)建數(shù)組及For,節(jié)省了循環(huán)時(shí)間,但這樣又使重復(fù)代碼變多,工作量加大。
3)怎么使用子VI?
輸出脈沖時(shí),脈沖的產(chǎn)生可以封裝成一個(gè)子VI,供多路端口進(jìn)行使用;采集脈寬時(shí),脈寬采集可以封裝成一個(gè)子VI供多路端口進(jìn)行調(diào)用。然而,默認(rèn)情況下,子VI的執(zhí)行是串行的(因?yàn)椴]有設(shè)置VI屬性為“可重入執(zhí)行”),子VI在同一時(shí)間內(nèi)只能被一路端口所占用,可能導(dǎo)致的結(jié)果是循環(huán)時(shí)間變長,精度降低。如果設(shè)置子VI為可重入執(zhí)行,又可能導(dǎo)致FPGA空間占用率過高,編譯無法通過。我想到的一種折中的辦法是:使用幾個(gè)程序框圖一樣的子VI(功能完全一樣,將子VI多另存為幾個(gè)所生成)來代替原先一個(gè)子VI,替換之后,相當(dāng)于減少了串行運(yùn)行的子VI數(shù)量,循環(huán)用時(shí)減少明顯。下圖中使用6個(gè)子VI A,如果用2個(gè)B與2個(gè)C替換其中的4個(gè)A,循環(huán)時(shí)間可能減少為原來的1/3。
While循環(huán)方式1:子VI A子VI A子VI A子VI A子VI A子VI AWhile循環(huán)方式2:子VI A子VI A子VI B子VI B子VI C子VI C
4)精打細(xì)算
這一點(diǎn)可能只會(huì)在FPGA空間不夠用時(shí)才會(huì)被重視,下圖是邏輯片不夠用時(shí)導(dǎo)致的FPGA編譯失敗錯(cuò)誤:
因此,當(dāng)資源有限時(shí),盡量使用能滿足使用要求的最小長度的數(shù)據(jù)類型來實(shí)現(xiàn),能使用U16滿足要求的堅(jiān)決不用U32!另一方面,暫時(shí)還沒有發(fā)現(xiàn)數(shù)據(jù)類型變長時(shí)對(duì)FPGA循環(huán)運(yùn)行時(shí)間產(chǎn)生明顯影響。
5)循環(huán)延時(shí)考慮
脈沖輸出及采集均需要根據(jù)實(shí)際循環(huán)時(shí)間來計(jì)算,若參與運(yùn)算的值不是實(shí)際的循環(huán)時(shí)間,輸出或采集的結(jié)果自然不會(huì)準(zhǔn)確。例如可配置脈沖或電平輸出的端口,若輸出電平,其算法簡單,所需時(shí)間較少,而配置為脈沖輸出時(shí),算法復(fù)雜。配置為單路脈沖輸出可能不會(huì)有明顯的影響循環(huán)時(shí)間,但當(dāng)多路脈沖一起輸出時(shí),可能影響到循環(huán)時(shí)間增加1~2us甚至更長。故實(shí)際配置循環(huán)時(shí)間時(shí),需按照可能的最復(fù)雜算法進(jìn)行運(yùn)行測試,并依此來設(shè)置循環(huán)時(shí)間,以保證循環(huán)時(shí)間的確定性已經(jīng)算法運(yùn)算的正確性。
總而言之,設(shè)計(jì)時(shí)還是應(yīng)該根據(jù)實(shí)際需要,綜合考慮數(shù)據(jù)完整性、FPGA板卡資源大小、循環(huán)時(shí)間等因素,已達(dá)到滿意效果。
第三篇:編程經(jīng)驗(yàn)
1.當(dāng)性能遇到問題時(shí),如果能在應(yīng)用層進(jìn)行計(jì)算和處理,那就把它從數(shù)據(jù)庫層拿出來。排
序和分組就是典型的例子。在應(yīng)用層做性能提升總是要比在數(shù)據(jù)庫層容易的多。就像對(duì)于MySQL,sqlite更容易掌控。
2.關(guān)于并行計(jì)算,如果能避免就盡量避免。如果無法避免,記住,能力越大,責(zé)任越大。
如果有可能,盡量避免直接對(duì)線程操作。盡可能在更高的抽象層上操作。例如,在iOS中,GCD,分發(fā)和隊(duì)列操作是你的好朋友。人類的大腦沒有被設(shè)計(jì)成用來分析那些無窮臨時(shí)狀態(tài)——這是我的慘痛教訓(xùn)所得。
3.盡可能簡化狀態(tài),盡可能局部本地化,適用至上。
4.短小可組合的方法是你的好朋友。
5.代碼注釋是危險(xiǎn)的,因?yàn)樗鼈兒苋菀赘虏患皶r(shí)或給人誤導(dǎo),但這不能成為不寫注釋的理由。不要注釋雞毛蒜皮的事情,但如果需要,在某些特殊地方,戰(zhàn)略性的長篇注釋是需要的。你的記憶會(huì)背叛你,也許會(huì)在明天早上,也許會(huì)在一杯咖啡后。
6.如果你認(rèn)為一個(gè)用例場景也許“不會(huì)有問題吧”,它也許就是一個(gè)月后讓你在發(fā)布的產(chǎn)品
中遭受慘痛失敗的地方。做一個(gè)懷疑主義者,測試,驗(yàn)證。
7.有疑問時(shí),和團(tuán)隊(duì)中所有相關(guān)人交流。
8.做正確的事情——你通常會(huì)知道這指的是什么。
9.你的用戶并不傻,他們只是沒有耐心理解你的捷徑。
10.如果一個(gè)開發(fā)人員沒有被安排長期的維護(hù)你們開發(fā)的系統(tǒng),對(duì)他保持警惕。80%的血、汗、淚水都是在軟件發(fā)布后的時(shí)間里流的——那時(shí)你會(huì)變成一個(gè)厭世者,但也是更聰明的“行家”。
11.任務(wù)清單是你的好朋友。
12.主動(dòng)讓你的工作更有樂趣,有時(shí)這需要你付出努力。
13.悄無聲息的崩潰,我仍然會(huì)為此從噩夢(mèng)中驚醒。監(jiān)控,日志,警報(bào)。清楚各種的假警報(bào)
和不可避免的感覺鈍化。保持你的系統(tǒng)對(duì)故障的敏感和及時(shí)警報(bào)。
14.復(fù)雜是大敵。
第四篇:基于VHDL編程FPGA的地鐵自動(dòng)售票機(jī)
地鐵自動(dòng)售票機(jī)
一、設(shè)計(jì)要求
1、功能描述
用于模仿地鐵售票自動(dòng)售票,完成地鐵售票的核心控制功能。
2、功能要求
售票機(jī)有兩個(gè)進(jìn)幣孔,一個(gè)是輸入硬幣,識(shí)別的范圍是一元硬幣;一個(gè)是紙幣,識(shí)別的范圍是一元、兩元、五元、十元、二十元。乘客可以連續(xù)多次投入錢幣。乘客 一次只能選擇一個(gè)出站口,購買車票時(shí),乘客先選出站口,有六個(gè)出站口可供選擇,再選擇所需的票數(shù),然后投幣,投入的錢幣達(dá)到或者超過所需金額時(shí),售票機(jī)自 動(dòng)出票,并找零。本次交易結(jié)束后,等待下一次交易。在選擇出站口、所需票數(shù)以及在投幣期間,乘客可以按取消鍵取消操作,錢幣自動(dòng)退出。
二、實(shí)驗(yàn)分析
1、買票時(shí),乘客按下開始鍵,售票機(jī)進(jìn)入站臺(tái)選擇程序,乘客選擇出站口后,可以按取消鍵重新選擇,否則售票機(jī)自動(dòng)進(jìn)入票數(shù)選擇程序,同樣這時(shí)可以按下取消鍵重新開始選擇出站口以及票數(shù)。
2、當(dāng)選擇好出站口以及所需票數(shù)時(shí),乘客可以投硬幣或者用紙幣,當(dāng)所投的錢幣總額大于或者等于票價(jià)時(shí),售票機(jī)自動(dòng)出票以及找零。期間,可以按下取消鍵重新開始選擇,并退出所有的錢幣。
3、乘客若還沒選擇出站口或者票數(shù),就投幣或者使用紙幣,售票機(jī)會(huì)自動(dòng)退出所有的錢幣。
4、有六個(gè)站臺(tái)可供乘客選擇,每個(gè)乘客最多可以買3張票,六個(gè)站臺(tái)編號(hào)為1到6,票價(jià)從2元依次遞增到7。
三、系統(tǒng)流程圖
四、程序源代碼 LIBRARY IEEE;USE IEEE.std_logic_1164.ALL;USE IEEE.std_logic_arith.ALL;USE IEEE.std_logic_unsigned.ALL;ENTITY metrosell IS PORT(clk:in std_logic;startselect:in std_logic;sure:in std_logic;save your forward step(s)coin1y:in std_logic;pmoney1y:in std_logic;pmoney2y:in std_logic;pmoney5y:in std_logic;pmoney10y:in std_logic;money pmoney20y:in std_logic;money cancel:in std_logic;number:in std_logic_vector(3 downto 0);the tickets platform:in std_logic_vector(3 downto 0);want to reach moneystorage:out std_logic;acceptmo:out std_logic;stamp:out std_logic;--set the clock signal--start to select the platform--this button is to--1 yuan coin
--1 yuan paper money--2 yuan paper money--5 yuan paper money--10 yuan paper--20 yuan paper--cancel the forward step(s)--choose the number of--choose the platform you--to store the money--accept the money--stamp outgate charge:out std_logic_vector(3 downto 0);--the mount of charge,up to 15 yuan chargegate:out std_logic--charge outgate);END metrosell;ARCHITECTURE sell OF metrosell IS type state_type is(initial_type,selectp_type,selectnum_type,insert_type,stamp_type,charge_type);--define six types signal state:state_type;--define a shared state BEGIN main:process(clk,state,startselect,platform,number,coin1y,pmoney1y,pmoney2y,pmoney5y,pmoney10y,pmoney20y,cancel,sure)variable univalence :integer range 0 to 7;--the univalence of the ticket variable total_money :integer range 0 to 21;--the price of the ticket(s)variable selectp_alr:std_logic;--the flag of select platform type variable selectnum_alr:std_logic;--the flag of select number type variable stamp_alr:std_logic;--the flag of the stamp gate variable charge_alr:std_logic;--the flag of the charge gate variable money_reg:integer range 0 to 21;--the mount of money put in variable coin1y_f:std_logic;--the flag of one yuan coin variable pmoney1y_f:std_logic;--the flag of one yuan paper money variable pmoney2y_f:std_logic;--the flag of two yuan paper money variable pmoney10y_f:std_logic;--the flag of ten yuan paper money variable pmoney20y_f:std_logic;--the flag of twelve yuan paper money variable pmoney5y_f:std_logic;--the flag of five yuan paper money variable charge_reg:integer range 0 to 15;
begin if(rising_edge(clk))then case state is when initial_type => variables univalence:=0;selectp_alr:='0';selectnum_alr:='0';stamp_alr:='0';charge_alr:='0';money_reg:=0;total_money:=0;coin1y_f:='0';pmoney1y_f:='0';pmoney2y_f:='0';pmoney5y_f:='0';
--the register of charge--initialize some pmoney10y_f:='0';pmoney20y_f:='0';moneystorage<='0';stamp<='0';charge_reg:=0;charge<=“0000”;acceptmo<='0';chargegate<='0';if(startselect='1')then state<=selectp_type;end if;when selectp_type => if(selectp_alr='0'and cancel='0')then--choose the platform if(platform=“0001”)then univalence:=2;selectp_alr:='1';elsif(platform=“0010”)then univalence:=3;selectp_alr:='1';elsif(platform=“0011”)then univalence:=4;selectp_alr:='1';elsif(platform=“0100”)then univalence:=5;selectp_alr:='1';elsif(platform=“0101”)then univalence:=6;selectp_alr:='1';elsif(platform=“0110”)then univalence:=7;selectp_alr:='1';elsif(platform=“0000”)then univalence:=0;selectp_alr:='0';else null;end if;elsif(selectp_alr='1'and cancel='1')then state<=initial_type;elsif(selectp_alr='1'and sure='1')then state<=selectnum_type;end if;when selectnum_type =>--you can buy at most 3 tickets if(selectnum_alr='0'and cancel='0')then--choose the number of tickets if(number=“0001”)then if(univalence=2)then total_money:=2;selectnum_alr:='1';elsif(univalence=3)then total_money:=3;selectnum_alr:='1';elsif(univalence=4)then total_money:=4;selectnum_alr:='1';elsif(univalence=5)then total_money:=5;selectnum_alr:='1';elsif(univalence=6)then total_money:=6;selectnum_alr:='1';elsif(univalence=7)then total_money:=7;selectnum_alr:='1';elsif(univalence=0)then total_money:=0;selectnum_alr:='0';else null;end if;end if;
if(number=“0010”)then if(univalence=2)then total_money:=4;selectnum_alr:='1';elsif(univalence=3)then total_money:=6;selectnum_alr:='1';elsif(univalence=4)then total_money:=8;selectnum_alr:='1';elsif(univalence=5)then total_money:=10;selectnum_alr:='1';elsif(univalence=6)then total_money:=12;selectnum_alr:='1';elsif(univalence=7)then total_money:=14;selectnum_alr:='1';elsif(univalence=0)then total_money:=0;selectnum_alr:='0';else null;end if;end if;if(number=“0011”)then if(univalence=2)then total_money:=6;selectnum_alr:='1';elsif(univalence=3)then total_money:=9;selectnum_alr:='1';elsif(univalence=4)then total_money:=12;selectnum_alr:='1';elsif(univalence=5)then total_money:=15;selectnum_alr:='1';elsif(univalence=6)then total_money:=18;selectnum_alr:='1';elsif(univalence=7)then total_money:=21;selectnum_alr:='1';elsif(univalence=0)then total_money:=0;selectnum_alr:='0';else null;end if;end if;elsif(selectnum_alr='1'and cancel='1')then state<=initial_type;elsif(selectnum_alr='1'and sure='1')then state<=insert_type;end if;when insert_type => moneystorage<='1';if(money_reg
when 2 => charge<=“0010”;when 3 => charge<=“0011”;when 4 => charge<=“0100”;when 5 => charge<=“0101”;when 6 => charge<=“0110”;when 7 => charge<=“0111”;when 8 => charge<=“1000”;
end case;end if;
when 9 => charge<=“1001”;when 10 => charge<=“1010”;when 11 => charge<=“1011”;when 12 => charge<=“1100”;when 13 => charge<=“1101”;when 14 => charge<=“1110”;when 15 => charge<=“1111”;when others => charge<=“0000”;end case;if(charge_reg>0 and charge_alr='0')then chargegate<='1';charge_alr:='1';elsif(charge_reg=0 and charge_alr='0')then chargegate<='0';charge_alr:='1';else state<=initial_type;end if;end process main;END sell;
五、波形仿真
1、乘客按下開始按鈕,進(jìn)入選站臺(tái)模式,選擇二號(hào)站臺(tái),按下確定鍵,再選擇票數(shù)為2張,按下確定鍵,售票機(jī)錢箱關(guān)閉,投入一張兩元和五元紙幣(對(duì)順序沒有要求),此時(shí)錢幣總額大于票價(jià),出兩張票并找零一元。之后系統(tǒng)進(jìn)入初始化狀態(tài)。具體仿真如圖 1 仿真1
圖 1 仿真1
2、測試cancel鍵,當(dāng)乘客按正確的操作完成選站臺(tái)時(shí),按下取消鍵,再重新選擇,如圖 2 cancel仿真,仿真波形如下。
圖 2 cancel仿真
3、還是測試cancel鍵,當(dāng)乘客選擇好票數(shù)時(shí),按下cancel鍵,然后重新選擇兩張單價(jià)為七塊錢的六號(hào)站臺(tái)票,投入一張20元和5元,找零六元。仿真波形如圖 3 cancel仿真2
圖 3 cancel仿真2
4、乘客選擇五號(hào)站臺(tái),兩張票,然后先后投入一元紙幣,兩元紙幣,一元紙幣,五元紙幣,然后按下取消鍵,售票機(jī)自動(dòng)放出所有的錢幣。仿真如圖 4 cancel仿真3。
圖 4 cancel仿真3
六、心得體會(huì)
在我的設(shè)計(jì)中,有一個(gè)moneystorage信號(hào)量用于控制儲(chǔ)存錢幣箱的開與關(guān),這個(gè)設(shè)計(jì)主要考慮到當(dāng)乘客要求退幣時(shí),最好不是從售票機(jī)中取出投入的錢數(shù),然后退還,設(shè)置了這個(gè)開關(guān),就可以在按下取消鍵時(shí),直接從儲(chǔ)存錢幣箱中退出錢幣。
還有,乘客選擇的站臺(tái)以及票數(shù),在售票機(jī)內(nèi)部會(huì)自動(dòng)將這兩個(gè)信號(hào)傳給出票系統(tǒng),從而自動(dòng)出票,以上寫的程序只是讓系統(tǒng)知道怎樣收錢以及找零。
這次實(shí)驗(yàn)總體上來說比六人搶答器簡單,但是因?yàn)檫@個(gè)售票機(jī)完全是自己寫的,所以也不是想象中的那么簡單。這也讓我看出,要完全自己去做一件東西不是簡單的,特別是要考慮很全面,還是要發(fā)一些時(shí)間的。
第五篇:PLC編程經(jīng)驗(yàn)詳談
PLC編程經(jīng)驗(yàn)詳談
(晴天)2009-3-17 13:31:00
------------------
PLC程序調(diào)試步驟
人的腦力是有限的,并且記事情也有時(shí)間性。過了N天就會(huì)忘記每次修改的原因,為什么要加這條指令,為什么要?jiǎng)h除這個(gè)網(wǎng)絡(luò),讓自己以后看自己以前編寫的程序時(shí)都會(huì)很困惑。做到以下步驟,對(duì)所有程序理解與修改會(huì)有很大幫助的。
1、把原有程序另存一個(gè), 在另存的程序上作修改。文件命名一個(gè)主要的程序名稱,標(biāo)注第幾次修改,并加上修改的日期,最好是在文件名外加上簡要的修改標(biāo)題。例如: 《 捆扎程序5(06.10.23翻板步進(jìn)電機(jī)加條件)》
2、用.doc文件記錄修改的年月日。
3、在日期下面記錄修改程序的步驟,增加或是刪除了哪些指令等。并在程序的編輯條注釋中做記錄,以備下次修改。
4、在.doc文件中詳細(xì)記錄修改程序的原因,所出現(xiàn)的故障現(xiàn)象是什么,故障是如何排除的。
5、在.doc文件中標(biāo)注修改后所現(xiàn)用的程序全名,包括日期與簡要的修改標(biāo)題。
6、把過時(shí)與現(xiàn)用的程序用,過時(shí)文件夾與現(xiàn)用文件夾分開整理,按日期排列。
這樣每次所作的修改就有了詳細(xì)的檔案,便于以后的程序修改。現(xiàn)用的程序是標(biāo)有最近日期的程序。
這樣的工作步驟同時(shí)也適用于電氣圖紙的修改
PLC編程經(jīng)驗(yàn)
弄通有關(guān)PLC程序設(shè)計(jì)理論是重要的。沒有這方面的理論準(zhǔn)備或指導(dǎo),僅靠在實(shí)踐中摸索,簡單的問題還好辦。復(fù)雜的就不好辦了。不僅無從下手,而且花了很多時(shí)間與精力,也難編出效率較高、質(zhì)量也較高的程序,常常是事倍功半。
但是,編程的具體實(shí)踐,以及在這個(gè)實(shí)踐中得來的知識(shí)或技能,即經(jīng)驗(yàn),也是重要的。沒有經(jīng)驗(yàn),僅有理論,既無法深刻理解理論,又無法靈活應(yīng)用理論。這正如學(xué)數(shù)學(xué),如僅了解一些定理或記住一些公式,沒有作相應(yīng)的練習(xí),肯定是學(xué)不好的。更不用說,任何理論也都只是經(jīng)驗(yàn)的總結(jié),歸根到底也都有是來自實(shí)踐。
1、經(jīng)驗(yàn)積累
經(jīng)驗(yàn)有別人的,也有自己的,都很重要。前者要靠細(xì)心學(xué)習(xí),后者要靠用心積累,都要在一定的時(shí)間與必要的精力。
別人的經(jīng)驗(yàn)有上了書的或登載在雜志上的。有的是細(xì)心學(xué)習(xí)別人的,但多數(shù)是我自己的經(jīng)驗(yàn)。所有的例子都經(jīng)我測試過,都經(jīng)實(shí)踐證明是可行的。我想,別的書本或雜志上介紹的也會(huì)是這樣的。所以學(xué)習(xí)這樣楊功的經(jīng)驗(yàn)是必要的。
還有就是你同事的經(jīng)驗(yàn),也是值得學(xué)習(xí)。這種經(jīng)驗(yàn)離你很“近”,很易借鑒。
自己的經(jīng)驗(yàn)則是最重要的。要在自己的實(shí)踐中,積累自己的經(jīng)驗(yàn)。同時(shí),最好在學(xué)別人的經(jīng)驗(yàn)時(shí),也能親自作些測試,能使自己也有類似的經(jīng)歷,進(jìn)而把這些經(jīng)驗(yàn)變成自己的。這也是自己經(jīng)驗(yàn)的重要積累。
還有一些失敗的經(jīng)驗(yàn),這往往是不會(huì)公開的,但這些經(jīng)驗(yàn)也要學(xué)習(xí),也要積累。
經(jīng)驗(yàn)的積累要用自己的腦記,更要用電腦記。最好作些分類,建立一個(gè)自用的程序庫,以便于隨時(shí)引用。
2、經(jīng)驗(yàn)升華
經(jīng)驗(yàn)還有待升華。升華有三個(gè)層次:
最低的層次就是建立一個(gè)典型的程序庫,供今后再用。若程序復(fù)雜,還可建一些功能塊,或子程序,以便以后引用。
其次,要總結(jié)出有效算法。如單按鈕起停程序庫等。
最高層次的升華是把經(jīng)驗(yàn)上升到理論的高度,為豐富PLC程序設(shè)計(jì)理論作貢獻(xiàn)。我想,隨著PLC使用的普及與提高,是會(huì)有越來越多從經(jīng)驗(yàn)中升華出來的,而又能用以指導(dǎo)實(shí)踐的PLC編程理論的。
3、經(jīng)驗(yàn)應(yīng)用
經(jīng)驗(yàn)積累、經(jīng)驗(yàn)升華都是為了應(yīng)用。經(jīng)驗(yàn)應(yīng)用有三方面:
1)用作工程設(shè)計(jì)模板。設(shè)計(jì)新系統(tǒng)時(shí),選用一個(gè)或幾個(gè)與現(xiàn)設(shè)計(jì)工程類似的,已取得成功的工程,作樣板進(jìn)行設(shè)計(jì)。這既可減輕設(shè)計(jì)的工作量,又增加設(shè)計(jì)的成功率。這也是信息可重用的一大好處。
2)用作程序設(shè)計(jì)參考。在無成功的工程可作樣板時(shí),在新設(shè)計(jì)的邏輯中,仍有相當(dāng)一部分控制邏輯,可采用或借用已有典型邏輯,這也可減少設(shè)計(jì)的工作量,增加設(shè)計(jì)的成功率。
3)用作算法設(shè)計(jì)參考。在既無樣板可參照,又無典型可采用時(shí),還可運(yùn)用過去的一些成功的算法。
經(jīng)驗(yàn)是寶貴的,但是經(jīng)驗(yàn)特別是個(gè)人經(jīng)驗(yàn),總是有限的。所以,經(jīng)驗(yàn)的應(yīng)用也還要與編程理論相結(jié)合PLC現(xiàn)場工程師工作指南
一、出發(fā)前的準(zhǔn)備
從事PLC的技術(shù)支持的人,如果是要到現(xiàn)場開始進(jìn)行系統(tǒng)調(diào)試,無論是對(duì)OEM客戶,還是對(duì)一個(gè)過程控制的系統(tǒng)集成,都要在事先做好一些準(zhǔn)備工作。就像一個(gè)“驢友”出行前,要更換自己的服裝尤其是鞋子,帶好水、食品,還要準(zhǔn)備在野外的一些防身用品,如果是過夜的話,還要有帳篷、手電筒等一樣,作為一個(gè)職業(yè)的PLC技術(shù)支持工程師,也有不少的東西是要準(zhǔn)備的。
首先要安排自己的行程計(jì)劃和衣食住行。如果是需要住宿的話,那么如何定機(jī)票、酒店(旅館、招待所),這里就不多說了。如果時(shí)間很長(如超過一個(gè)月),為了省錢,就要考慮在當(dāng)?shù)刈夥孔恿?,尤其是出發(fā)的是一個(gè)小組,而不是一個(gè)人的時(shí)候。衣食住行,這些問題與普通的旅行是一樣的,雖然這些問題對(duì)你完成任務(wù)的影響力并不亞于你的專業(yè)水平。想
象一下,你到了現(xiàn)場,因?yàn)槭澄镏卸緦?dǎo)致一個(gè)星期拉痢疾的情況會(huì)對(duì)工作造成什么樣的影響,就知道該準(zhǔn)備那些東西了。通常,有經(jīng)驗(yàn)的自動(dòng)化公司的行政部門會(huì)為工程師考慮好這些情況,但是,作為工程師自己一定要進(jìn)行確認(rèn),看看是否所有的事情都已經(jīng)安排好了。
安頓好了衣食住行的后,要準(zhǔn)備自己的工具。作為PLC的現(xiàn)場調(diào)試工程師,并不需要很多的調(diào)試工具。但是,一個(gè)螺絲刀、一臺(tái)萬用表,還是必備的。另外,如果要與現(xiàn)場的儀表傳感器進(jìn)行系統(tǒng)聯(lián)調(diào)的時(shí)候,還要有一臺(tái)信號(hào)發(fā)生器來模擬現(xiàn)場儀表的信號(hào),以確定當(dāng)發(fā)生問題時(shí),現(xiàn)場的信號(hào)是完好的。還有,一臺(tái)結(jié)實(shí)的手提電腦,是你編程和調(diào)試的必需的工具。雖然這些工具你可以要求用戶準(zhǔn)備好,但是,作為一個(gè)職業(yè)的PLC工程師,如果連這幾樣工具都沒有,會(huì)被用戶懷疑你的職業(yè)水平的。其它的一些儀器儀表,如果需要的話,你可以向公司或者客戶提出來,讓他們提前準(zhǔn)備,比如,示波器、穩(wěn)壓電源等等。畢竟這些不那么通用的儀器,通常是不可能隨身攜帶或備用的。
有一些常被忽視的小東西,你準(zhǔn)備了之后一定有用的。如,電氣膠帶、熱縮套管、打火機(jī)(你吸煙的話自然會(huì)有,沒有別人也會(huì)有),束線帶、還有,如果現(xiàn)場接線已經(jīng)完成了,要準(zhǔn)備好一些與信號(hào)線相同的電纜,和一些固定基座的螺絲。你可能懷疑要這些做什么用,相信我,帶上這些,雖然有些只值幾分錢,但到了現(xiàn)場后,可能會(huì)節(jié)約你一天甚至幾天的時(shí)間,尤其是你去的地方是在一個(gè)偏遠(yuǎn)的山區(qū)的時(shí)候。雖然在發(fā)貨的時(shí)候廠家都有螺絲釘,但是到了現(xiàn)場什么都有可能發(fā)生,如果螺絲釘不夠(而這是每次都必然發(fā)生的),會(huì)引起許多問題。
除了以上的東西,就是這次調(diào)試所要帶的備品備件了。雖然現(xiàn)場的貨物清單可能會(huì)已經(jīng)考慮了備品備件的問題,但為了應(yīng)付萬一的情況,有些備件你最好還是自己要隨身攜帶。首先是PLC的基板(有的成為機(jī)架)、電源、CPU模塊,因?yàn)檫@些是一臺(tái)PLC能夠工作的基礎(chǔ),如果現(xiàn)場只有一套系統(tǒng),那么這些模塊就只有一個(gè),假如沒有備分的話,一旦出現(xiàn)故障,你的所有的工作都必須停下來。因此最好帶上一套。
其它的I/O模塊和通訊模塊,如果現(xiàn)場只有一個(gè)的,你都要考慮在多帶一個(gè)。對(duì)于那些現(xiàn)場已經(jīng)有兩塊以上的模塊,你就不用考慮自己帶了。
二、設(shè)計(jì)交底工作
如果系統(tǒng)設(shè)計(jì)不是你自己做的,那么在出發(fā)前,就要與系統(tǒng)的設(shè)計(jì)人員進(jìn)行充分的溝通,對(duì)于不清楚和不明白的地方,一定要弄清楚,確保自己清晰地理解了要完成的工作目標(biāo),和設(shè)計(jì)者的意圖。不要輕易否定設(shè)計(jì)者的方案,也不要輕易地說別人那里設(shè)計(jì)得不行。
但是,因?yàn)槟闶菑氖卢F(xiàn)場的工程師,因此,也不必過于迷信設(shè)計(jì)者。你可以提出自己的建議。比如,PLC的機(jī)架和CPU模塊和I/O模塊的搭配原則,可能有時(shí)候,設(shè)計(jì)師不知道你所用的 PLC的機(jī)架有4槽、6槽和8槽,甚至12槽的,因此,也許全部都選了8槽的,而導(dǎo)致了幾個(gè)槽的空缺,你可以建議它修改為4槽或6槽的。
方案設(shè)計(jì)中,最容易出問題的地方是通訊,現(xiàn)場調(diào)試最麻煩的地方也是通訊,所以對(duì)于通訊的部分,你必須清晰了解系統(tǒng)的框架結(jié)構(gòu),并且對(duì)需要進(jìn)行通訊的東西在出發(fā)前就要全部進(jìn)行一遍調(diào)試,而且要確認(rèn)其中的所有需要通訊的模塊是可以通訊的。比如,操作臺(tái)電腦、觸摸屏、PLC、變頻器、其它的PLC、一些智能儀表和儀器,如果這些東西需要通訊的話,你必須要確認(rèn)它們相互之間是可以通訊的,如果你不確認(rèn)的話,就要與廠家聯(lián)絡(luò),并親自再試一次。如果PLC的節(jié)點(diǎn)數(shù)較多,要考慮距離和廠家CPU的限制。
如果系統(tǒng)較大,遠(yuǎn)程單元、本地機(jī)架數(shù)量、每個(gè)機(jī)架的模塊數(shù)量的限制,并非出于系統(tǒng)功能和技術(shù)上的限制,而是由于使用規(guī)范性的限制。在系統(tǒng)硬件組態(tài)時(shí),要考慮這些模塊的搭配作用。
對(duì)于電源模塊的配置,一個(gè)資深的工程師應(yīng)該能夠做出比較合理的搭配。例如,電源模塊通常有5A和10A的分別,如果模塊較少,可以選用功率小的電源模塊,如果模塊較多,則應(yīng)該選用大功率的電源模塊。而一般,如果現(xiàn)場儀表需要PLC也供應(yīng)24V直流電源而不是采用外部電源供電(如RTU)的情景,通常CPU所在的機(jī)架上選用大功率的電源比較合理。
此外,在I/O模塊的安裝時(shí),根據(jù)不同的系統(tǒng),通常同型號(hào)的模塊放置在一起。但是,如果對(duì)于輸出模塊與輸入模塊形成回路的,則可以將一個(gè)回路的參量所涉及的模塊放置在一個(gè)機(jī)架上(或一個(gè)CPU所控制的機(jī)架上)比較合理。有的設(shè)計(jì)師在設(shè)計(jì)的時(shí)候不會(huì)考慮這一點(diǎn),你可以調(diào)整過來。
在選型的時(shí)候,因?yàn)楦鞣NPLC都有大型、中型、小型的分別,這些分別主要是由CPU模塊的性能不同造成的。在實(shí)際上,并非一定大型的功能就是合適的。除了價(jià)格方面的考量之外,主要是,如果控制點(diǎn)數(shù)不多,小型的CPU模塊完全可以勝任,則小型的CPU反而比大型的CPU模塊工作還要可靠一些。因?yàn)?,小型的CPU所涉及的資源少,而大型CPU的資源多,在程序執(zhí)行中,為處理那些程序不需用到的資源時(shí),也要分配時(shí)間去處理,這樣不僅造成資源的浪費(fèi),可能在程序處理上不及小型CPU可以更單純和穩(wěn)定地工作。
在設(shè)計(jì)交底的過程中要指出的是,對(duì)于設(shè)計(jì)中的任何變更,你只能提建議,而不是擅自做修改。因?yàn)?,你的職?zé)是按照設(shè)計(jì)施工,而不是設(shè)計(jì),因此,對(duì)于任何你發(fā)現(xiàn)的不合理的東西,你可以提出意見,但必須要等到設(shè)計(jì)變更確認(rèn)書下到你手里后,你才能按照變更后的設(shè)計(jì)工作,盡管這個(gè)變更可能是你的意見。還有,即使最初的設(shè)計(jì)也是你做的,你在變更后,也要通知客戶,并取得客戶的書面同意。
三、裝機(jī)步驟
到了現(xiàn)場后,進(jìn)行系統(tǒng)安裝前,需要考慮安裝環(huán)境是否滿足PLC的使用環(huán)境要求,這一點(diǎn)可以參考各類產(chǎn)品的使用手冊(cè)。但無論什么PLC,不都能裝設(shè)在下列場所:含有腐蝕性氣體之場所,陽光直接照射到的地方,溫度上下值在短時(shí)間內(nèi)變化急遽的地方,油、水、化學(xué)物質(zhì)容易侵入的地方,有大量灰塵的地方,振動(dòng)大且會(huì)造成安裝件移位的地方。
如果必須要在上面的環(huán)境使用,則要為PLC制作合適的控制箱,采用規(guī)范和必要的防護(hù)措施。如果需要在野外極低溫度下使用,可以使用有加熱功能的控制箱。如何做這些防護(hù)箱或控制箱,各制造商和和資格的系統(tǒng)集成商將會(huì)為客戶提供相應(yīng)的供應(yīng)和設(shè)計(jì)。
在使用控制箱時(shí),在控制箱內(nèi)OpenPLC安裝的位置要注意如下事項(xiàng):控制箱內(nèi)空氣流通是否順暢(各裝置間須保持適當(dāng)?shù)木嚯x),變壓器、馬達(dá)控制器、變頻器等是否與PLC保持適當(dāng)距離,動(dòng)力線與信號(hào)控制線是否分離配置,組件裝設(shè)之位置是否利于日后之檢修,是否需預(yù)留空間,供日后系統(tǒng)擴(kuò)充使用。
除了上述注意事項(xiàng)之外,還有其它注意事項(xiàng)要留意。
首先比較重要的是靜電的隔離。靜電是無形的殺手,但可能因?yàn)椴粫?huì)對(duì)人造成生命危險(xiǎn),所以許多人常常忽視它。在中國的北方、干燥的場所,人體身上的靜電都是造成靜電損壞電子組件的因素。雖然你被靜電打到的話,只不過是輕微的酥麻,但這對(duì)PLC和其它任何電子器件就足以致命了。
要避免靜電的沖擊有下列三種方式:在進(jìn)行維修或更換組件時(shí),請(qǐng)先碰觸接地的金屬,以去除身上的靜電;不要碰觸電路板上的接頭或是IC接腳;電子組件不使用時(shí),請(qǐng)用有隔離靜電的包裝物,將組件放置在里面。想象PLC里的元器件是一個(gè)嬌嫩的嬰兒,而那些靜電會(huì)導(dǎo)致這個(gè)嬰兒死亡,你就會(huì)更容易以正確的態(tài)度對(duì)待這個(gè)問題了。
基座安裝(RACK)時(shí),在決定控制箱內(nèi)各種控制組件及線槽位置后,要依照?qǐng)D紙所示尺寸,標(biāo)定孔位,鉆孔后將固定螺絲旋緊到基座牢固為止。在裝上電源供應(yīng)模塊前,必須同時(shí)注意電源線上的接地端有無與金屬機(jī)殼連結(jié),若無則須接上。接地不好的話,會(huì)導(dǎo)致一系列的問題,靜電、浪涌、外干擾,等等。由于不接地,往往PLC也能夠工作,因此,不少經(jīng)驗(yàn)不足的工程師就誤以為接地不那么重要了。這就像登山的時(shí)候,沒有系上保護(hù)纜繩一樣,雖然你正常前進(jìn)的時(shí)候,保護(hù)纜繩沒有任何作用,但一旦你失足的時(shí)候,沒有那根繩子,你的生命就完結(jié)了。PLC的接地,就相當(dāng)于給PLC系上保護(hù)纜繩。
在I/O模塊安裝時(shí),須注意如下事項(xiàng):I/O模塊插入機(jī)架上的槽位前,要先確認(rèn)模塊是否為自己所預(yù)先設(shè)計(jì)的模塊;I/O模塊在插入機(jī)架上的導(dǎo)槽時(shí),務(wù)必插到底,以確保各接觸點(diǎn)是緊密結(jié)合的;模塊固定螺絲務(wù)必鎖緊;接線端子排插入后,其上下螺絲必須旋緊。由于現(xiàn)場的變壓器、電機(jī)等影響,多少會(huì)有振動(dòng),如果這些螺絲釘松動(dòng)了,會(huì)導(dǎo)致模塊從機(jī)架中松開