01背景與介紹
?步進(jìn)電機(jī)是一個用數(shù)字來控制運(yùn)動的數(shù)字化電機(jī),特別適用于精準(zhǔn)控制場合。今天,我們將通過步進(jìn)電機(jī)控制云臺準(zhǔn)確定位轉(zhuǎn)動的應(yīng)用,詳細(xì)講解一下對步進(jìn)電機(jī)運(yùn)動的控制。
?
首先,云臺通過一個搖桿控制器進(jìn)行控制,速度分為0~63。其中,0即為停止,63即為最快速度。該產(chǎn)品模型,如圖1所示:
?


- ?
- ?
- ?
- ?
? ?sbit Cdata = P?^?; // ->2051
sbit Cctrl = P?^?; // -INT0
sbit Crclk = P?^?;
sbit Ctclk = P?^?;
02分析與對策
?我們都知道,51單片機(jī)的客觀條件不怎么好。
?
首先是工作頻率較低。傳統(tǒng)的51單片機(jī)是12T機(jī),也就是說,執(zhí)行一條指令的速度是1/12主頻,即12M的晶振執(zhí)行指令的速度只有1M。當(dāng)然,后來出了一些變種51單片機(jī)是1T機(jī),大部分指令速度是1T的,無論這個大部分有多大概率,至少執(zhí)行速度是提高了不少。
?
這里采用的就是1T機(jī),因?yàn)檫@款產(chǎn)品實(shí)際上有兩個步進(jìn)電機(jī),如果單片機(jī)速度太慢,有很多產(chǎn)品功能就無法流暢實(shí)現(xiàn)。要充分利用JBC指令來實(shí)現(xiàn)判斷跳轉(zhuǎn),這條指令對應(yīng)的C語言語句是_testbit_(abitvar)。不能小看這一點(diǎn)點(diǎn)的節(jié)省,這對一個功能復(fù)雜、運(yùn)行速度敏感的產(chǎn)品來說非常重要!
?
其次是定時器數(shù)量少,單次計(jì)時時間短。作為一個產(chǎn)品的主控芯片,因?yàn)?1單片機(jī)是8位機(jī),定時器資源也非常緊缺,所以本產(chǎn)品利用了定時器0的模式3,將定時器0一拆為二,變成了兩個不能自動重載的8位定時器(此時原定時器1只能作為波特率發(fā)生器<這也正是我們需要的>,原定時器1的寄存器都作為定時器0的第二個定時器<新定時器1>的控制寄存器,一旦啟動,無法更改)。
?
因?yàn)檫@種模式一旦啟動,后期不能進(jìn)行修改。所以,為了極大地減少指令數(shù)量,可將這兩個定時器工作于偽重載的模式下。即當(dāng)定時器計(jì)數(shù)寄存器溢出為0后,直接將這個0作為重載數(shù)據(jù),從而避免通過命令進(jìn)行重載。對于一個反復(fù)運(yùn)行的代碼來說,精簡一條指令的收益是不容小覷的。
?
定時器初始化代碼如下:
?- ?
setBaud(BaudID); // 先初始化定時器1作為波特率發(fā)生器
?
?第三是內(nèi)存資源很有限。變種的51單片機(jī)有一個神奇的現(xiàn)象,那就是代碼存儲器容量足夠大,而RAM(即使用MOV來訪問)卻依然很少,片內(nèi)擴(kuò)展的外部存儲器(即使用MOVX來訪問)執(zhí)行時耗又比較大。所以,將好鋼用在刀刃上就變得非常重要了,甚至我們經(jīng)常還需要用代碼來換取RAM的節(jié)約使用。
?03編程魔法師觀點(diǎn)
?編程魔法師的觀點(diǎn),就是要面向?qū)ο筇幚怼?/span>也就是后面使用步進(jìn)電機(jī)時,不能夾帶控制代碼,只能設(shè)置設(shè)置參數(shù)(屬性)、調(diào)用調(diào)用動作(函數(shù))。
?
為了減少生澀的說明,這里直接用云臺自檢為例簡要說明。云臺x軸自檢過程,如圖3所示:
?

- ?
sbit Pos0x = Px^?; // x光電管信號
?
?我們先來看一下自檢的代碼:
?- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
?voidSelfChk(void)
{
? ?? ? Pscx= (Pos0x)?0:1;
? ?? ?while(fx)
? ?? ?{
? ?? ? WDI = !WDI;? ?? ?// ******** 喂狗 ********
? ?? ? if(NdCtrlx)
? ?? ???{
? ?? ?? ?? ?NdCtrlx = 0;
? ?? ?? ?if(fx)
? ?? ?? ?{
? ?? ?? ?? ?? ?? ? Pscx++;
? ?? ?? ?? ?? ?? ? switch(Pscx)
? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ? case??2: xRun321(0,CVauto,CWavoid);
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? Sx = 0;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? xRun();
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? break;
? ?? ?? ?? ?? ?? ?? ?? ?? ? case??1: Pscx = 3;
? ?? ?? ?? ?? ?? ?? ?? ?? ? case??3: Sx = 0;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? xRun321(1,CVauto,0xFFFF);
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? xRun();
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? break;
? ?? ?? ?? ?? ?? ?? ?? ?? ? case??5: CSmaxx1 = Sx;
? ?? ?? ?? ?? ?? ?? ?? ?? ? case??4: Sx = 0;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? break;
? ?? ?? ?? ?? ?? ?? ?? ?? ? case??6: CSdelta = Sx - 1;? ?? ?? ?? ? // 自檢確定光電管寬度
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? fx = 0;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? xStop();
? ?? ?? ?? ?? ???}
? ?? ?? ?}
? ?? ???}
? ?? ?}
}
從自檢代碼中,我們可以看出,對步進(jìn)電機(jī)的控制只使用了一些方法(函數(shù)/宏)。這是一種擼碼的較高境界,即代碼與日常語義貼近。
?
接下來,我們再看一下步進(jìn)電機(jī)的方法代碼:
?- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
?/*--------------------------------------------------------
??功能:x方向運(yùn)動預(yù)備
? ?? ?? ???填入目標(biāo)Sendx、速度Vobj、運(yùn)行方向mmd
??參數(shù):o1: 運(yùn)行方向
? ?? ?? ???o2: 目標(biāo)速度
? ?? ?? ???o3: 目標(biāo)行程
--------------------------------------------------------*/
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?mmCmdx =((o2)>CVmax)?CVmax:o2;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?mmSx =o3; mmcx = 1;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? }
/*--------------------------------------------------------
??功能:x方向運(yùn)動開始
? ?? ?? ???調(diào)用之前要確認(rèn)目標(biāo)Sendx、速度Vobj、運(yùn)行方向mmd
--------------------------------------------------------*/
void xRun(void)
{
? ?? ?if(TR0) return;
? ?? ?TL0? ? = CT2Vooo; // 進(jìn)入運(yùn)行的時間
? ?? ?NdCtrlx = 0;
? ?? ?TR0? ? = 1;
}
/*--------------------------------------------------------
??功能:x方向運(yùn)動停止
--------------------------------------------------------*/
很顯然,通過控制步進(jìn)電機(jī)的運(yùn)行參數(shù)設(shè)置、步進(jìn)電機(jī)的起與停,符合我們的日常控制習(xí)慣,這就是工程學(xué)與實(shí)際應(yīng)用完美統(tǒng)一的境界。
?04步進(jìn)電機(jī)運(yùn)動控制策略
?控制步進(jìn)電機(jī)運(yùn)動有兩種方式:一種是速度控制方式,另一種是終點(diǎn)控制方式。
?
速度控制方式是指在實(shí)時控制時,只有目標(biāo)速度,沒有目標(biāo)位置的控制方式。這種控制具有隨意性,它可能是從一個速度到另一個速度的變化,也可能是保持某個速度的運(yùn)動;而速度的變化可以是增速,也可以是減速;一個速度與另一個速度可以是0,也可以不是0(如圖4所示)。
?



05代 碼
?我知道很多小伙伴不喜歡啰嗦、只喜歡代碼,所以這里就不多說了,大家直接復(fù)制代碼就行了。
?
定時器0(x電機(jī))的ISR如下:
?- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
?voidTimer0(void) interrupt 1 using 1
{
? ?? ?static UINT??data Dis=0;? ?? ?? ?? ???//剩余行程
? ?? ?static bit? ?? ???D=0;? ?? ?? ?? ?? ?? ?//運(yùn)動方向
? ?? ?static UCH? ?data Vend=0;? ?? ?? ???//目標(biāo)速度
? ?? ?static UCH? ?data V=0;? ?? ?? ?? ?? ?? ?? ? //當(dāng)前速度
? ?? ?static UCH? ?data lps=0;? ?? ?? ?? ???//定時器延時倍率計(jì)數(shù)器
? ?? ?static bit? ?? ???Wavoid=0;
? ?? ?//--------------------------------------------------------------------------------
? ?? ?if(_testbit_(mmcx))? ?? ?? ?? ?// 存在立即執(zhí)行命令
? ?? ?{
? ?? ?? ???switch(mmCmdx)
? ?? ?? ???{
? ?? ?? ?? ?? ???case 0x40:??// 停止
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? if(Dis>V)Dis = V;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?Vend= 0;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? mmCmdx = 0x00;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? break;
? ?? ?? ?? ?? ???default??:? ?// 開始命令解釋: mmcx = 0 表示速度變化,其他命令必須mmcx = 1
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? if(V&&(D!=mmdx)) // 如果速度大于0反向則執(zhí)行減速到自動停止
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?if(Vend){Dis= V; Vend = 0;}
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? else
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?D = mmdx;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?Vend = mmCmdx;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?Sendx =mmSx;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?if(Sendx<(CSmaxx1))
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?Dis= (fx)?(Sendx -Sx):((D)?((Sendx>=Sx)?(Sendx-Sx)((Sendx<=Sx)?(Sx-Sendx):(CSmaxx1-Sendx+Sx)));
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?else
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?Dis= 0xFFFF;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? if(!Dis)StopRunx();
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?if(!lps) lps = CT2Vooo; //以最快速度進(jìn)入第一步
? ?? ?? ???}
? ?? ?}
? ?? ?// 運(yùn)行處理
? ?? ?if(++lps) return;? ?? ?? ?? ?? ?? ?? ?// 延長定時器定時時間,lps自增到溢出(==0)才進(jìn)行一次運(yùn)動運(yùn)動處理
? ?? ?SendMx();? ?? ?? ?? ?? ?? ? //根據(jù)當(dāng)前方向運(yùn)動一步
? ?? ?NextPx();? ?? ?? ?? ?? ?? ???//求下一個圓周坐標(biāo)Sx,以及剩余行程Dis(行程不能大于等于最大圓周坐標(biāo),自動計(jì)算近距離及方向到達(dá)目標(biāo))
? ?? ?WidAvd();? ?? ?? ?? ?? ?? ? //光電管處同步處理(自檢正方向從未遮擋到遮擋處為0,從遮擋到未遮擋處為光電管寬度,反方向倒著處理)
? ?? ?NxtxAn();? ?? ?? ?? ?? ?? ???//求下一個速度參數(shù)
}
步進(jìn)電機(jī)走一步代碼如下(此處代碼根據(jù)硬件確定,以下僅供參考):
?- ?
- ?
- ?
- ?
?? ?? ?? ?? ?? ?? ?? ?? ?? ? Cctrl = 1; Cdata =0; Cctrl = 0;
? ?? ?? ?? ?? ?? ?? ?? ?? ? Cctrl = 1; Cdata =!D; Cctrl = 0;
???????????????????????}
步進(jìn)電機(jī)走一步后坐標(biāo)與行程處理的代碼如下:
?- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
?#define NextPx(){
?? ?? ?? ?? ?? ?? ?? ?? ? if(fx)
? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? Sx++;
? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ? else
? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? if(D)
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?Sx++;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?if(Sx>=CSmaxx1)Sx = 0;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? else
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?if(Sx)Sx--; else Sx = CSmaxx1 - 1;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ? if(Dis &&(Dis<(CSmaxx1))) Dis--;
????????????????????????}
每次檢測到光電管后同步處理的代碼如下:
?- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
?#define WidAvd(){
?? ?? ?? ?? ?? ?? ?? ?? ? if(Wavoid)
? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? if(Pos0x)
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?Wavoid =0;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?if(fx)if(Pscx==5) NdCtrlx = 1;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ? else
? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? if(!Pos0x)
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?Wavoid =1;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?if(fx)
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?{
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?if((Pscx==3)||(Pscx==4))NdCtrlx = 1;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?}
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?else
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?{
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?Sx= (D)?0:CSdelta;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?}
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ? }
???????????????????????}
步進(jìn)電機(jī)走一步后速度處理的代碼如下:
?- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
? ?#define NxtxAn(){
?? ?? ?? ?? ?? ?? ?? ?? ? if(Dis)
? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? if(Dis>V)
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?if(V
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?{
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?V++;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?}
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?else
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?{
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?if(V>Vend)V--;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?}
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? else
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?V--;
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? lps = CxT2Vmin+ V;
? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ?? ?? ?? ?? ? else
? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? StopRunx();
? ?? ?? ?? ?? ?? ?? ?? ?? ? }
???????????????????????}
06相關(guān)問題與處理方法
?1、由于步進(jìn)電機(jī)是一種電轉(zhuǎn)換率很低的設(shè)備,因此,當(dāng)負(fù)載與輸出功率出現(xiàn)矛盾時,一定要保證設(shè)備不能出現(xiàn)失步,盡可能降低負(fù)載影響是重中之重。例如,減輕負(fù)載質(zhì)量、降低負(fù)載運(yùn)動阻力等,都是很重要的工作。
?
2、選擇銅耗鐵耗低的步進(jìn)電機(jī),是在體積一定的情況下提高步進(jìn)電機(jī)帶載能力的優(yōu)選方案,如果你能接受這樣做帶來的成本增加的話。
?
3、速度突變?nèi)菀讓?dǎo)致步進(jìn)電機(jī)失步,這主要是“既想步進(jìn)電機(jī)小,又想步進(jìn)電機(jī)快”導(dǎo)致的步進(jìn)電機(jī)功率跟不上速度變化。在不提高步進(jìn)電機(jī)功率的前提下,利用合適的加速曲線能一定程度上抑制失步。
?
4、光電管位置同步,是避免步進(jìn)電機(jī)控制時,因機(jī)械誤差導(dǎo)致數(shù)位累積誤差的有效辦法。由于這種誤差通常只會在整周轉(zhuǎn)動時產(chǎn)生累積,因此只要在每次經(jīng)過零位光電管時進(jìn)行一次同步即可消除。
?
5、對于計(jì)算時出現(xiàn)位置速度偏差的處理方法是,當(dāng)?shù)竭_(dá)指定目標(biāo)前速度按加減速曲線應(yīng)該變?yōu)?時,保持速度1不變,直到到達(dá)終點(diǎn)。當(dāng)?shù)竭_(dá)指定目標(biāo)時速度按加減速曲線計(jì)算無法到達(dá)0時,到達(dá)終點(diǎn)時速度直接降為0。
?
盡管這種處理看起來不太合理,但這種偏差在運(yùn)算出現(xiàn)±1誤差時進(jìn)行強(qiáng)制修正,實(shí)際造成的影響可以忽略不計(jì)。
?
6、如果出現(xiàn)步進(jìn)電機(jī)在某個速度時抖動特別厲害(電機(jī)運(yùn)行聲音明顯變大),可以通過改變負(fù)載結(jié)構(gòu)與質(zhì)量的方式修改產(chǎn)品的固有諧振頻率,以避開結(jié)構(gòu)共振點(diǎn)造成的抖動。 ?好了,以上就是今天分享的所有內(nèi)容了,如果有需要查看原圖和代碼的小伙伴,請點(diǎn)擊底部“閱讀原文”進(jìn)行下載。 ?
評論