This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Using eCAP for quadrature encoder

Other Parts Discussed in Thread: HALCOGEN, TMS570LS1224

Hi

Im trying to use the eCAP 2 and 3 from TMS570LS1224 to capture one encoder signals. I was looking at Halcogen but I have some questions.

I need to configure it fro continuous and for rising edge. And I need to reset the counter when I reach certain amount. Lets say 1000. Also I need to obtain the direction, which is easy. I just need to know how to obtain the timer value on the two events (channel A and channel B) so I can do

direction=timer_evnt1-timer_evnt2

if(direction<0)

direction is ccw

else

direction is cw

But I don't know 

1)how to configure the reset to happen with a value

2)how to obtain the timer value on that moment. 

Thanks!!

  • Hi,
    Is there any reason you don't want to use the eQEP module foryour intended application?

    The counter will keep going up until the specified event (i.e. a rising edge) is detected. For your question you can use the CTRRST1 bit in the ECCTL1 register to reset the counter when a capture event has happened. Note that counter is reset when an event is detected not when the counter reached a certain value. The eCAP has no such capability.

    To obtain the timer value you just read the CAPx register depending which one you pick to use for your application.
  • Hi Charles

    Those pins are being used for something else.. I have actually 12 encoders. Most of them are in the N2HET, which I still don't know how to retrieve the data but...
    For counter Im not talking about the timer. Im talking about the variable that gets incremented every time the event occurs.

    thanks

  • Please be specific as I'm really not clear what 'variable' you are talking about. The eCAP is a just a simple timer. A counter (timer) is counting and when there is a specified event detected on the eCAP pin then the counter value is captured into one of the CAPx register. That is pretty much all to the eCAP module.

    The eCAP can also operate in PWM mode. But the PWM is an output function. So I don't think this is what you are looking for.
  • aaaaaaaaaaaaaaaaaaaaaah ok ok ok
    I get it now.
    So I should then make a capture
    lets say:
    cap1 = ecapGetCAP1(ecapREG1);
    cap2 = ecapGetCAP2(ecapREG1);
    dir=cap2-cap1;
    if(dir<0)
    i++;
    else
    i--;
    if (i>max_position)
    i=0;

    but here I should need to reset the counter no? to avoid problems with the end of the cycle. Or start the timer with the first capture, and make a time stamp, turn it off on the second capture and reset it, without knowing which signal A or B could be the first one to arrive...
  • what is loading on capture?? what it does???

    and what timer is the one the module uses?? to know the maximum count... where is it configured??

  • is something like this, bit without me knowing the direction of the motor

    if(duty!=0)
    {
    	if(dir==0)
    	{
    		/*Configure Event 1 to Capture the rising edge*/ 
    		ecapSetCaptureEvent1(ecapREG1, RISING_EDGE, RESET_DISABLE);
    
    		/*Configure Event 2 to Capture the rising edge*/
    		ecapSetCaptureEvent2(ecapREG1, RISING_EDGE, RESET_ENABLE);
    
    		/*Set Capure mode as Continuous and Wrap event as CAP2*/
    		ecapSetCaptureMode(ecapREG1, CONTINUOUS, CAPTURE_EVENT2);
    
    		/* Start counter */
    		ecapStartCounter(ecapREG1);
    
    		/* Enable Loading on Capture */
    		ecapEnableCapture(ecapREG1);
    	}
    	if(dir==1)
    	{
    		/*Configure Event 1 to Capture the rising edge*/
    		ecapSetCaptureEvent1(ecapREG1, RISING_EDGE, RESET_ENABLE);
    
    		/*Configure Event 2 to Capture the falling edge*/
    		ecapSetCaptureEvent2(ecapREG1, RISING_EDGE, RESET_DISABLE);
    
    		/*Set Capure mode as Continuous and Wrap event as CAP3*/
    		ecapSetCaptureMode(ecapREG1, CONTINUOUS, CAPTURE_EVENT1);
    
    		/* Start counter */
    		ecapStartCounter(ecapREG1);
    
    		/* Enable Loading on Capture */
    		ecapEnableCapture(ecapREG1);
    
    
    	}
    }
    
    void ecapNotification(ecapBASE_t *ecap,uint16 flags)
    {
    	uint32 cap1, cap2;
    
    	cap1 = ecapGetCAP1(ecapREG1);
    	cap2 = ecapGetCAP2(ecapREG1);
    	
    	counter=cap1-cap2;
    	if(counter<0)
    		position++;
    	else
    		position--;
    
    }
    /* USER CODE END */

    this but lets say that the counter starts on the first event that occurs and gets reset after the second event, but I dont know which event is going to happen first, if event 1 or event 2

    thanks Charles

  • I don't think this is how you use it. The ecapGetCAP1(ecapREG1) is to read the CAP1 register of the eCAP1 module and eCAPGetCAP2(ecapREG1) is to read the CAP2 register of the same eCAP1 register. You can't use the way you are using here because it the same eCAP1 module. I though you will need two signals. That means you need two eCAP module. I think the eQEP is the module you want to use if your intention is quadrature encoding.
  • ok, I had a typo.
    I cannot use the eQEP because the pins are being used for other thing. It has to be the eCAP. What I need to know is how to do the code I show earlier to work without me knowing the direction of the rotation of the motors and without reseting the timer by hardware when using continuous mode but by software.
  • Your understanding of the eCAP is not really correct. I really suggest you to read the 4 examples about the eCAP usage in the TRM starting at section 20.6.1.

    As I said, You can't use only one eCAP module (which takes only 1 eCAP pin) to determine its rotational direction.

    On the first rise edge you capture a timer value. On the second rise edge you capture another value which will always be greater than the first value no matter how fast and slow the 2nd edge arrives. Even if the input does change direction it is only another edge to the eCAP module. The counter never knows a direction has changed. When you subtract the two values it is only a postive value no matter your dir==0 or dir==1.

    You really need two eCAP modules to even have a slight chance to get it work and I really don't think the eCAP is the right module for your quadradure encoding operation.
  • Hi

    This is what I did. I could just use the first capture or the second but I prefer using the 3 captures only in case I want to modify something and control the speed too. 

    		/*Configure Event 1 to Capture the rising edge*/ 
    		ecapSetCaptureEvent1(ecapREG2, RISING_EDGE, RESET_DISABLE);
    
    		/*Configure Event 2 to Capture the rising edge*/
    		ecapSetCaptureEvent2(ecapREG2, FALLING_EDGE, RESET_DISABLE);
    
    		/* Configure Event 3 to Capture the rising edge with reset counter enable */
    		ecapSetCaptureEvent3(ecapREG2, RISING_EDGE, RESET_ENABLE);
    
    		/*Set Capure mode as Continuous and Wrap event as CAP2*/
    		ecapSetCaptureMode(ecapREG2, CONTINUOUS, CAPTURE_EVENT3);
    
    		/* Enable Interrupt for CAP3 event */
    		ecapEnableInterrupt(ecapREG2, ecapInt_CEVT3);
    
    
    
    
    		/*Configure Event 1 to Capture the rising edge*/ 
    		ecapSetCaptureEvent1(ecapREG3, RISING_EDGE, RESET_DISABLE);
    
    		/*Configure Event 2 to Capture the rising edge*/
    		ecapSetCaptureEvent2(ecapREG3, FALLING_EDGE, RESET_DISABLE);
    
    		/* Configure Event 3 to Capture the rising edge with reset counter enable */
    		ecapSetCaptureEvent3(ecapREG3, RISING_EDGE, RESET_ENABLE);
    
    		/*Set Capure mode as Continuous and Wrap event as CAP2*/
    		ecapSetCaptureMode(ecapREG3, CONTINUOUS, CAPTURE_EVENT3);
    
    		/* Enable Interrupt for CAP3 event */
    		ecapEnableInterrupt(ecapREG3, ecapInt_CEVT3);
    
    
    		
    
    
    
    if(duty!=0)
    {
    
    	/* Start counter */
    	ecapStartCounter(ecapREG2);
    	/* Start counter */
    	ecapStartCounter(ecapREG3);
    
    	/* Enable Loading on Capture */
    	ecapEnableCapture(ecapREG2);
    	/* Enable Loading on Capture */
    	ecapEnableCapture(ecapREG3);
    
    	
    }
    
    void ecapNotification(ecapBASE_t *ecap,uint16 flags)
    {
    	if(ecap==ecapREG2)
    	{
    		ecapDisableCapture(ecapREG3);
    		if(position_motor_X<1440)
    		{
    			position_motor_X++;
    		}
    		if(position_motor_X==1440)
    		{
    			position_motor_X=0;
    		}
    		/*
    		uint32 cap1, cap2, cap3;
    				
    		cap1_A = ecapGetCAP1(ecapREG2);
    		cap2_A = ecapGetCAP2(ecapREG2);
    		cap3_A = ecapGetCAP3(ecapREG2);
    
    		cap1_B = ecapGetCAP1(ecapREG2);
    		cap2_B = ecapGetCAP2(ecapREG2);
    		cap3_B = ecapGetCAP3(ecapREG2);
    		*/
    
    	}
    		
    	if(ecap==ecapREG3)
    	{
    		ecapDisableCapture(ecapREG2);
    
    		if(position_motor_X<1440)
    		{
    			position_motor_X--;
    		}
    		if(position_motor_X==0)
    		{
    			position_motor_X=1439;
    		}
    	}
    
    
    }
    

    Basically, I configure the module from Halcogen but with the configuration shown at the top of the code. 

    Hope this helps.