增量式編碼器是直接利用光電轉(zhuǎn)換原理輸出三組方波脈沖A、B和Z相;A、B兩組脈沖相位差90o,從而可方便地判斷出旋轉(zhuǎn)方向,而Z相為每轉(zhuǎn)一個(gè)脈沖,用于基準(zhǔn)點(diǎn)定位。它的優(yōu)點(diǎn)是原理構(gòu)造簡(jiǎn)單,機(jī)械平均壽命可在幾萬(wàn)小時(shí)以上,抗干擾能力強(qiáng),可靠性高,適合于長(zhǎng)距離傳輸。其缺點(diǎn)是無(wú)法輸出軸轉(zhuǎn)動(dòng)的絕對(duì)位置信息。增量式編碼器是一種測(cè)量設(shè)備轉(zhuǎn)動(dòng)的傳感器,在電機(jī)驅(qū)動(dòng)控制中得到廣泛應(yīng)用。
關(guān)鍵詞:SPMC75? 增量編碼器
1?引言
? 本文主要是講解SPMC75F2413A的PDC定時(shí)器模塊的增量碼盤接口功能,用這個(gè)接口可以測(cè)量增量碼盤轉(zhuǎn)軸的角位移,同時(shí)還可根據(jù)單位時(shí)間的角位移計(jì)算出增量碼盤轉(zhuǎn)軸的角速度,進(jìn)而得到轉(zhuǎn)軸的轉(zhuǎn)速。本例使用的增量碼盤接口模式1,這是四倍頻接口模式,適合圖2-1中所示類型的波形。
2?系統(tǒng)框圖
系統(tǒng)結(jié)構(gòu)如圖2-1所示,主要由信源模擬發(fā)生模塊和速度測(cè)量模塊組成。兩個(gè)模塊均由SPMC75F2413A構(gòu)成。信源模擬發(fā)生模塊產(chǎn)生如中A、B所示的信號(hào)波形,A、B信號(hào)相差90度,圖中只示出了B超前A的情況,信號(hào)的頻率由電位器調(diào)整。
圖 2-1 系統(tǒng)結(jié)構(gòu)圖
?
3?增量編碼盤接口原理
3.1 設(shè)計(jì)原理
增量編碼盤是一種測(cè)量角位移增量的傳感器,根據(jù)其工作方式的不同可分為光電式、磁電式和純機(jī)械式等幾種,光電式和磁電式是現(xiàn)今最常用的方式。其中光電式用得最多是光電透射式,而磁電式主要是利用類式磁帶的原理在一個(gè)圓周上均布了N、S的磁信號(hào),利用磁敏組件檢出信號(hào)。
SPMC75F2413A的增量編碼盤接口模式1工作原理如圖3-1所示:外部輸入信號(hào)TCLKA、TCLKB頻率相同但相位互差90度,其頻率與其轉(zhuǎn)速成正比,比例為增量編碼的細(xì)分?jǐn)?shù)(每轉(zhuǎn)1轉(zhuǎn)所輸出的脈沖個(gè)數(shù))。而兩路信號(hào)的相位關(guān)系則代表了轉(zhuǎn)向信息。當(dāng)TCLKA超前TCLKB時(shí)為正轉(zhuǎn),反之當(dāng)TCLKA滯后TCLKB時(shí)為反轉(zhuǎn)。同時(shí),由于這兩路信號(hào)是互差90度的,為了提高測(cè)量的精度,計(jì)數(shù)器是在兩路信號(hào)的跳變沿都計(jì)數(shù),而計(jì)數(shù)的方向則由兩路信號(hào)的相位關(guān)系確定。TCLKA超前時(shí)計(jì)數(shù)器增計(jì)數(shù),TCLKA滯后時(shí)計(jì)數(shù)器減計(jì)數(shù)。如此,用戶便可以得到從計(jì)數(shù)器開始計(jì)數(shù)后增量編碼轉(zhuǎn)軸的角位移量(如當(dāng)增量編碼盤的細(xì)分?jǐn)?shù)為N時(shí),增量編碼盤的每一個(gè)脈沖代表的角位移為由于為四倍頻計(jì)數(shù),因此,當(dāng)計(jì)數(shù)器的值為K時(shí),所代表的角位移為)。同時(shí),用戶可以通過測(cè)量單位時(shí)間內(nèi)的角位移而得到當(dāng)前轉(zhuǎn)軸的轉(zhuǎn)速。其轉(zhuǎn)速為:
??????? ------(式3-1)
式中:為轉(zhuǎn)軸角速度;
為測(cè)量時(shí)間;
為內(nèi)的計(jì)數(shù)器增量;
N為碼盤的細(xì)分?jǐn)?shù);
圖2-1 相位計(jì)數(shù)模式1
?
4?硬件說明
4.1 信號(hào)模擬發(fā)生電路
這部分電路如圖4-1所示,使用SPMC75F2413A的MCP3實(shí)現(xiàn)雙線增量碼盤輸出信號(hào)的模擬,并根據(jù)AD采集的數(shù)據(jù)設(shè)置信號(hào)的頻率和方向,以滿足系統(tǒng)測(cè)試的需要。
圖4-1信號(hào)模擬發(fā)生電路
4.2 測(cè)量接口電路
電路如圖4-2所示,這部分是本例的主體部分,它主要是利用SPMC75F2413A的PDC定時(shí)計(jì)數(shù)器的相位計(jì)數(shù)(碼盤接口)模式1完成位置信號(hào)的采集、速度的測(cè)量。為了提高測(cè)量精度,使用了四倍頻技術(shù)。
圖4-2測(cè)量接口電路
?
5?軟件說明
5.1 軟件說明
系統(tǒng)的軟件部分主要是系統(tǒng)所用到的硬件的初始化,并在硬件中斷時(shí)進(jìn)行相應(yīng)的的處理。同時(shí)利用DMC的通信軟體庫(kù)完成與PC的通信,以便對(duì)系統(tǒng)狀態(tài)和結(jié)果進(jìn)行監(jiān)控。
5.2 軟件流程
5.2.1?主程序流程
主程序在完成系統(tǒng)初始化以后,就不斷檢測(cè)有沒有來自PC的控制信息,如果有便完成相應(yīng)的控制功能,沒有就繼續(xù)檢測(cè)。同時(shí)將當(dāng)前系統(tǒng)測(cè)得數(shù)據(jù)送入DMC接口區(qū),以便系統(tǒng)狀態(tài)的監(jiān)示。
圖5-1 主程序流程圖
5.2.2?中斷流程
中斷服務(wù)主要有三個(gè),一個(gè)是系統(tǒng)通信中斷服務(wù),主要是在DMC庫(kù)中完成;一個(gè)是PDC定時(shí)器的溢出中斷服務(wù),在這里主要完成位置計(jì)數(shù)溢出的處理,以保證位置單元的正確性;最后一個(gè)是定時(shí)器的周期中斷服務(wù),這里主要完成當(dāng)前位置信息的采集,同時(shí)根據(jù)位置增量計(jì)算當(dāng)前的轉(zhuǎn)速。
5.3 程序代碼
使用SPMC75F2413A的PDC0的相位計(jì)數(shù)模式(即兩線增量碼盤接口)實(shí)現(xiàn)使用兩線增量碼盤測(cè)量電機(jī)轉(zhuǎn)速。
#include "Spmc75_regs.h" #include "mcMACRO.h" #include "Spmc75_dmc_uart_ext.h" #define Samp_Time 8 // 采樣定時(shí)器 , 單位 ms void Daly_Time(int Time); void PDC0_Init(void); void Time2_Init(void); static int Moto_Speed = 0; // 電機(jī)轉(zhuǎn)速 static int Over_flag = 0; // 位置計(jì)數(shù)器溢出標(biāo)志 static int Encoder_Data = 256*4; // 編碼盤的細(xì)分常數(shù) // 電機(jī)絕對(duì)位置 ( 長(zhǎng)整數(shù) , 為了計(jì)算方便 , 高低分開定義 ) static unsigned int Position_Count[2] = {0,0}; static unsigned int Old_Position_Count = 0; // 上一次電機(jī)位置 ( 低 16 位 ) //===================================================================== // ----Function: main(void); // -Description: 主函數(shù) // -----Returns: None // -------Notes: //===================================================================== main() { PDC0_Init(); Time2_Init(); MC75_DMC_UART_Setup(9600); INT_IRQ(); while(1) { MC75_DMC_UART_Service(); if(SPMC_DMC_Load_SpdCmd(1) > 0) Encoder_Data = SPMC_DMC_Load_SpdCmd(1)*4; SPMC_DMC_Save_SpdNow(1,Moto_Speed); } } //===================================================================== // ----Function: void PDC0_Init(void); // -Description: 定時(shí)器初始化 // --Parameters: None // -----Returns: None // -------Notes: //===================================================================== void PDC0_Init(void) { P_IOA_Dir->W &= 0xe7ff; // 設(shè)置用到的 IO 口 P_IOA_Attrib->W &= 0xe7ff; P_IOA_Buffer->W |= 0x1800; P_IOA_SPE->W |= 0x1800; P_TMR0_Ctrl->B.SPCK = CB_TMR0_SPCK_FCKdiv1; // 設(shè)置采樣時(shí)鐘為主系統(tǒng)時(shí)鐘 // 設(shè)置定時(shí)計(jì)數(shù)器模式為四倍頻增量碼盤接口 P_TMR0_Ctrl->B.MODE = CB_TMR0_MODE_Mode1; P_TMR0_Ctrl->B.CCLS = CB_TMR0_CCLS_Disabled; // 禁止計(jì)數(shù)器清除 P_TMR0_Ctrl->B.CKEGS = CB_TMR0_CKEGS_Rising; // 設(shè)定計(jì)數(shù)邊沿為上升沿 P_TMR0_Ctrl->B.TMRPS = CB_TMR0_TMRPS_FCKdiv1; // 設(shè)置時(shí)鐘 , 這是必需的 // 使能計(jì)數(shù)器的上溢下溢中斷 P_TMR0_INT->W |= CW_TMR0_TCUIE_Enable + CW_TMR0_TCVIE_Enable; P_TMR_Start->B.TMR0ST = 1; // 啟動(dòng)定時(shí)器 } //===================================================================== // ----Function: void Time2_Init(void); // -Description: TMR2_module initialize function // --Parameters: None // -----Returns: None // -------Notes: //===================================================================== void Time2_Init(void) { P_TMR2_Ctrl->B.MODE = CB_TMR2_MODE_Normal; // 工作模式初始化為連續(xù)增計(jì)數(shù) P_TMR2_Ctrl->B.CCLS = CB_TMR2_CCLS_TPR; // 計(jì)數(shù)器清零源為周期匹配信號(hào) P_TMR2_Ctrl->B.CKEGS = CB_TMR2_CKEGS_Rising; // 計(jì)數(shù)邊沿為上升沿 P_TMR2_Ctrl->B.TMRPS = CB_TMR2_TMRPS_FCKdiv4;// 計(jì)數(shù)時(shí)鐘為主時(shí)鐘的 1/4 P_TMR2_TPR->W = 6000*Samp_Time; // 定時(shí)周期設(shè)為 48000---8ms P_TMR2_INT->B.TPRIE = CB_TMR2_TPRIE_Enable; // 使能定時(shí)器的周期中斷 P_TMR_Start->B.TMR2ST = CB_TMR_TMR2ST_Start; // 啟動(dòng)定時(shí)器 } //===================================================================== // Description: IRQ1 interrupt source is XXX,used to XXX // Notes: //===================================================================== void IRQ1(void) __attribute__ ((ISR)); void IRQ1(void) { if(P_TMR0_Status->B.TCUIF) { P_TMR0_Status->B.TCUIF = 1; //Clear TCUIF flag (int)Position_Count[1] --; // 位置計(jì)數(shù)下溢出 Over_flag = 1; } if(P_TMR0_Status->B.TCVIF) { P_TMR0_Status->B.TCVIF = 1; //Clear TCVIF flag (int)Position_Count[1] ++; // 位置計(jì)數(shù)上溢出 Over_flag = 1; } } //===================================================================== // Description: IRQ4 interrupt source is XXX,used to XXX // Notes: //===================================================================== void IRQ4(void) __attribute__ ((ISR)); void IRQ4(void) { long Temp; if(P_TMR2_Status->B.TPRIF) { P_TMR2_Status->B.TPRIF = 1; Position_Count[0] = P_TMR0_TCNT->W; if(Position_Count[0] < Old_Position_Count) // 計(jì)算位置增量 { if(Over_flag > 0) //1 正轉(zhuǎn) , 上溢 Temp = (0xffff - Old_Position_Count) + Position_Count[0] + 1; else //0 反轉(zhuǎn) , 沒有溢出 { Temp = Old_Position_Count - Position_Count[0]; Temp = -Temp; } } else { if(Over_flag > 0) // 反轉(zhuǎn) , 溢出 { Temp = (0xffff - Position_Count[0]) + Old_Position_Count + 1; Temp = - Temp; } else // 正轉(zhuǎn) , 沒有溢出 Temp = Position_Count[0] - Old_Position_Count; } Over_flag = 0; Old_Position_Count = Position_Count[0]; Moto_Speed = (int)((Temp*7500)/Encoder_Data);// 速度計(jì)算 } } //===================================================================== // Description: IRQ6 interrupt source is XXX,used to XXX // Notes: //===================================================================== void IRQ6(void) __attribute__ ((ISR)); void IRQ6(void) { if(P_UART_Status->B.RXIF && P_UART_Ctrl->B.RXIE) MC75_DMC_RcvStream(); } |
評(píng)論
查看更多