[Chia sẻ] Giải mã encoder bằng Capture trên MSP

thienminh_npn

Thành Viên PIF
Tình hình là lỡ chém gió vs thằng saiya về cái vụ mình điều khiển động cơ bằng MSPG2553 hồi thực tập kỹ thuật nên bây giờ tớ post cái code giải mã encoder bằng chức năng capture của timer trong đó. Pà con cho xin tí gạch nào:

Đầu tiên ta phải config cho 1 chân GPIO nối vô channel A để trigger capture ở cạnh lên, một chân nữa làm input nối vô channel B của cái encoder để so pha khi có ngắt capture, trong chương trình này thì pin 2.0 vào channel A, pin 2.1 vào channel B, các pin 2.6 và 1.6 được dùng để phát PWM ở mỗi nửa pha cầu H, và các chân làm UART Tx, Rx v.v... Tổ hợp bit của PxSEL và PxSEL2 tương ứng cho các chức năng vừa giới thiệu các bạn rút ra từ trong hàm luôn nhé.
Code:
void GPIO_init(void)
 
{
 
/* Port 1 Output Register */
 
P1OUT = 0;
 
/* Port 1 Port Select Register */
 
P1SEL = BIT1 + BIT2 + BIT6;
 
/* Port 1 Port Select 2 Register */
 
P1SEL2 = BIT1 + BIT2;
 
/* Port 1 Direction Register */
 
P1DIR = BIT6;
 
/* Port 1 Interrupt Edge Select Register */
 
P1IES = 0;
 
/* Port 1 Interrupt Flag Register */
 
P1IFG = 0;
 
/* Port 2 Output Register */
 
P2OUT = 0;
 
/* Port 2 Port Select Register */
 
P2SEL = BIT0 + BIT6;
 
/* Port 2 Port Select Register */
 
P2SEL &= ~(BIT7);
 
/* Port 2 Direction Register */
 
P2DIR = BIT6;
 
/* Port 2 Interrupt Edge Select Register */
 
P2IES = 0;
 
/* Port 2 Interrupt Flag Register */
 
P2IFG = 0;
 
}
Sau đó ta config cho Timer1 thực hiện chức năng capture, nguồn ngắt từ pin2.0
Code:
void Timer1_A3_init(void)
 
{
 
/*
 
* TA1CCTL0, Capture/Compare Control Register 0
 
*
 
* CM_2 -- Falling Edge
 
* CCIS_0 -- CCIxA
 
* SCS -- Sychronous Capture
 
* ~SCCI -- Latched capture signal (read)
 
* CAP -- Capture mode
 
* OUTMOD_0 -- PWM output mode: 0 - OUT bit value
 
*
 
* Note: ~SCCI indicates that SCCI has value zero
 
*/
 
TA1CCTL0 = CM_2 + CCIS_0 + SCS + CAP + OUTMOD_0;
 
/*
 
* TA1CTL, Timer_A3 Control Register
 
*
 
* TASSEL_2 -- SMCLK
 
* ID_0 -- Divider - /1
 
* MC_0 -- Stop Mode
 
*/
 
TA1CTL = TASSEL_2 + ID_0 + MC_0;
 
}
Hàm trên mới config cách hoạt động thôi chưa enable cho timer và các interrupts vì mình điều khiển bằng GUI nên khi có lệnh mới bật các module này, các bạn phải bật/tắt các bit enable của Capture/Compare và Timer Overflow theo chế độ hoạt động của mình nhé:
Code:
TA1CTL |= MC1; //let the timer counter to run in continuous mode
 
TA1R = 0; //reset the timer counter to zero value
 
TA1CCTL0 |= CCIE; //enable capture interrupt to capture speed and inc/dec position
 
TA1CTL |= TAIE; //enable timer 1 overflow interrupt to compensate for speed //value when the period between 2 edges surpasses the
 
//maximum period of the counter.
Sau đó là hàm ngắt cho Timer1 capture event, nó cập nhật cả vị trí và tốc độ:
Code:
#define DIR (P2IN & BIT1)
 
//this function is the interrupt handler of timer A 1 capture block 0
 
//@return: none
 
//@param: none
 
//*notice: this uses 2 global variables : ulcap_val(unsigned long captured value) and dir (direction), //which is used in PID function
 
void state_feedback(void)
 
{
 
ulcap_val = TA1CCR0; //load the captured value to the unsigned variable
 
dir = DIR; //consider the speed signed based on the phase difference of the encoder
 
//increment or decrement the position variable based on the direction
 
if( dir == DIR_FW )
 
ipos_encp ++;
 
else ipos_encp --;
 
//reset the timer counter
 
TA1R = 0;
 
TA1CTL |= TAIE; //enable timerA1 interrupt to make addition to ulcap_val when an overflow occurs
 
TA1CCTL0 &= ~CCIFG; //reset the capture compare flag
 
}
và thế là chúng ta có 3 biến ulcap_val là tốc độ (thời gian 1 chu kỳ xung encoder), dir là hướng (tùy bạn đặt theo cấu hình phần cứng) và position là vị trí động cơ.

Ok brick collection begins :gach
 

saiya

Thành Viên PIF
DIR_FW :gach:gach:gach phải hướng quay động cơ hok vậy? FW hướng về trước phải không anh?:2cool_after_boom:
 

saiya

Thành Viên PIF
Top