This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

C51 compiler type cast issues...

I am using Keil, C51 Compiler with Infineon XC886 8-bit micro....

I have a simple application that acquires rising and falling edges at P3.0 and then calculates the Period and Pulse Width in ticks of T12.

Then the program "based on these values" stretches the pulse using a 2D lookup table and generates a PWM output on P3.7 (it is inverted).

The lookup table returns a value from 0 to 1000.... a value of 300 means add 30% to the actual pulse width (NOT duty cycle which is %).

Everything seems to work except the output pulse width is incorrect.

I have (by process of elimintation) worked out the portion of code that is causing problems, but I think that it is actually the compiler.

The name of the function is "modifyDutyCycle"..

Step 1:
First I disabled all interrupts then cut and paste the contents of the function into main.
Since the calculation was quite involved I created a number of temporary variables to see the step by step results....


for (periodTemp = 3500; periodTemp < 31000; periodTemp += 200)
{
  for(pulseTemp = 150; pulseTemp < 4000; pulseTemp += 50)
  {
    //Checking the lookUpTable function here in the for loop.... works!
    //index1 = lookUpTable(periodTemp, pulseTemp);
    //delay(10);
    //Extended version of the calculation from the "modifyDutyCycle" function
    //adjustVal = (uword)(((ulong)dutyCycle[0])*((ulong)(lookUpTable(period[0], dutyCycle[0])))/1000);
    //index2 = (uword)(((ulong)pulseTemp)*((ulong)(lookUpTable(periodTemp, pulseTemp)))/1000);

    index2 = lookUpTable(periodTemp, pulseTemp);  //index2 = uword
    index3 = (ulong)index2;  //index3 = ulong
    index4 = (ulong)pulseTemp;  //index4 = ulong
    index5 = index3*index4;  //index5 = ulong
    index5 /= 1000;

    //Attempt #1
    //index6 = (uword)index5;   //index6 = uword
    //Attempt #2
    //blah = index5; //blah = uword
    //Attempt #3
    index6 = index5;

  }
}

Inititally "Attempt #1 failed to give the correct value"
Then I just added yet another variable "blah" - which generated the correct value.
Then I tried with no type cast with success

Step 2:
I returned to the original function and tried to get it to work - still using temporary variables.
When I simulate I get the following results...

1. There is no green/grey block on the side of the window (where you normally blace a breakpoint) at the "adjustVal = index4;" line

2. When I put the variable in the "watch" window however it seems to update the value of adjustVal

void modifyDutyCycle(void)
{
        //sam
        uword index1;
        ulong index2;
        ulong index3;
        ulong index4;
        uword adjustVal;
        //sam

        #ifdef debug
        programStatus = 0x40;
        #endif

        dutyCycleNew[3] = dutyCycleNew[2];
        dutyCycleNew[2] = dutyCycleNew[1];
        dutyCycleNew[1] = dutyCycleNew[0];

        //Calculate the extra number of timer ticks to be added to the output pulse
        //Stretch based on pulse width (off-time) not on total period

        //adjustVal = (uword)(((ulong)dutyCycle[0])*((ulong)(lookUpTable(period[0], dutyCycle[0])))/1000);

        index1 = lookUpTable(period[0], dutyCycle[0]);

        index2 = (ulong)index1;
        index3 = (ulong)dutyCycle[0];
        index4 = index2*index3;
        index4 /= 1000;

        //adjustVal = (uword)index4;      //typecast.. automatic??
        adjustVal = index4;
        //index1 = index4;

        //dutyCycleNew[0] = dutyCycle[0];

//      //Check that the new duty cycle is <100%
        if ((dutyCycle[0] + adjustVal) < (period[0] - 10))
        {
          //Return new updated duty cycle
          dutyCycleNew[0] =  dutyCycle[0] + adjustVal;
        }
        else //Error has occurred....
        {
          dutyCycleNew[0] = period[0] - 10;                     //Make the pulse width to approx. 100%
        }
}

3. When I try it on my hardware, I have a pulse output but the width is incorrect - which looks very similar to the first time I tried the funtion in main "Attempt #1"

My problem is something to do with a type cast or a memory addressing issue I think. But my results are inconsistent.

Any help on this oune would be much appreciated!!

Thanks, bye!!

Parents
  • As said before, 'word' is not my preference, as a lousy typist, I prefer U16. However, once again, if all developers in a group fully understand the meaning of "Ralph", "Ralph" will work.

    I do believe that outlawing "WORD" after it has been used by an organization for a long time will lead to more problems that keeping it.

    I have not, for a long time had the luxury of starting an organizations embedded software from scratch, but when doing so have never used 'word' or 'WORD'.

    Yes, using 'word' is not the best choice, but it is, in my opinion, not as disastrous as some think.

    Erik

Reply
  • As said before, 'word' is not my preference, as a lousy typist, I prefer U16. However, once again, if all developers in a group fully understand the meaning of "Ralph", "Ralph" will work.

    I do believe that outlawing "WORD" after it has been used by an organization for a long time will lead to more problems that keeping it.

    I have not, for a long time had the luxury of starting an organizations embedded software from scratch, but when doing so have never used 'word' or 'WORD'.

    Yes, using 'word' is not the best choice, but it is, in my opinion, not as disastrous as some think.

    Erik

Children
  • "However, once again, if all developers in a group fully understand the meaning of "Ralph", "Ralph" will work."

    Exactly. But even if all developers in a groupo fully understand the maning of "Ralph", it would still not be a good idea to create a variable "Ralph" or a data type "Ralph" to store the mains voltages read from an ADC.

    And "Ralph" would not be a good name of a function that computes the RMS of the same mains voltage measurements.

    And "Ralph" would not be a good name for a signal pin used to latch data onto a LCD to display the results of such a mains measurement.

    The bad thing here, is that "Ralph" - just as "word" - requires the user to memorize the meaning of a token that does not in itself carry any real descriptive meaning. A real program does not contain one symbol. It contains hundreds or thousands or maybe much, much more. But our memories are limited. So once now and then, one of these developers will forget the true, original, meaning of that symbol. And it will suddenly be used for something else that is not compatible with the original meaning.

    That a program can work, if a data type 'word' is used, doesn't say much. The question isn't if a program will work. The question is the total probability of introducing errors, because of the additional needs to make sure that everyone involved understands the exact meaning of every symbol, without the symbol name giving any meaningful hint.

    And the even bigger problem - what do you do with a program that uses the datatype 'word', if you need to move the source code to a different platform? Is 'word' still a 16-bit data type? Or is 'word' still a register-size data type? With a data type named after the properties it promises to supply the developer with, you will have a greater probability that all developers will remember that every single use of the datatype is based on these promised properties. And not potential extra properties for that specific platform.

    The ultimate question here is: What do you promise the developer, when you give them access to a variable of the data type 'word'? What is the text of your contract? And are you sure that you can keep that contract if porting the source code? Microsoft failed badly, when they promised a meaning of 'WORD'. They run like an express train straight into a very massive wall.
    Option 1: Break the contract on the meaning of 'WORD'.
    Option 2: Break the contract of the meaning of their different function calls and structures.

    Microsoft isn't the only company that have hit that very massive wall because they have reached a situation where they have to make a promise - all caused by the use of 'word', 'WORD', 'Word', 'QWORD', or similar.

    The smart thing to do, is to avoid taking routes where it is already know that a skillfull trap-layer have set out a number of well-camouflaged traps. The likelyhood of getting caught is just too high. And the rework costs can be quite high to try to back-track.