在本教程中,您將學習如何在 EAGLE CAD 中編寫您的第一個 ULP,以便為您的 CAD 工具添加新功能。
用戶語言程序 (ULP) 是 EAGLE CAD 用戶的一組擴展程序,用于以自動化方式促進日常工作或完成在沒有 ULP 幫助的情況下無法完成的工作。例如,將圖像導入 PCB 設計的唯一方法是使用命令 import-bmp ULP。在原理圖中自動放置、導出 BOM 和重新編號零件都是 ULP 可以提供幫助的日常工作。
從開發人員的角度來看,EAGLE ULP 與 C 有很多相似之處——實際上,它是一種用于開發這些擴展的類 C 語言。那么為什么它是一門重要的編程語言要學習呢?主要原因是開發自己的 ULP 來幫助自己和其他設計師。此外,ULP 主要由業余愛好者和工程師在空閑時間編寫,這通常意味著將來很少進行維護或修訂。
就個人而言,我一直在使用 ULP 在 PCB 上產生倒置(又名負)絲印。網絡上唯一可用的 ULP, negasilk (鏈接打開 zip 文件)可以執行我想要的工作,但步驟繁瑣。因為這個 ULP 不能直接應用于我的設計,所以我應該在一個新的 PCB 文件中運行它——復制輸出,然后將其粘貼回原始設計。了解 ULP 的基礎知識幫助我改進了流程,首先讓我自己和其他人更容易。
ULP 的第一眼
EAGLE 用戶語言可用于訪問 EAGLE 數據結構并創建各種輸出文件。
EAGLE 中有三種主要的數據結構類型:lbr、sch 和 brd。我認為稱它們為對象更明智,因為這些數據結構有兩種類型的成員:數據成員和循環成員。
數據成員存儲文件名、網格單元和符號名稱等數據,而循環成員用于在相同對象類型的元素之間切換,如原理圖文件或庫對象中零件的循環功能。循環的每個運行實例成員都包含數據成員。
你感到困惑嗎?別擔心,下面的例子會讓事情變得更清楚。示例 ULP 將獲取每個部件名稱并計算部件數量。基本上,要開發 ULP,您需要一個文本編輯器和一個帶有 ulp 擴展名的文本文件。
string Names,result;
int Number=0;
schematic(S)
{
S.parts(P)
{
Number++;
Names+=P.name;
Names+=“,”;
}
sprintf(result,“%d Parts, Names:%s”,Number,Names);
dlgMessageBox(result,“+OK”);
}
運行上一個 ULP 的輸出。
原理圖(S)語句用于訪問原理圖的上下文以分別到達其中的所有對象。S,原理圖對象的標識符,執行{。.}之間的代碼塊。原理圖對象(UL_SCHEMATIC 對象)有自己的數據和循環成員來訪問其他對象(零件、圖紙等)。
如我們所見, S.parts(P)是負責為每個部分P制作循環的方法。
UL_SCHEMATIC 對象的數據和循環成員。
在 ULP 手冊中,您可以找到有關每個對象及其成員的大量文檔。我將在樹形圖中總結它們。
讓我們退后一步;通常,ULP 的結構包括聲明變量、定義函數(如果可用),最后是主程序。無需放置 main 函數(void main()),盡管我可以找到一些帶有/不帶有 main 函數的 ULP。簡單地說,函數和變量定義之后的任何語句都被認為是主函數。
讓我們修改第一個示例以計算設計有多少張圖紙以及每張圖紙中有多少零件。
string Names,result;
int Number=0; schematic(S) { S.parts(P) { Number++; Names+=P.name; Names+=","; } sprintf(result,"%d Parts, Names:%s",Number,Names); dlgMessageBox(result,"+OK"); }
讓我們在樹上遵循這個:
將命令傳遞給編輯器
有兩種方法可以將命令傳遞給 EAGLE 編輯器。
第一個選項是使用 exit()函數。這是最前沿的方式;它終止 ULP 的執行并將命令傳遞給編輯器。命令必須是此內置函數的字符串參數。例如, exit(“Move R1”)將使 EAGLE 在終止 ULP 后執行該命令。
第二個選項是創建一個可以稍后執行的腳本文件。雖然腳本(.src 文件)不是我們對本教程的興趣,但知道腳本包含(非常基本)一組編輯器命令就足夠了。
ULP 執行后,會創建腳本文件,您可以使用SCRIPT file_name 運行它;命令或從菜單欄中的腳本圖標。一般來說,使用退出函數比較常見。
要查看退出函數的實際作用,我們將編寫一個簡單的程序,將當前日期作為文本添加到第 21 層中的設計中。
string Names,result;
int Number=0,Sh_Number=0; schematic(S) { S.sheets(Sh) { Sh_Number++; Sh.parts(P) { Number++; Names+=P.name; Names+=","; } sprintf(result,"Sheet #%d with %d Parts, Names:%s",Sh_Number,Number,Names); dlgMessageBox(result,"+OK"); Number=0; Names=""; } }
庫和原理圖是整數常量,如果當前編輯器窗口是庫或原理圖則返回 1,否則返回 0。
dlgMessageBox("! Open this ULP from PCB Editor","+OK");
這將帶來一個帶有消息的彈出窗口。我們將簡要解釋 ULP 中的對話框。
exit(-1);
將終止 ULP(錯誤情況)。
string Months[]= {"Jan","Feb","Mar","Apr","May","June","July","Aug","Sept","Oct","Nov","Dec"}; int t = time(); string CMD,text;
這是變量聲明。
time()函數是一個內置函數,它以數字格式返回系統時間。
CMD = "GRID INCH;LAYER 21;"; CMD += "CHANGE SIZE 0.066;"; CMD += "CHANGE RATIO 15%;"; CMD += "CHANGE FONT VECTOR;";
這些命令用于將網格單位設置為英寸并更改文本大小、比例和字體類型。您必須用分號分隔命令。
sprintf(text,"TEXT '%d %s %d'",t2day(t),Months[t2month(t)],t2year(t));
sprintf函數用于格式化數據字符串。
exit(CMD);
exit函數會將 CMD 字符串傳遞給編輯器并終止 ULP 執行。
EAGLE ULP 中的對話框
ULP 為作為用戶語言程序前端的對話框提供了一組內置函數。
dlgDialog是任何其他對話框對象的基本容器。它執行由括號{..}之間的塊定義的對話框。
作為介紹,我們將構建一個簡單的對話框,該對話框由一個帶有“Hello”標題和“Ok”按鈕的窗口組成。
int Result = dlgDialog("Hello") { dlgLabel("Hello world"); dlgPushButton("OK") { dlgMessageBox("! YOU PRESSED OK!","OK"); dlgAccept(); } };
dlgDialog有一個字符串參數來定義對話框標題。
dlgPushButton添加一個名為 OK 的按鈕,而 dlgMessageBox顯示一個帶有 OK 按鈕的簡單消息框。最后,退出對話框dlgAccept函數接受對話框內容(這里沒有內容)并關閉它。
運行上一個 ULP 的輸出。
注意:對話框中的文本中使用了一些特殊字符,如&、+和-來完成特定工作。
‘&’指定熱鍵以使焦點轉到該對象/標簽。
‘+’當您按 Enter 時選擇按鈕。
‘-’ 當您按下 Esc 時使按鈕被選中。
例子:
int result = dlgMessageBox("Try To Press:","+Enter","&O","-Esc");
switch(result) { case 0: dlgMessageBox("YOU PRESSED OK!"); break; case 1: dlgMessageBox("YOU PRESSED O!"); break; case 2: dlgMessageBox("YOU PRESSED Esc!"); break; }
運行上一個 ULP 的輸出。
其他對話框功能用于用戶輸入,如列表視圖、單選按鈕和數據字段輸入。
閱讀其用法說明后,您可以輕松使用任何其他對話框功能。同時,在 ULP 手冊中還可以找到許多同類別的其他功能。
dlgListView
dlgListView使用給定數組的內容定義了一個多列列表視圖。它需要三個主要參數:第一個參數是定義列表視圖標題的字符串參數,第二個參數是要顯示為列表項的字符串數組,第三個參數是反映所選索引的整數數組中的 listview 元素。dlgListView可以包含在您雙擊元素時執行的代碼塊。
dlgRadioButton
dlgRadioButton定義一個帶有給定文本的單選按鈕。它有兩個參數:第一個參數是使用字符串來定義按鈕旁邊的文本,第二個參數是一個整數,它反映了從使用 dlgGroup函數定義的組中選擇的單選按鈕。同一組內的所有單選按鈕必須使用相同的選擇變量。
dlgString編輯
dlgStringEdit定義了一個字符串輸入字段。它有一個字符串參數來包含用戶輸入的值。注意:它的工作方式與 dlgRealEdit 和 dlgIntEdit 的工作方式相同。
讓我們將上述信息付諸實踐。在下面的示例中,我們將檢查dlgListView、dlgRadioButton和dlgStringEdit的用法。
string Items[] = { "Item One", "Item Two", "Item Three" }, Item ;
int L_Selected = 0,R_Selected=0; // initially selects "One" int Result = dlgDialog("Items") { dlgLabel("Choose One:"); dlgHBoxLayout { dlgListView("Name\tDescription", Items, L_Selected) { dlgMessageBox("You have selected " + Items[L_Selected]); } dlgGroup("Items") { dlgRadioButton("&One", R_Selected); dlgRadioButton("&Two", R_Selected) {dlgMessageBox("You have selected " + Items[L_Selected]);} dlgRadioButton("&Three", R_Selected); } } dlgVBoxLayout { dlgLabel("Enter &Item"); dlgStringEdit(Item); dlgPushButton("OK") { dlgMessageBox("You have selected from ListView " + Items[L_Selected] + ". From RadioButton " + Items[R_Selected] + ", and entered "+ Item); dlgAccept(); } } };
運行上一個 ULP 的輸出。
dlgListView(“Name\tDescription”, Items, L_Selected)
如上圖所示,列表視圖具有“名稱”和“描述”標題,并顯示項目數組的元素。所選項目索引將存儲在L_Selected中。
如果您在列表的任何項目上單擊兩次——代碼塊將執行。
dlgGroup("Items")
{ dlgRadioButton("&One", R_Selected); dlgRadioButton("&Two", R_Selected) {dlgMessageBox("You have selected " + Items[L_Selected]);} dlgRadioButton("&Three", R_Selected); }
單選按鈕必須使用dlgGroup組合在一起,并共享相同的選擇變量R_Selected。如果單擊單選按鈕“Two”,您將看到一條消息,這是單選按鈕如何執行代碼的示例。
注意: dlgHBoxLayout和dlgVBoxLayout分別用于水平和垂直排列布局。
鍛煉
作為一個小練習,您可以編寫一個簡單的 ULP,根據其大小使用框架庫中的可用框架將適當的框架添加到您的示意圖中。我為您測量了框架,以便在本練習中使用它。您需要掃描圖紙以了解其尺寸。
以 Mil 為單位的尺寸
要解決此練習,您將使用以下技能:
使用數據和循環成員獲取計算圖紙尺寸所需的數據的能力。
使用 EAGLE 命令將設備添加到設計中的能力。
在 ULP 中使用對話框的能力。
注意:只是為了好玩,我在菜單欄上添加了一個圖標。您可以通過在 SCH: 部分中將以下行添加到位于安裝目錄中 src 文件夾中的 eagle.scr 文件中來做到這一點。
-
CAD
+關注
關注
17文章
1092瀏覽量
72487 -
EAGLE
+關注
關注
4文章
35瀏覽量
21342 -
ULP
+關注
關注
0文章
13瀏覽量
10858
發布評論請先 登錄
相關推薦
評論