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.

PWM problems (TimerA & TimerB)

Hello,

I'm working with eZ430-rf2500, I want 2  PWM (timerA) and another 2 PWM (timerB). But, the PWMs interfere themsleves, and I don't know why.

The program takes the information from differents ADC10.

This is the code:

////////////////////////////MAIN PROGRAM/////////////////////

for(;;)
{ 

potencia1 = potencia();
potencia2 = potencia();
potencia3 = potencia();
potencia4 = potencia();

do
{ 

switch(flag)
{
case(2):
a = calibrarX(); 
motor1(averageX);
flag = 4;

case(4):
b = calibrarY(); 
motor2(averageX);
flag = 2;

}



}
}while ( (a!= averageX)&&(b != averageY) );

}

/////////////////////////MOTORS////////////////////////////////////////////


void motor1(int averageX)
{
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;

P2DIR |= BIT3 + BIT4; // P2.3 and P2.4 output
P2SEL |= BIT3 + BIT4; // P2.3 and P2.4 TA1/2 otions

TACTL = TASSEL_2 + ID_3 + MC_1; // SMCLK, up mode BIT4
TACCR0 = 125; // PWM Period
TACCTL1 = OUTMOD_7; // TACCR1 reset/set MOTOR1
TACCTL2 = OUTMOD_7; // TACCR2 reset/set MOTOR2


while( (a!= averageX) || (a== averageX) ) //Valor instantaneo vs average1
{ 
if(a < averageX && potencia1 <126)
{ 
potencia1 = potencia1 + 1;
TACCR1 = potencia1; 
}
if(a < averageX && potencia2 >0)
{
potencia2 = potencia2 - 1;
TACCR2 = potencia2; 
}
if(a > averageX && potencia1 >0)
{ 
potencia1 = potencia1 - 1; 
TACCR1 = potencia1; 
}
if(a > averageX && potencia2 <126)
{ 
potencia2 = potencia2 + 1;
TACCR2 = potencia2;
} 
if (a == averageX)
{
TACCR1 = potencia1;
TACCR2 = potencia2;
} 
break; 
}
}

void motor2(int averageY)
{
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;

P4DIR |= BIT4 + BIT5; // P1.2 and P1.3 output
P4SEL |= BIT4 + BIT5; 

TBCTL = TBSSEL_2 + ID_3 + MC_1;
TBCCR0 = 125; // PWM Period
TBCCTL1 = OUTMOD_7; // TACCR1 reset/set
TBCCTL2 = OUTMOD_7; // TACCR2 reset/set BIT3


while( (b!= averageY) || (b == averageY) ) //Valor instantaneo vs average1
{
if (b < averageY && potencia3 <126)
{ 
potencia3 = potencia3 + 1;
TBCCR1 = potencia3;
}
if(b < averageY && potencia4 >0)
{
potencia4 = potencia4 - 1;
TBCCR2 = potencia4;
}
if(b > averageY && potencia3 >0)
{ 
potencia3 = potencia3 - 1;
TBCCR1 = potencia3; 
}
if(b > averageY && potencia4 <126)
{ 
potencia4 = potencia4 + 1;
TBCCR2 = potencia4;
} 
if (b ==averageY)
{
TBCCR1 = potencia3; 
TBCCR2= potencia4;
}
break; 
}
}

  • Marcos Marcos said:
    switch(flag) { case(2): a = calibrarX(); motor1(averageX); flag = 4;

    Add here a break;

  •  To clarify Leo's Advice:

    A switch block is a chain of if/goto statements, followed by code that contains labels to jump into it:

    If value == "1" goto case1;
    If value == "2" goto case2;

    goto default;
    case1:
    your code
    case2:
    your code
    ...

    The code for the cases is compiled sequentially, just as you wrote it. So at the end for the code for case1, the code for case 2 follows. Depending on the value parameter, the code execution just skips the first cases until the ‘right’ one, and continues execution there. To prevent one case falling through all the next cases, the last instruction in the case must be a break, which is a jump to the end of the switch block.

     The use of the __even_in_range intrinsic replaces teh chain of comparisons by something more efficient: assuming that there are n possible values which are from 0 to 2n, it generates a jumptable and just adds the switch value to the current program counter, ending up on one of the jump instructions in the table, jumping to the code for the associated case. There is no need for a default case or to define all cases, as any missing case of the n possible will jump to the end of the switch statement. The drawback is that the whole switch statement must be smaller than 1k of code (the jump instruction used in this table can only jump for 512 words)

**Attention** This is a public forum