Part Number: MSP432P401R
Tool/software: Code Composer Studio
Hi
I have two signals, A and B, coming from an encoder (to measure the velocity of motor shaft). If the direction of the motor is clockwise, the signal A leads signal B and vise versa. I am going to detect this phase delay with MSP432P401R. To do so, I am using P2.6 and P2.7 as GPIO and activated the interrupt for them and connected the channel A and channel B to them. Also, I am using Timer_A0. I have created a function innthe while loop, and in this function, first, the timer is initiated, then two flags, flagA and flagB, are reset. The captures are store into two unsigned shorts, captureA and captureB. when two interrupts, one from channel A and one from channel B occurred, In the ISR, the TA0R are stored in the captureA, and captueB.
The mentioned variables then are compared and the direction is defined. I have written the code, but there is a problem, sometimes it captureA is bigger and sometimes captureB in the same condition. Would you please help me resolve the issue? thanks!
The code is brought below:
#include "msp.h" #include "math.h" unsigned short captureA,captureB;//the timers values for signal A interrup and signal B is stored in them. short int phase_detection,CW,flagA=0,flagB=0;
int o; float motor1_velocity(void) { captureA=0; captureB=0; // //Define the direction of rotation// phase_detection=1; TIMER_A0->CTL = TIMER_A_CTL_TASSEL_2 | //Select SMCLK as clock source for timer TIMER_A_CTL_ID_3 | //ID=8 TIMER_A_CTL_CLR; // clear TA0R TIMER_A0->CTL |= TIMER_A_CTL_MC_2 ; // Start timer in continuous mode P2IE |= BIT6 + BIT7; // The interrupt is activated for P2.6/P2.7. P2IES &= ~(BIT6 + BIT7); // The interrupt is activated on high to low transition. P2IFG &= ~(BIT6 + BIT7); // P2.6/P2.7 IFG cleared while (!((flagA&1)&(flagB&1))); //wait until two captures for channels A and B occure. phase_detection=0; //Now, we change our policy to frequency measurement. flagA=0; flagB=0; P2IE &= ~(BIT6 + BIT7); // The interrupts are temporarily halted to define the lead/lag of channel A wrt channel B. if ((captureA-captureB)>0){CW=0;} //The motor is rotating CW. else {CW=1;}// The motor is rotating CCW. return 0; } void main(void) { WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer //******Pin configurations**********// NVIC_ClearPendingIRQ(PORT2_IRQn); // Clear any stale Interrupt Controller status NVIC_EnableIRQ(PORT2_IRQn); // Enable P1 interrupt in the Interrupt Controller //****************************// P1DIR |=BIT0; P2DIR |= BIT1; P2REN |= BIT6 + BIT7; //Pullp/pulldown resistor is activated. P2DIR &= ~(BIT6+ BIT7); //P2.6/7 is defined as input pin. P2OUT &= ~ (BIT6 + BIT7); //The default of the P1.6/7 is low. __enable_irq(); while (1) { motor1_velocity(); for(o=650000;o>1;o--); } } /*Port 2 Interrupt handler*/ void PORT2_IRQHandler(void) { if(phase_detection==1) { if(P2IFG & BIT6) { captureA=TA0R; flagA=1; P1OUT ^=BIT0; P2IFG &=~ BIT6; } else if (P2IFG & BIT7) { captureB=TA0R; flagB=1; P2OUT ^= BIT1; P2IFG &=~ BIT7; } } }