;load("D:/mdd/PlaceCapsUnderBga.il")
axlCmdRegister("Pcub' 'SPBXA_Pcub_main ?cmdType "interactive")
g_verPcub = "20241211-022"
2024.12.09:第一次完成,实现水平或垂直方向上相邻电源地管脚的滤波电容放置
2024.12.10:优化从封装名中提取主pitch间距;2024.12.11:优化实现1.95倍*主pitch范围内 的电源地管脚;
defstruct(PwrPinInfo, aPin, strNetName, strRef, strNumber, fPoint_x, fPoint_y, tableGndPins)
;主程序:完成全局变量的初始化、界面的初始化
procedure(SPBXA_Pcub_main()
let((pcbunit,curDesign,curLayers,strFunType,strContent,etchParam,etchLayer_list)
;if( accreditedFun() then when( axIOKToProceed())
g_pcbunit = "mil" ;全局单位,mm或mils
g_pcbprecision = cadr(axlDBGetDesignUnits());全局精度,1,2,3,4
pcbunit = car(axIDBGetDesignUnits()); 提取PCB的单位
if("millimeters" == pcbunit then;如果单位为mm,则设置为1/39.37
g_pcbunit $=$ "mm"
g_tableSym2Ref $=$ nil;
1
Pcub_mark $=$ nil
g_PcubExecute = nil
SPBXA_Pcub_Popup
SPBXA_Pclub_form $=$ nil SPBXA_Pclub_create_form()
;记录调用信息
etchParam = ax1GetParam("paramLayerGroup:etch")
etchLayer_list = etchParam->groupMembers
curDesign = axlCurrentDesign()
curLayers = printf(nil, %d, length(etchLayer_list))
strFunType = "BGA\261\263\303\346\302\313\262\250\265\347\310\335\262\274\276\326";BGA背面滤波电容布局
strContent = strcat("DsnName:" curDesign "><Units:" pcbunit "><Layers:" curLayers ">")
toolCallRecord(strFunType, strContent)
);if( accreditFun() then);let and procedure
;初始化对话框
defun SPBXA_Pclub_create_form()
let((SPBXA_Pcub_form_file, lstGndNets, dbDesign,aNet,strNama)
SPBXA_Pclub_form_file = "/SPBXA_Pclub_form.form"
SPBXA_Pclub_create_form_file(SPBXA_Pclub_form_file)
SPBXA_Pclub_form = axlFormCreate( (gensym), SPBXA_Pclub_form_file, nil;SPBXA_Pclub_action_form, t);生成主界面 if(isFile(SPBXA_Pclub_form_file) then deleteFile(SPBXA_Pclub_form_file)
else
printf("*** Warning, cannot delete\n" SPBXA_Pclub_form_file);endif
lstGndNets $=$ nil
dbDesign $\equiv$ axIDBGetDesign()
foreach(aNet, dbDesign->nets
strNetName $\equiv$ upperCase( aNet->name)
if(index(strNetName,"GND") &&nil $= =$ member(strNetName, lstGndNets) then lstGndNets $\equiv$ append1( lstGndNets,strNetName)
)
)
if( lstGndNets then
lstGndNets $=$ sort( lstGndNets,'alphalessp)
axlFormBuildPopup(SPBXA_Pcub_form,"Text_GndNets",lstGndNets)
if(1 $= =$ length(1stGndNets) then
axlFormSetField(SPBXA_Pcub_form, "Text_GndNets", nth(0, lstGndNets))
axlUIWDisableQuit(SPBXA_Pclub_form)
axlFormDisplay(SPBXA_Pcub_form)
axlControlRaise('options')
);defun
;菜单动作
(defun SPBXA_Pcub_action_form (SPBXA_Temp_form)
let( (strAddDist,fAddDist)
case(SPBXA_Temp_form->curField
("BtN_SelCaps" axlFinishEnterFun() axlShell("done")
axlFormSetFieldEditable(SPBXA_Temp_form, "Text_GndNets", nil)
axlFormSetFieldEditable(SPBXA_Temp_form, "BtN_SelCaps", nil)
axlFormSetFieldEditable(SPBXA_Temp_form, "BtN_SelBg", nil)
SPBXA_Pcub_SelCaps(SPBXA_Temp_form)
axiShell("done")
axlFormSetFieldEditable(SPBXA_Temp_form, "Text_GndNets", t)
axlFormSetFieldEditable(SPBXA_Temp_form, "Btn_SelCaps", t)
axlFormSetFieldEditable(SPBXA_Temp_form, "Btn_SelBga", t)
t);("AddDist"
("BtN_SelBga" axlFinishEnterFun() axlShell("done")
axlFormSetFieldEditable(SPBXA_Temp_form, "Text_GndNets", nil)
axlFormSetFieldEditable(SPBXA_Temp_form, "BtN_SelCaps", nil)
axlFormSetFieldEditable(SPBXA_Temp_form, "BtN_SelBga", nil)
SPBXA_Pcub_SelBgas(SPBXA_Temp_form)
axlFormSetFieldEditable(SPBXA_Temp_form, "Text_GndNets", t)
axlFormSetFieldEditable(SPBXA_Temp_form, "Bt_n_SelCaps", t)
axlFormSetFieldEditable(SPBXA_Temp_form, "Bt_n_SelBga", t)
t) ;("AddDist"
("BtncClose" if( g_PcubExecute then SPBXA_Pcub_Done() axlFormClose(SPBXA_Temp_form) t
);( "Btnc_Close"
)
);;Defun
procedure(SPBXA_Pclub_CapDone()
let( () axlUIppuset(nil) axlUIWprint(nil"-Done-") axlFinishEnterFun() axlShell("done") axlFormSetFieldEditable(SPBXA_Pclub_form, "Text_GndNets", t) axlFormSetFieldEditable(SPBXA_Pclub_form, "Btnc_SelCaps", t) axlFormSetFieldEditable(SPBXA_Pclub_form, "Btnc_SelBga", t));end let and procedure
procedure(SPBXA_Pclub_Done()
let( () axlUIppuset(nil) axlUIWprint(nil"-Done-") axlDBTransactionCommit(Pclub_mark) g_PclubExecute $=$ nil axlFinishEnterFun() axlShell("done") axlFormSetFieldEditable(SPBXA_Pclub_form, "Text_GndNets", t) axlFormSetFieldEditable(SPBXA_Pclub_form, "Btnc_SelCaps", t) axlFormSetFieldEditable(SPBXA_Pclub_form, "Btnc_SelBga", t));end let and procedure
procedure(SPBXA_Pclub_Cancel()
let( () axlUIppuset(n极) axlUIWprint(nil"-Cancel-") axlDBTransactionRollback(Pclub_mark) g_PclubExecute $=$ nil axlFinishEnterFun() axlShell("done") axlFormSetFieldEditable(SPBXA_Pclub_form, "Text_GndNets", t) axlFormSetFieldEditable(SPBXA_Pclub_form, "Btnc_SelCaps", t) axlFormSetFieldEditable(SPBXA_Pclub_form, "Btnc_SelBga", t));end let和procedure
(defun SPBXA_Pclub_SelCaps (SPBXA_Tempt_form) prog( ( strRef,strPackage,strPinNet_1,strPinNet_2,Noobj,strRef,aPin )
g_tableSym2Ref $=$ makeTable( "g_table极2Ref",nil) ;;封装对应的位号 strRef $=$ nil strPackage $=$ nil strPinNet_1 $=$ nil strPinNet_2 $=$ nil
;创建菜单 SPBXA_Pclub_Popup $=$ axlUIppuPDefine( nil(list ("Done" 'SPBXA_Pclub_CapDone) )) axlUIppupSet(SPBXA_Pclub_Popup) axlClearSelSet()
axlSetFindFilter(?enabled list("noall" "Symbols") ?onButtons list("noall" "Symbols")) axlClearSelSet() ;请选择滤波电容器
listobjs $=$ axlGetSelSet(axlSelect(? prompt $"\{307\backslash 353\backslash 321\backslash 241\backslash 324\backslash 361\backslash 302\backslash 313\backslash 262\backslash 250\backslash 265\backslash 347\backslash 310\backslash 335\backslash 306\backslash 367\backslash 274\backslash 376.\} )$ if(listobjs then foreach(aObj, listobjs ;位号 strRef $=$ aObj->refdes ;当前封装 ;记录0402类型电容(封装名中包含了滤波电容) strPackage $=$ upperCase(aObj->name) println("SPBXA_Pclub_SelCaps") if(strRef && index(strPackage,"0402C") && 2 == length(aObj->pins) then strRef $=$ upperCase(strRef) strPinNet_1 $=$ nil strPinNet_2 $=$ nil ;第1个管脚网络 aPin $=$ nth(0,aObj->pins) strPinNet_1 $=$ upperCase(aPin->net->name) ;第2个管脚网络 aPin $=$ nth(1,aObj->pins) strPinNet_2 极$ upperCase(aPin->net->name) ;按封装名记录 println(strRef) println(strPackage) println(strPinNet_1) println(strPinNet_2) g_tableSym2Ref[ strPackage] $=$ append1(g_tableSym2Ref[strPackage], list( strRef, strPackage, strPinNet_1, strPinNet_2)) ) ;foreach(aObj, listobjs);if listobjs axlUIPopupSet( nil); axlClearSelSet(); axlFinishEnterFun(); axlShell("done") ) (defun SPBXA_Pclub_SelBgas(SPBXA_Temp_form) prog( ( strNet_Pwr,strNet_Gnd,DBDesign,bGndFlag,aNet,strRef,strPackage,aObj,lstPins,aPin,aNet_Pwr,lstInfo,tableCapsToPlace,aSymbol_B GBA,strRef_BGA, strPackage_BGA,fPinDist_BGA,lstElems,strTmp,fRotation_BGA) strNet_Pwr $=$ nil strNet_Gnd $=$ nil ;电源网络名,屏蔽,从拾取的电源管脚上获取 strNet_Gnd $=$ axlFormGetField(SPBXA_Temp_form, "Text_GndNets") strNet_Gnd $=$ axlStringRemoveSpaces(strNet_Gnd) strNet_Gnd $=$ upperCase(strNet_Gnd) ;请先设置地网络名. if( \*\*strNet_Gnd then printf("\307\\353\\317\\310\\311\\350\\326\\303\\265\\330\\315\\370\\302\\347\\303\\373.\n")
return(nil)
} dbDesign $\equiv$ axlDBGetDesign() bGndFlag $\equiv$ nil foreach(aNet,dbDesign->nets if( upperCase(aNet->name) $\equiv$ strNet_Gnd then bGndFlag $=$ t ) ;;设置的地网络名不存在: if(nil $\equiv$ bGndFlag then printf(strcat("\311\\350\\326\\303\\265\\304\\265\\330\\315\\370\\302\\347\\303\\373\\262\\273\\264\\346\\324\\332:", strNet_Gnd,.n") return(nil) ;滤波电容默认为0402类型,封装名上带0402C的 strRef $\equiv$ nil tableCapsToPlace $\equiv$ makeTable("tableCapsToPlace",nil);存储满足封装名及两端网络的待放置电容 ;创建菜单 SPBXA_Pcub_Popup $\equiv$ axlUIPopuDefine( nil(list (list "Done" 'SPBXA_Pcub_Done) (list "Cancel" 'SPBXA_Pcub_Cancel) ) axlUIPopuSet(SPBXA_Pcub_Popup) Pcub_mark $\equiv$ axlDBTransactionStart() aObj $\equiv$ nil while(g_PcubExecute ;请选择BGA上的1个电源管脚 printf("\307\\353\\321\\241\\324\\361 BGA\\311\\317\\265\\304 1\\270\\366\\265\\347\\324\\264\\271\\334\\275\\305.\n") axlClearSelSet() axlSetFindFilter(?enabled list("noall" "Pins") ?onButtons list("noall" "Pins")) axlClearSelSet() lstPins $\equiv$ axlGetSelSet(axlSingleSelectPoint()) if(lstPins then if(1 $\equiv$ length(lstPins) then aPin $\equiv$ nth(0,lstPins) tableCapsToPlace $\equiv$ makeTable("tableCapsToPlace",nil);存储满足封装名及两端网络的待放置电容 ...;获取滤波电容列表 aNet_Pwr $\equiv$ nil aNet_Pwr $\equiv$ aPin->net strNet_Pwr $\equiv$ nil if( aNet_Pwr then strNet_Pwr $\equiv$ upperCase(aNet_Pwr->name) if( strNet_Pwr != strNet_Gnd then foreach( strPackage,g_tableSym2Ref foreach( lstInfo,g_tableSym2Ref[strPackage] ;g_tableSym2Ref按照器件封装名存储的电容信息列表 if( (strNet_Pwr $\equiv$ nth(2,lstInfo) && strNet_Gnd $\equiv$ nth(3,lstInfo)) || (strNet_Pwr $\equiv$ nth(3,lstInfo) && strNet_Gnd $= =$ nth(2,lstInfo)) then tableCapsToPlace[ nth(0,lstInfo)] $=$ lstInfo ; nth(0,lstInfo)为位号; ("C24" "0402C-N" "VCC3.3V" "GNDD") ) ) ;管脚所在器件 aSymbol_BGA $\equiv$ aPin->parent ;位号
strRef_BGA = aSymbol_BGA->refdes
;当前封装
strPackage_BGA = upperCase( aSymbol_BGA->name)
;判断位号是否以D开头,封装名中是否包含BGA以及-nRnn[-]表示管脚间距的字符
print("strRef_BGA.")
println(strRef_BGA)
if (rexMatchp("D[0123456789]+", strRef_BGA) && 2 < length(aSymbol_BGA->pins) && rexMatchp("BGA", strPackage_BGA) && rexMatchp([-0123456789]+R[0123456789]+[-]++, strPackage_BGA) then
println("strRef_BGA OK")
fPinDist_BGA = nil
lstElems = nil
lstElems = parseString( strPackage_BGA, "_")
foreach( strTmp, lstElems
if (index(strTmp, "BGA") == nil && rexMatchp([-0123456789]+R[0123456789]+", strTmp) then
rxCompile("R")
strTmp = rexReplace( strTmp, "", 0)
fPinDist_BGA = axlMKSCovert( strcat(strTmp,"mm"),g_pcbunit);;atof(strTmp) ;
);
);foreach( strTmp, lstElems
;从封装名中提取管脚间距,则继续放置
println(fPin极st_BGA)
if (fPinDist_BGA then
fRotation_BGA = 0.0
fRotation_BGA = aSymbol_BGA->rotation
;BGA器件以水平或垂直放置,则准备放置电容,否则暂不放置
println("fRotation_BGA.")
println(fRotation_BGA)
if (abs(fRotation_BGA - 0.0) <= 0.01 || abs(fRotation_BGA - 90.0) <= 0.01 || abs(fRotation_BGA - 180.0) <=
0.01 || abs(fRotation_BGA - 270.0) <= 0.01 then
......;逐个提取BGA中的电源网络及管脚位置
SPBXA_Pclub_PlaceCapsForPwrGnd( aSymbol_BGA, strNet_Pwr, strNet_Gnd, fPinDist_BGA, tableCapsToPlace )
axlDBTransactionMark(Pclub_mark)
else
;BGA器件不是以水平或垂直放置;;;这种情况下不放置滤波电容
printf("BGA\\306\\367\\274\\376\\262\\273\\312\\307\\322\\324\\313\\256\\306\\275\\273\\362\\264\\271\\326\\261\\267\\305\\326\\303.\n")
else
;无法从封装名中提取管脚间距
printf("\\316\\336\\267\\250\\264\\323\\267\\342\\327\\260\\303\\373\\326\\320\\314\\341\\310\\241\\271\\334\\275\\305\\274\\344\\276\\340.\n")
;if( fPinDist_BGA then
;if( rexMatchp("D[0123456789]+", aObj->name) && 2 < length(aObj->pins) && rexMatchp("BGA", strPackage) &&
rexMatchp([-0123456789]+R[0123456789]+[-]++, strPackage) then
else
;电源网络和地网络不能是同一网络
printf("\\265\\347\\324\\264\\315\\370\\302\\347\\272\\315\\265\\330\\315\\370\\302\\347\\262\\273\\304\\334\\312\\307\\315\\254\\322\\273.\n")
else
;选择的电源网络为空
printf("\\321\\241\\324\\361\\265\\304\\265\\347\\324\\264\\315\\370\\302\\347\\316\\252\\277\\325.\n")
;if( aNet_Pwr then
);foreach( aObj, listobjs
);if listobjs
);whileg_PcubExecute axlClearSelSet() axlUI镇政府nil)
获取某个BGA中的指定电源及地网络的管脚及坐标,并进行分析
defun SPBXA_Pclub_PlaceCapsForPwrGnd ( aSymbol_BGA, strNet_Pwr, strNet_Gnd, fPinDist_BGA, tableCapsToPlace) prog(
strRef_BGA, lstPwrPins, lstGndPins, tablePwr2Gnd, aPin_Pwr, aPin_Gnd, strPinNumber_Pwr, strPinNumber_Gnd, aPinInfo, aPinInfo_Gnd, a PinInfo_Pwr, fDistTemp,
fPointCap_x,fPointCap_y,bMirrored_Bga,bMirrored_Cap,bMirrored_target,lstPlacedPins,lstPlacedRefs,lstVis,aPin,lstObjs,aObj,strRef, bFlag_Placed,
lstCapsNum,fAngle_target,fAngle)mirror,fAngle_Rel,fPoint(rel,fPoint_ref,bMirror_ref,strRef_cap,aSymbol_cap,fAngle_cap,lstSymbol Caps,iIndex,
fDist_x,fDist_y,strDist)
strRef_BGA = aSymbol_BGA->refdes
lstPwrPins $=$ nil
lstGndPins $=$ nil
println("SPBXA_Pcub_PlaceCapsForPwrGnd start")
foreach( aPin, aSymbol_BGA->pins
if(aPin->net then
提取器件上的电源管脚列表
if(aPin->net->name == strNet_PWR then
lstPwrPins = append1( lstPwrPins, list(strRef_BGA, aPin->number, strNet_Pwr, fPinDist_BGA, aPin->xy, nth(0, aPin->xy), nth(1, aPin->xy)))
)
::提取器件上的地管脚列表
if( aPin->net->name == strNet_Gnd then lstGndPins = append1( lstGndPins, list( strRef_BGA, a极->number, strNet_Gnd, fPinDist_BGA, aPin->xy, nth(0, aPin->xy), nth(1, aPin->xy)) )
);foreach(aPin,aSymbol_BGA->pins
tablePwr2Gnd = makeTable("tablePwr2Gnd", nil)
aPin Pwr = nil
aPin_Gnd = nil
strPinNumber_Pwr = nil
strPinNumber_Gnd = nil
aPinInfo $=$ nil
aPinInfo_Gnd = nil
逐个提取器件上的电源管脚
aPinInfo_Pwr = nil
foreach( aPin_Pwr, lstPwrPins
strPinNumber_Pwr = nth(1, aPin_Pwr)
··
aPinInfo = make_PwrPinInfo()
aPinInfo->strRef = nth(0, aPin_Pwr)
aPinInfo->strNumber = nth(1, aPin_Pwr)
aPinInfo->aPin = aPin_PWR
aPinInfo->tableGndPins = makeTable("tableGndPins", nil)
……
逐个提取器件上的地管脚,并按1倍间距,sqrt(2)倍间距,2倍间距和sqrt(8)倍间距记录
foreach( aPin_Gnd, lstGndPins
strPinNumber_Gnd = nth(1,aPin_Gnd)
;println(aPin_Gnd)
fDistTemp = axlDistance(nth(4, aPin_Pwr), nth(4, aPin_Gnd))
一倍间距
if(abs(fDistTemp - fPinDist_BGA) <= 0.1 then
aPinInfo->tableGndPins[1] = append1(aPinInfo->tableGndPins[1], aPin_Gnd)
1.414倍间距
if(abs(fDistTemp - sqrt(2)*fPinDist_BGA) <= 0.1 then
aPinInfo->tableGndPins[2] = append1(aPinInfo->tableGndPins[2], aPin_Gnd)
);2倍间距 if(abs(fDistTemp - 2*fPinDist_BGA) <= 0.1 then aPinInfo->tableGndPins[3] = append1(aPinInfo->tableGndPins[3], aPin_Gnd) );;sqrt(5)倍间距 if(abs(fDistTemp - sqrt(5)*fPinDist_BGA) <= 0.1 then aPinInfo->tableGndPins[4] = append1(aPinInfo->tableGndPins[4], aPin_Gnd) ) ;;水平 pwr->Gnd if(abs(nth(1, nth(4, aPin_Pwr)) - nth(1, nth(4, aPin_Gnd))) <= 0.1 then fDist_x = nth(0, nth(4, aPin_Gnd)) - nth(0, nth(4, aPin_Pwr)) strDist = printf(nil, "%010.4f", 10000.0 + abs(fDist_x)) ;水平朝右 pwr->Gnd if ( fDist_x > 0.1 && fDist_x < 1.95*fPinDist_BGA then aPinInfo->tableGndPins[5] = append1(aPinInfo->tableGndPins[5], list(strDist, aPin_Gnd)) ) ;水平朝左 pwr->Gnd if ( fDist_x < -0.1 && fDist_x > -1.95*fPinDist_BGA then aPinInfo->tableGndPins[6] = append1(aPinInfo->tableGndPins[极], list(strDist, aPin_Gnd)) ) ;垂直 pwr->Gnd if(abs(nth(0, nth(4, aPin_Pwr)) - nth(0, nth(4, aPin_Gnd))) <= 0.1 then fDist_y = nth(1, nth(4, aPin_Gnd)) - nth(1, nth(4, aPin_Pwr)) strDist = printf(nil, "%010.4f", 10000.0 + abs(fDist_y)) ;垂直朝上 pwr->Gnd if ( fDist_y > 0.1 && fDist_y < 1.95*fPinDist_BGA then aPinInfo->tableGndPins[7] = append1(aPinInfo->tableGndPins[7], list(strDist, aPin_Gnd)) ) ;处置朝下 pwr->Gnd if ( fDist_y < -0.1 && fDist_y > -1.95*fPinDist_BGA then aPinInfo->tableGndPins[8] = append1(aPinInfo->tableGndPins[8], list(strDist, aPin_Gnd)) ) ;;foreach( aGndPin, lstGndPins ) foreach( index, list(5,6,7,8) if ( aPinInfo->tableGndPins[lIndex] then aPinInfo->tableGndPins[lIndex] = sortcar( aPinInfo->tableGndPins[lIndex], 'alphalessp') ) tablePwr2Gnd(strPinNumber_Pwr) = aPinInfo } ;foreach( aPwrPin, lstPwrPins ) ;先遍历放置1倍间距的中间情况,在遍历放置1倍间距两侧的情况 ifPointCap_x = nil ifPointCap_y = nil
bMirrored_Cap = nil
bMirrored_target = nil
...
lstPlacedPins = nil;记录BGA管脚处已经放置了器件的的管脚号
lstPlacedRefs = nil;记录重新放置的滤波电容位号
;获取BGA背面已经放置了器件的管脚号
;仅显示背面管脚,过孔不显示
lstVis = axlVisibleGet()
axlVisibleDesign(nil)
if(bMirrored_Bga then
axlVisibleLayer("PIN/TOP", t)
axlVisibleLayer("Package Geometry/TOP", t)
else
axlVisibleLayer("PIN/Bottom", t)
axlVisibleLayer("Package Geometry/Bottom", t)
)
axlVisibleUpdate(t)
......
axlClearSelSet()
axlSetFindFilter(?enabled list("noall" "SYMBOLS") ?onButtons list("symbols"))
println("lstPlacedRefs=")
foreach( aPin, aSymbol_BGA->pins
axlClearSelSet()
lstObjs = axlGetSelSet( axlSingleSelectPoint( aPin->xy))
if( lstObjs then
lstPlacedPins = append1( lstPlacedPins, aPin->number)
foreach( aObj, lstObjs
strRef = aObj->refdes
if( strRef then
strRef = upperCase(strRef)
if( tableCapsToPlace[strRef] && nil == member(strRef, lstPlacedRefs) then
println(strRef)
lstPlacedRefs = append1( lstPlacedRefs, strRef)
)
)
)
axlClearSelSet()
);foreach( aPin, aSymbol_BGA->pins
axlClearSelSet()
;重新显示原先的层显示
axlVisibleDesign(nil)
axlVisibleSet( lstVis)
axlVisibleUpdate(t)
;逐个电源管脚判断
bFlag_PLaced = nil
fAngle_target = nil
foreach( strPinNumber_Pwr, tablePwr2Gnd
if( nil == member( strPinNumber_Pwr, lstPlacedPins) then
;println(strcat("strPinNumber_Pwr, tablePwr2Gnd Begin = ", strPinNumber_Pwr))
aPinInfo = tablePwr2Gnd[strPinNumber_Pwr]
;("D30" "M3" "VCC1.8V" 31.49606 (5189.68 4182.84) 5189.68 4182.84)
aPinInfo_Pwr = aPinInfo->aPin
;先判断最近的管脚上的电容
bFlag_Placed = nil; 表示当前电源管脚在本次放置过程中成功放置滤波电容
lstCapsNum = list(1, 2, 3, 4)
lstCapsNum = list(5, 6, 7, 8)
;foreach( aPinInfo_Gnd, aPinInfo->tableGndPins[1]
foreach( iIndex, lstCapsNum
if( aPinInfo->tableGndPins[iIndex ] then
aPinInfo_Gnd = nth(1, nth(0, aPinInfo->tableGndPins[iIndex]) )
;垂直或水平
fAngle_target = nil
; println(aPinInfo_Pwr)
if(abs(nth(5,aPinInfo_Pwr) - nth(5,aPinInfo_Gnd)) <= 0.1 || abs(nth(6,aPinInfo_Pwr) - nth(6,aPinInfo_Gnd)) <= 0.1 then
fPointCap_x = 0.5 * (nth(5,aPinInfo_Pwr) + nth(5,aPinInfo_Gnd))
fPointCap_y = 0.5 * (nth(6,aPinInfo_Pwr) + nth(6,aPinInfo_Gnd))
if( abs(nth(6, aPinInfo_Pwr) - nth(6, aPinInfo_Gnd)) <= 0.1 then
;Pwr管脚在左,Gnd管脚在右
if( nth(5, aPinInfo_Pwr ) < nth(5, aPinInfo_Gnd ) then
;printf("shui ping 1")
;如果BGA上的电源地管脚是水平,则先滤波电容器件管脚按照90.0或270.0度放置;
fAngle_target = 0.0
else
;Pwr管脚在右,Gnd管脚在左
;printf("shui ping 2")
fAngle_target = 180.0
if( abs(nth(5, aPinInfo_Pwr) - nth(5, aPinInfo_Gnd)) <= 0.1 then
;Pwr管脚在下,Gnd管脚在上
if( nth(6, aPinInfo_Pwr ) < nth(6, aPinInfo_Gnd) then
; println("ChuiChi 1")
fAngle_target = 90.0
else
;Pwr管脚在上,Gnd管脚在下
; println("ChuiChi 2")
fAngle_target = 270.0
)
)
fAngle_ref = 0.0
fPoint(relx = nil
fPoint_refy = nil
bMirror_ref = nil
strRef_cap = nil
;逐个识别待移滤波电容
println("strRef_cap=")
foreach( strRef_cap, tableCapsToPlace
aSymbol_cap = nil
fAngle_ref = 0.0
fPoint(relx = nil
fPoint_refy = nil
bMirror_ref = nil
fAngle_cap = nil
lstSymbolCaps = nil
println(strRef_cap)
println(bFlag_Placed)
if( nil == bFlag_Placed && nil == member(strRef_cap, lstPlacedRefs) then
axClearSelSet()
axSetFindFilter(?enabled list("noall" "SYMBOLS") ?onButtons list("symbols"))
lstSymbolCaps = axGetSelSet( axSingleSelectName( "SYMBOL", list( strRef_cap)))
axClearSelSet()
println("lstSymbolCaps.length=")
println(length( lstSymbolCaps))
if( lstSymbolCaps then
aSymbol_cap = car( lstSymbolCaps)
fPoint(relx = fPointCap_x - nth(0, aSymbol_cap->xy)
fPoint_refy = fPointCap_y - nth(1, aSymbol_cap->xy)
fAngle_cap = SPBXA_Pclub_GetThePlacedCapAngle( aSymbol_cap, strNet_Pwr, strNet_Gnd )
println("fAngle_cap=")
println(fAngle_cap)
fAngle.Rel = fAngle_target - fAngle_cap
;如BGA和电容在同一面,则滤波电容mirrorl
if( bMirrored_Bga == aSymbol_cap->isMirrored then
bMirror_ref = t
if( abs(fAngle_cap) < 0.1 || abs(fAngle_cap-180.0) < 0.1 then
fAngle_ref = fAngle.Rel + 180.0
)
)
;
if( bMirror_ref then
axTransformObject( aSymbol_cap, ?mirror bMirror_ref )
);)
;axTransformObject( aSymbol_cap, ?move fPoint_relx:fPoint_rely, ?angle fAngle_ref )
println("axTransformObject=")
println(aSymbol_cap)
axTransformObject( aSymbol_cap, ?mirror bMirror_ref, ?move fPoint_relx:fPoint_rely, ?angle fAngle_ref )
axIDRefreshld(aSymbol_cap)
foreach( aPin, aSymbol_cap->pins
axIDRefreshld( aPin)
)
;记录放置的滤波电容if( nil $= =$ member(strRef_cap, lstPlacedRefs) thenlstPlacedRefs $\equiv$ append1( lstPlacedRefs, strRef_cap));记录放置了器件的管脚号if( nil $= =$ member(nth(1,aPinInfo_Pwr), lstPlacedPins) thenlstPlacedPins $\equiv$ append1( lstPlacedPins, nth(1,aPinInfo_Pwr)))if( nil $= =$ member(nth(1,aPinInfo_Gnd), lstPlacedPins) thenlstPlacedPins $\equiv$ append1( lstPlacedPins, nth(1,aPinInfo_Gnd)));bFlag Placed $\equiv$ t);if( lstSymbolCaps thenaxlClearSelSet());if( nil $= =$ bFlag_PLaced &&nil $= =$ member(strRef_cap, lstPlacedRefs) then);foreach( strRef_cap, tableCapsToPlace);if(abs( nth(5,aPinInfo_Pwr)-nth(5,aPinInfo_Gnd)) $\ll = 0.1$ abs( nth(6,aPinInfo_Pwr)- nth(6,aPinInfo_Gnd))<=0.1then);if( nil $= =$ member(nth(1,aPinInfo_Gnd), lstPlacedPins) then);if( aPinInfo->tableGndPins[Index] then);foreach( aPinInfo_Gnd, aPinInfo->tableGndPins[1]);;if( nil $= =$ member( strPinNumber, lstPlacedPins) then);foreach( strPinNumber, tablePwr2Gnd)
;获取某个BGA中的指定电源及地网络的管脚及坐标,并进行分析,2024.12.10,原先的,暂时屏蔽,不用(defun SPBXA_Pclub_ClaseCapsForPwrGnd_1(aSymbol_BGA,strNet_Pwr,strNet_Gnd,fPinDist_BGA, tableCapsToPlace)prog(strRef_BGA,lstPwrPins,lstGndPins,tablePwr2Gnd,aPin_Pwr,aPin_Gnd,strPinNumber_Pwr,strPinNumber_Gnd,aPinInfo,aPinInfo_Gnd,aPinInfo_Pwr,fDistTemp,fPointCap_x,fPointCap_y,bMirrred_Bga,bMirrred_Cap,bMirrred_target,lstPlacedPins,lstPlacedRefs,lstVis,aPin,lstObjs,aObj,strRef,bFlag_PLaced,lstCapsNum,fAngle_target,fAngleMirror,fAngle reli,fPoint_relx,fPoint_rely,bMirror_reli,strRef_cap,aSymbol_cap,fAngle_cap,lstSymbolCaps)strRef_BGA $\equiv$ aSymbol_BGA->refdeslstPwrPins $\equiv$ nillstGndPins $\equiv$ nilforeach( aPin, aSymbol_BGA->pinsif( aPin->net then;提取器件上的电源管脚列表if( aPin->net->name $= =$ strNet_Pwr thenlstPwrPins $\equiv$ append1(lstPwrPins, list( strRef_BGA, aPin->number, strNet_Pwr, fPinDist_BGA, aPin->xy, nth(0, aPin->xy),nth(1, aPin->xy)))
;提取器件上的地管脚列表
if( aPin->net->name == strNet_Gnd then lstGndPins = append1( lstGndPins, list( strRef_BGA, aPin->number, strNet_Gnd, fPinDist_BGA, aPin->xy, nth(0, aPin->xy), nth(1, aPin->xy))))
)
);foreach(aPin,aSymbol_BGA->pins
tablePwr2Gnd = makeTable("tablePwr2Gnd", nil)
aPin_Pwr = nil
aPin_Gnd = nil
strPinNumber_Pwr = nil
strPinNumber_Gnd = nil
aPinInfo $=$ nil
aPinInfo_Gnd = nil
aPinInfo_Pwr = nil
逐个提取器件上的电源管脚
foreach( aPin_Pwr, lstPwrPins
strPinNumber_Pwr = nth(1, aPin_Pwr)
··
aPinInfo = make_PwrPinInfo()
aPinInfo->strRef = nth(0, aPin_Pwr)
aPinInfo->strNumber = nth(1, aPin_Pwr)
aPinInfo->aPin = aPin_Pwr
aPinInfo->tableGndPins = makeTable("tableGndPins", nil)
……
逐个提取器件上的地管脚,并按1倍间距,sqrt(2)倍间距,2倍间距和sqrt(8)倍间距记录
foreach( aPin_Gnd, lstGndPins
strPinNumber_Gnd = nth(1,aPin_Gnd)
;printf(aPin_Gnd)
fDistTemp = axlDistance(nth(4, aPin_Pwr), nth(4, aPin_Gnd))
# 一倍间距
if( abs(fDistTemp - fPinDist_BGA) <= 0.1 then
aPinInfo->tableGnd_pins[1] = append1(aPinInfo->tableGnd_pins[1], aPin_Gnd)
)
1.414倍间距
if( abs(fDistTemp - sqrt(2)*fPinDist_BGA) <= 0.1 then
aPinInfo->tableGndPins[2] = append1(aPinInfo->tableGndPins[2], aPin_Gnd)
2倍间距
if( abs(fDistTemp - 2*fPinDist_BGA) <= 0.1 then
aPinInfo->tableGndPins[3] = append1(aPinInfo->tableGndPins[3], aPin_Gnd)
sqrt(5)倍间距
if( abs(fDistTemp - sqrt(5)*fPinDist_BGA) <= 0.1 then aPinInfo->tableGndPins[4] = append1(aPinInfo->tableGndPins[4], aPin_Gnd)
;水平pwr->Gnd
if(abs(nth(1, nth(4, aPin_Pwr)) - nth(1, nth(4, aPin_Gnd))) <= 0.1 then
fDist_x = nth(0, nth(4, aPin_Gnd)) - nth(0, nth(4, a极_Pwr))
;水平朝右pwr->Gnd
if(fDist_x > 0.1 && fDist_x < 1.95*fPinDist_BGA then
aPinInfo->tableGndPins[5] = append1(aPinInfo->tableGndPins[5], aPin_Gnd)
);水平朝左pwr->Gnd
if(fDist_x < -0.1 && fDist_x > -1.95*fPinDist_BGA then
aPinInfo->tableGndPins[6] = append1(aPinInfo->tableGndPins[6], aPin_Gnd)
);垂直pwr->Gnd
if(abs(nth(0, nth(4, aPin_Pwr)) - nth(0, nth(4, aPin_Gnd))) <= 0.1 then
fDist_y = nth(1, nth(4, aPin_Gnd)) - nth(1, nth(4, aPin_Pwr))
;垂直朝上pwr->Gnd
if(fDist_y > 0.1 && fDist_y < 1.95*fPinDist_BGA then
aPinInfo->tableGndPins[7] = append1(aPinInfo->tableGndPins[7], aPin_Gnd)
);处置朝下pwr->Gnd
if(fDist_y < -0.1 && fDist_y > -1.95*fPinDist_BGA then
aPinInfo->tableGndPins[8] = append1(aPinInfo->tableGndPins[8], aPin_Gnd)
);
);foreach( aGndPin, lstGndPins
tablePwr2Gnd(strPinNumber_P极) = aPinInfo
);foreach( aPwrPin, lstPwrPins
先遍历放置1倍间距的中间情况,在遍历放置1倍间距两侧的情况
fPointCap_x = nil
fPointCap_y = nil
bMirrored_Bga = nil
bMirrored_Bga = aSymbol_BGA->isMirrored
bMirrored_Cap = nil
bMirrored_target $=$ nil
中
lstPlacedPins = nil;记录BGA管脚处已经放置了器件的的管脚号
lstPlacedRefs = nil;;记录重新放置的滤波电容位号
获取BGA背面已经放置了器件的管脚号
仅显示背面管脚,过孔不显示
lstVis $=$ axlVisibleGet()
axlVisibleDesign(nil)
if( bMirrored_Bga then axlVisibleLayer("PIN/TOP", t) axlVisibleLayer("Package Geometry/TOP", t) else axlVisibleLayer("PIN/BOTTM", t) axlVisibleLayer("Package Geometry/BOTTM", t) ) axlVisibleUpdate(t)
;axlClearSelSet() axlSetFindFilter(?enabled list("noall" "SYMBOLS") ?onButtons list("symbols"))
foreach( aPin, aSymbol_BGA->pins axlClearSelSet() lstObjs = axlGetSelSet( axlSingleSelectPoint( aPin->xy)) if( lstObjs then lstPlacedPins = append1( lstPlacedPins, aPin->number) foreach( aObj, lstObjs strRef = aObj->refdes if( strRef then strRef = upperCase(strRef) if( tableCapsToPlace[strRef] && nil == member(strRef, lstPlacedRefs) then lstPlacedRefs = append1( lstPlacedRefs, strRef) ) ) axlClearSelSet() ;:foreach( aPin, aSymbol_BGA->pins axlClearSelSet()
axlVisibleDesign(nil)
axlVisibleSet( lstVis)
axlVisibleUpdate(t)
::逐个电源管脚判断
bFlag_Placed = nil
fAngle_target = nil
foreach( strPinNumber_Pwr, tablePwr2Gnd
if( nil == member( strPinNumber_Pwr, lstPlacedPins) then
; println(strcat("strPinNumber_Pwr, tablePwr2Gnd Begin = ", strPinNumber_Pwr))
aPinInfo = tablePwr2Gnd[strPinNumber_Pwr]
;("D30" "M3" "VCC1.8V" 31.49606 (5189.68 4182.84) 5189.68 4182.84)
aPinInfo_Pwr = aPinInfo->aPin
先判断最近的管脚上的电容
bFlag_Placed = nil; 表示当前电源管脚在本次放置过程中成功放置滤波电容
lstCapsNum = list(1, 2, 3, 4)
foreach(aPinInfo_Gnd, aPinInfo->tableGndPins[1])
...电源管脚未放置器件,且地管脚处也未放置
if(nil == bFlag_Placed && nil == member(nth(aPinInfo_Gnd), lstPlaced))
;("D30" "J12" "GNDD" 31.49606 (5473.15 4277.33) 5473.15 4277.33)
;垂直或水平
fAngle_target = nil
if( abs(nth(5, aPinInfo_Pwr) - nth(5, aPinInfo_Gnd)) <= 0.1 || abs(nth(6, aPinInfo_Pwr) - nth(6, aPinInfo_Gnd)) <= 0.1 then
fPointCap_x = 0.5 * (nth(5, aPinInfo_Pwr) + nth(5, aPinInfo_Gnd))
fPointCap_y = 0.5 * (nth(6, aPinInfo_Pwr) + nth(6, aPinInfo_Gnd))
水平
if(abs(nth(6,aPinInfo_Pwr)-nth(6,aPinInfo_Gnd))<=0.1 then
Pwr管脚在左,Gnd管脚在右
if(nth(5, aPinInfo_Pwr) < nth(5, aPinInfo_Gnd) then; println("shui ping 1")
如果BGA上的电源地管脚是水平,则先滤波电容器件管脚按照90.0或270.0度放置;
fAngle_target = 0.0 else
;Pwr管脚在右,Gnd管脚在左
; println("shui ping 2")
fAngle_target = 180.0
)
垂直
if( abs(nth(5, aPinInfo_Pwr) - nth(5, aPinInfo_Gnd)) <= 0.1 then
;Pwr管脚在下,Gnd管脚在上
if(nth(6, aPinInfo_Pwr) < nth(6, aPinInfo_Gnd) then
; println("ChuiChi 1")
fAngle_target = 90.0
else
;Pwr管脚在上,Gnd管脚在下
; println("ChuiChi 2")
fAngle_target = 270.0
)
)
fAngle.rel = 0.0
fPoint_relx = nil
fPoint_rely = nil
bMirror_ref = nil
strRef_cap = nil
逐个识别待移滤波电容
foreach( strRef_cap, tableCapsToPlace
aSymbol_cap = nil
fAngle.Rel = 0.0
fPoint_relx $=$ nil
fPoint_rely $=$ nil
bMirror_rel = nil
fAngle_cap = nil
lstSymbolCaps $=$ nil
if( nil $= =$ bFlag_Placed &&nil $= =$ member(strRef_cap, lstPlacedRefs) then axClearSelSet() axlSetFindFilter(?enabled list("noall" "SYMBOLS") ?onButtons list("symbols")) lstSymbolCaps $=$ axlGetSelSet( axlSingleSelectName("SYMBOL", list( strRef_cap ))) axlClearSelSet() if( lstSymbolCaps then aSymbol_cap $=$ car(lstSymbolCaps) fPoint(rel $= \mathrm{f}$ PointCap_x - nth(0, aSymbol_cap->xy) fPoint relying $=$ fPointCap_y - nth(1, aSymbol_cap->xy) fAngle_cap $=$ SPBXA_Pcub_GetThePlacedCapAngle( aSymbol_cap, strNet_PWR, strNet_Gnd ) fAngle.Rel $=$ fAngle_target - fAngle_cap
;如BGA和电容在同一面,则滤波电容mirrorl if( bMirrroRed_Bga $= =$ aSymbol_cap->isMirrrored then bMirror.rel $= t$ if(abs(fAngle_cap) $< 0.1$ || abs(fAngle_cap-180.0) $< 0.1$ then fAngle rel $=$ fAngle rel + 180.0 )
;if( bMirror_rel then axlTransformObject( aSymbol_cap, ?mirror bMirror_rel ) )
;axlTransformObject( aSymbol_cap, ?move fPoint_relx:fPoint_rely , ?angle fAngle_rel ) axlTransformObject( aSymbol_cap, ?mirror bMirror_rel, ?move fPoint_relx:fPoint_rely , ?angle fAngle_rel ) axlDBRefreshld(aSymbol_cap) foreach( aPin, aSymbol_cap->pins axlDBRefreshld( aPin) )
;记录放置的滤波电容 if( nil $= =$ member(strRef_cap, lstPlacedRefs) then lstPlacedRefs $=$ append1( lstPlacedRefs, strRef_cap) ) ;记录放置了器件的管脚号 if( nil $= =$ member(nth(1, aPinInfo_Pwr), lstPlacedPins) then lstPlacedPins $=$ append1( lstPlacedPins, nth(1, aPinInfo_Pwr)) ) if( nil $= =$ member(nth(1, aPinInfo_Gnd), lstPlacedPins) then lstPlacedPins $=$ append1( lstPlacedPins, nth(1, aPinInfo_Gnd)) ) ....... bFlag_PLaced $= t$ ) ;if( lstSymbolCaps then axlClearSelSet() ) ;if( nil $= =$ bFlag_PLaced &&nil $= =$ member(strRef_cap, lstPlacedRefs) then ) ;foreach( strRef_cap, tableCapsToPlace
);if(abs( nth(5,aPinInfo_Pwr)- nth(5,aPinInfo_Gnd)) <= 0.1 || abs( nth(6,aPinInfo_Pwr)- nth(6,aPinInfo_Gnd) 0.1 then ;;if( nil $= =$ member(nth(1,aPinInfo_Gnd), lstPlacedPins) then
);foreach( aPinInfo_Gnd, aPinInfo->tableGndPins[1] );if( nil $= =$ member(strPinNumber, lstPlacedPins) then );foreach( strPinNumber, tablePwr2Gnd )
;根据已放置器件的电源网络和地网络分别对应的管脚方位来计算其角度,该角度不一定是器件的放置角度 (defun SPBXA_Pcub_GetThePlacedCapAngle(aSymbol, strNet_Pwr, strNet_Gnd) prog( fAngle,aPin_1,aPin_2, aPin, fAngle)
fAngle $=$ nil
aPin_1 $=$ nil
aPin_2 $=$ nil
foreach( aPin, aSymbol->pins if( strNet_Pwr $= =$ aPin->net->name then aPin_1 $=$ aPin
) if( strNet_Gnd $= =$ aPin->net->name then aPin_2 $=$ aPin
)
if( aPin_1 && aPin_2 then
;ifAngle: aPin_1 指向 aPin_2的角度
;水平 if( abs( nth(1,aPin_1->xy)-nth(1,aPin_2->xy))<=0.1then if( nth(0,aPin_1->xy)<nth(0,aPin_2->xy)then fAngle $= 0.0$ else fAngle $= 180.0$ (20
)
;垂直 if( abs( nth(0,aPin_1->xy)-nth(0,aPin_2->xy))<=0.1then if( nth(1,aPin_1->xy)<nth(1,aPin_2->xy)then fAngle $= 90.0$ else fAngle $= 270.0$ (20
)
)
return( fAngle)
建立菜单文件
defun SPBXA_Pclub_create_form_file (form_file)
prog (my_form_file)
my_form_file = outfile(form_file "w")
if (my_form_file != nil then
fprintf(my_form_file "FILE_TYPE=FORM_defN VERSION=2\n")
fprintf(my_form_file "FORM\n")
fprintf(my_form_file "FIXED\n")
fprintf(my_form_file "PORT 50 11\n")
fprintf(my_form_file "HEADER
"BGA\261\263\303\3460402\302\313\262\250\347\310\335\262\274\276\326"\n");BGA背面滤波电容布局
fprintf(my_form_file "\n")
fprintf(my_form_file "POPUP <GndPop> \\"\"\"\"".n")
fprintf(my_form_file "TILE\n")
# ;1,地网络
fprintf(my_form_file "TEXT \\"1,\\265\\330\\315\\370\\302\\347:\\\"n")
fprintf(my_form_file "TLOC 3 1\n")
fprintf(my_form_file "ENDTEXT\n")
fprintf(my_form_file "\n")
fprintf(my_form_file "FIELD Text_GndNets\n")
fprintf(my_form_file "FLOC 13 1\n")
fprintf(my_form_file "STRFILLIN 20 70\n")
fprintf(my_form_file "OPTIONS prettyprint\n")
fprintf(my_form_file "POP\\"GndPOP\"n")
fprintf(my_form_file "ENDFIELD\n")
fprintf(my_form_file "\n")
# ;2, 滤波电容
fprintf(my_form_file "TEXT \\"2, 0402\302\313\262\250\265\347\310\335:\"n")
fprintf(my_form_file "TLOC 3 4\n")
fprintf(my_form_file "ENDTEXT\n")
fprintf(my_form_file "\n")
# ;3, BGA上的1个电源管脚
fprintf(my_form_file "TEXT "3, BGA\311\317\265\3041\270\366\265\347\324\264\271\334\275\305:\\"n")
fprintf(my_form_file "TLOC 3 7\n")
fprintf(my_form_file "ENDTEXT\n")
fprintf(my_form_file "\n")
# 滤波电容
fprintf(my_form_file "FIELD Btn_SelCaps\n")
fprintf(my_form_file "FLOC 28 4\n")
fprintf(my_form_file "MENUBFUNCTION \\"\\302\\313\\262\\250\\265\\347\\310\\335\" 10 3\n")
fprintf(my_form_file "ENDFIELD\n")
# 电源管脚
fprintf(my_form_file "FIELD Btn_SelBga\n"); 电源管脚
fprintf(my_form_file "FLOC 28 7\n")
fprintf(my_form_file "MENUBFUNCTION \\"265\\347\\324\\264\\271\\334\\275\\305\" 10 3\n")
fprintf(my_form_file "ENDFIELD\n")
# ,关闭界面
fprintf(my_form_file "FIELD Btn_Clear\n")
fprintf(my_form_file "FLOC 28 10\n")
fprintf(my_form_file "MENUBFUNCTION \\"\\271\\330\\261\\325\\275\\347\\303\\346\" 10 3\n")
fprintf(my_form_file "ENDFIELD\n")
;提示:1,滤波电容:封装名中含有"0402C"且2个管脚的器件;2,BGA器件:封装名中含有"BGA"、"-xRxx-"且大于2个管脚的器件.
fprintf(my_form_file "TEXT
\"314\\341\\312\\276:\\r1,\\302\\313\\262\\250\\265\\347\\310\\335:\\267\\342\\327\\260\\303\\373\\326\\320\\272\\254\\323\\320 '0402C'
307\3222\270\366\271\334\275\305\265\304\306\367\274\376;
\r2,BGA\306\367\274\376:\267\342\327\260\303\\373\326\320\272\254\323\320'BGA",-xRxx-"
\307\322\264\363\323\3322\270\366\271\334\275\305\265\304\306\367\274\376.\{"n"
fprintf(my_form_file "TLOC 3 14\n")
fprintf(my_form_file "FSIZE 46 6\n")
fprintf(my_form_file "ENDTEXT\n")
fprintf(my_form_file "\n")
fprintf(my_form_file "ENDFILE\n")
fprintf(my_form_file "ENDFORM\n")
close(my_form_file)
else
printf("ERROR,can't create form file!")
return(nil)
) 帮完翻译下这段skill代码要求输出一个翻译后的text文本内容给我
最新发布