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.

TMS320F2812 QEP peripheral

Other Parts Discussed in Thread: TMS320F2812

Hello everyone, I am starting programing a DSP (TMS320F2812), and I´m trying to use de QEP peripheral, following the example thats cames with the device. When I read de counter (EvbRegs.T4CNT) and save in to an array. This  is an example of the array that I read, when i finish my program:

vector=[constan, 0, constan, 0, constan,..........., 0, constan]

I want to know if, this is rigth or i should have an array like this (reading the counter of de QEP):

vector=[constans, constans, constans, constans, constans,..........., constans, contans]

thanks for taking your time to read this

  • Alan,

    The QEP provides a 16-bit result that is kept in the 16-bit register T2CNT (for EV-A) or T4CNT (for EV-B).  So, when you read the TxCNT register you get a 16-bit value.  I would assume you'd store it in a 16-bit array, vector=[value1, value2, ...].  I'm not following where the zeros would be coming from in your suggested [value1, 0, value2, 0,...].

    Note that F2812 is an older device.  You'd be better off using the floating point F2833x family (e.g., F28334) or the fixed-point F2823x family (e.g., F28234).

    Regards,

    David

  • Thank you very much David, thats helped me a little fot undestang the behavior of the QEP, but I still have that problem about the array thats read a 0 between the constants 

    This is my code for configuration

    void conf_QEP (void)
    {
    DemoQEP.position = 0x0000;

    // configure shared pins as capture input pins
    EALLOW;
    GpioMuxRegs.GPAMUX.all = 0x0700;//0x73F; // EVA CAP/QEP pins
    EDIS;

    EvaRegs.GPTCONA.bit.T2TOADC = 0; // configure GPTCONA not to start ADC on GPT2 Event
    // set GPT2 configuration register
    EvaRegs.T2CON.all = TxCON_INI_QEP; // T2CON prepared to use for QEP, x/1

    // configure Capture Control Register CAPCONA
    EvaRegs.CAPCON.bit.CAPQEPN = 3; // enable QEP in CAPCONA register

    }

    And this is where I read the counter


    //===========================================
    if (med_veloc==1){ //Se lanza el contador de pulsos
    // Setup Timer 2 Registers (EV A)
    EvaRegs.T2PR = T2PR_INI; // initialize GPT2 timer period
    EvaRegs.T2CNT = TxCNT_INI_QEP; // reset GPT2 counter register
    // start timer 2
    EvaRegs.T2CON.bit.TENABLE = 1; // Start GPT2 counter to count QEP circuit pulses
    EvaRegs.CAPCON.bit.CAPQEPN = 3; // enable QEP in CAPCONA register

    } //Pasaron 50 microsegundos y se hace el calculo de la velocidad

    if (med_veloc==2){
    med_veloc=0;
    cont = EvaRegs.T2CNT; //Se almacena el valor del contador
    //if(cont>100){
    //Se comprueba si la maquina gira en sentido real
    if(k<2499){
    res_ma[k]=cont;
    k++;
    }

    Do I have any erro in the configuration of the QEP?

  • Alan,

    You don't show the declarations for your variables and array in your code.  You should not be getting zeros in between the data in the res_ma[] array.  T2CNT is a 16-bit register.  Read it temporarily to the 16-bit variable cont, and then store it to a 16-bit array res_ma[].  For example:

    Uint16 k, cont, res_ma[2500];
    cont = EvaRegs.T2CNT;
    if(k<2499)
    {
       res_ma[k]=cont;
       k++;
    }

     

    Frankly, I don't see why you need the intermediate variable 'cont', but I'm just following what you showed in your code.

     

    Regards,

    David

     

  • David:

    Thank you again for the help, as last option I wanto to know if you give me a mail were I could find a paper thats talk about the enmask of the QEP. Maybe there I could find some answer to my problem.

    Regards

    Alan

  • Alan,

    Alan Blumenstein said:

    ... find a paper thats talk about the enmask of the QEP. Maybe there I could find some answer to my problem.

    I do not understand what you mean by "Enmask of the QEP".  Can you explain?

    Regards,

    David

  • Dacid

    In the example program i have the line were its define the "enmask"

    EALLOW;
    GpioMuxRegs.GPAMUX.all = EVA_QEPENMSK;           //* EVA CAP/QEP pins

    EDIS;

    the value its usually 0x0700, but I know that I can change that for make it work in oder for, were can i find the paper for read about that?

  • Alan,

    Alan Blumenstein said:

    EALLOW;
     GpioMuxRegs.GPAMUX.all = EVA_QEPENMSK;           //* EVA CAP/QEP pins
    EDIS; 

    OK, I see what you are talking about now.  I don't know what example you have.  Maybe something from an old TI motor control EVM?  EVA_QEPENMSK is just a #define in some header file someplace in the project.  It is not in the peripheral header files, so it must be specific to the example you are looking at.  I can see that whoever named it, it stands for 'Event-manager-A QEP Enable Mask'.  All the code you show is doing is setting the GPIO mux register so that the QEP pins are set to QEP function instead of GPIO function.  See the F2812 System Control and Interrupts User's Guide, SPRU078F, p.4-11, Table 4-3:

     

    You can see why the constant is defined as 0x0700.  That sets bits 8, 9, and 10 to a '1', which means QEP1, QEP2, and QEPI function.  I would say that normally you would use an OR operation to set the mux register instead of an assignment to preserve the other bits (unless the other bits are all supposed to be GPIO):

    EALLOW;
     GpioMuxRegs.GPAMUX.all |= EVA_QEPENMSK;           //* EVA CAP/QEP pins
    EDIS;

    but this has absolutely nothing to do with the issue you're having.  I don't think the GPIO mux has anything to do with the issue you're having either.

    Have you tried setting a breakpoint where you read the TxCNT register (the QEP) and see what is going on?  Is the TxCNT register actually zero (I bet not)?  Hand turn the encoder and watch the TxCNT change each time you hit the breakpoint.  Then watch the code read the value into the array.  You should be able to see pretty quickly what is going on.  My suspicion continues to be that you've declared the array as a 32-bit quantity.

    Regards,

    David

  • David:

    Tank you for the help again, I allready changed the array for an Uint16, and its reading better but it still have some 0 in the aray wen I read, I also try changing the period of my PWM, its supous to read a diferent constant but it doesn´t.

    Wen I put a breakpoint in my variable I read negative numbers (like -256 ,-14, -26, etc) but in the vector I read 64550 all the time, I guess that that hapen becase its unsigned, I will try chanfing that and see waths happend, but is normal reading  in my TxCNT negative numbers?

    Regarts

    Alan   

  • Allready change it for an int, the value that i have in my vector is 0xFFF or 65535

  • Alan,

    The timer counter TxCNT is a 16-bit unsigned value.  If you read it, you get a hex value of 0x0000 to 0xFFFF, which equates to 0 to 65535 decimal.  You should read it as unsigned.

    If you read it as a signed value, then 0xFFFF will be seen -1 decimal.

    - David

  • I allready did that, rigth now my array is an Uint16 array, and i ´m saving directly from the TxCNT, but I´m having the same problem, rigth now my array is reading mainly valuos mostly from 0 65.534 and in some case 65535 and 1 (not to often the 1), I think i am having an overflowing.

    How can I change the period or do something for read faster the encoder?

  • Alan,

    I don't think you have a reading problem here at all.  I think you have something else going on.  Maybe the encoder signals are not connected correctly or something like that.

    I would turn off whatever it is that is rotating the encoder.  Then, put an endless loop in your code after init and run your code.  Halt it in the loop.  View the TxCNT register in a watch window.  You should then be able to hit run, halt, run, halt, etc. and the TxCNT register should NOT change.  Then run the code and rotate the encoder a tick or two BY HAND.  Then halt the processor.  Does the TxCNT reflect a count of a couple of ticks?  Do this some more.  Is it still working?  Then rotate in the opposite direction.  Are the ticks coming off the counter?

    If everything above seems to work correctly, then you can turn to the code that reads the counter.  But frankly, there is no much you can do to mess up reading a 16-bit register into an array.  Hence, I think something else is going on.  Also, I seriously doubt you are overflowing the counter.  What is the encoder attached to?  How fast does it rotate?  How many ticks per rotation?  You can calculate how long it would take to overflow the 16-bit counter.  And if you did overflow, what are the chances that you'd always be reading the counter when the count was around zero?  Unlikely.

    Regards,

    David

  • Thanks for the help again! Finally, Its reading something, but it´s reading position, I want to read speed (or frequency), I hope there is a simply way, (changing a parameter to make this hapen.

    Regards

  • Alan,

    The QEP on the F2812 event manager reads position.  If you need velocity, you need to estimate it using a first-order difference (for example):

    v ~= [x(t) - x(t-T)]/T

    where

    x(t) is current QEP position reading

    x(t-T) is the QEP reading at time 'T' back

    T is a fixed time interval.

    The above works OK for speeds other than very slow speed (which I am not defining here deliberately).  At very slow speed, you need to use

    v ~= delta_x/(t2 - t1)

    where delta_x is a fixed position interval (one tick on the encoder usually) and (t2-t1) is how long it takes for the delta_x to occur.

    There is some discussion on this in the F2803x Piccolo eQEP user's guide, SPRUFK8, p.10.  I know you are using F2812, but the discussion still applies.  You'd need to use the capture unit to compute the slow speed v (eQEP has facilities to assist with this, but that is not on the F2812).  There is also a very old appnote SPRA363 that talks about this, http://www.ti.com/general/docs/litabsmultiplefilelist.tsp?literatureNumber=spra363.  This is for the old C24x processor, but basically applies to F2812 (C24x also had the event manager).

    - David

     

  • Oder way to say it is

    v = EvaRegs.T2CNT/EvaRegs.T2PR ?

  • Alan Blumenstein said:

    Oder way to say it is

    v = EvaRegs.T2CNT/EvaRegs.T2PR ?

     
    No, that is not correct.  The 'T' in the equation is the elapsed time between QEP readings.  That is not the same thing as the T2PR value.  Actually, you want T2PR to be set to 0xFFFF in order for the T2CNT to roll over at 0xFFFF (I assume T2 is holding your QEP count).  That way you can perform modulo-16 arithmetic when you compute x(t)-x(t-T).
     
    I mean, think about this.  Suppose x(t)=0x0001, and x(t-T)=0xFFFF.  It means that x(t)-x(t-T) = 0x0002.
     
    Take a look at that appnote SPRA363.
  • Hello again! I´m still trying to mesuare speed with the QEP, for that I am mearing the speed on an Interruption activate by 

    IER |= M_INT5; // Habilita la interrupcion para el contador
    IER |= M_INT9; // Habilita la interrupcion para el monitor

    I am using this algorith for mesuare the speed:

    if (med_veloc==1){

    //Se lanza el contador de pulsos
    // Setup Timer 2 Registers (EV A)


    EvaRegs.T2PR = T2PR_INI; // initialize GPT2 timer period
    EvaRegs.T2CNT = TxCNT_INI_QEP; // reset GPT2 counter register


    // start timer 2


    EvaRegs.T2CON.bit.TENABLE = 1; // Start GPT2 counter to count QEP circuit pulses
    EvaRegs.CAPCON.bit.CAPQEPN = 3; // enable QEP in CAPCONA register

    } //Pasaron 50 microsegundos y se hace el calculo de la velocidad

    if (med_veloc==2){
    med_veloc=0;
    cont = EvaRegs.T2CNT;


    if(k<20480){
    res_ma[k]=cont;
    k++;
    }//Se almacena el valor del contador

    res_ma (is the vector (Uint16) wich I mesuare the speed.

    Anyway I am reading number close to the end of scale (65530-65535) whith diferents speed of my motor. So i am not sure if I am making this rigth (I know I still need to divide th "cont" by oder contans, but I think that I should get diferents constanst number for diferents speed, I am rigth?)

    Thanks for the help!