I and a co-worker are programming an 8051 uController in C. Last week we were struggling with a poor perfomance time of our program. So I talked to the assembly guy and we figured that our way of software timer handling was too slow. We were using 16 bit variables. Now I tweaked the timer software a bit and it runs about 4x faster, which is fast enough.
Digging a little deeper in the produced assembly code we found a 'persistent nuisance'. As a test I wrote these lines in code:
uint8 j; for(j=10;j--;){ rightTorqueArray[j] = j; }
The array is an unsigned char array but when we observe the assembly
MOV R7,#0AH ?C0001: MOV R6,AR7 DEC R7 MOV A,R6 JZ ?C0002 ; rightTorqueArray[j] = j; } ; SOURCE LINE # 52 MOV A,#LOW (rightTorqueArray) ADD A,R7 MOV DPL,A CLR A ADDC A,#HIGH (rightTorqueArray) MOV DPH,A MOV A,R7 MOVX @DPTR,A SJMP ?C0001 ?C0002:
We noticed that the array is adressed with LOW and HIGH so apparantly it is treated as a 16 bit variable. But my assembly-nese is not so well, so please correct me if I am wrong.
I set the Code Optimalization at level 8: reuse Common entry code and the emphasis at Favor speed.
The assembly was produced as a .SRC file using #pragma SRC on top of the C-file.
if the above code is the actual code, then the array actually contains fixed values over time, so it can be used as a code space array with predetermined byte values.
It isn't - the OP stated: "As a test I wrote these lines in code".
"the array actually contains fixed values over time, so it can be used as a code space array with predetermined byte values"
Indeed - Although fetching from CODE space isn't necessarily very efficient, either.
In fact, you wouldn't even need the array at all - as each element value is equal to its index, you could just use the index!
But, as noted, it's not the real code anyhow.
This is the torque measurement function with the old way using arrays and my attempt to make it quicker. One problem is that I cannot reliably monitor the execution time of any code on the oscilloscope because of an opto-coupler circuit. By toggling an output I can measure cycle times by counting the time between 2 up going flanks and devide it by 2 but to count the 'high time' of one block of code cannot be done.
I wrote a detailed description of what the function does, but this forum claimed I used a certain spam word SxAxLxE even though I could not find the string in question.
void updateTorque() { uint8 j=0; static uint8 firstPollLeft, secondPollLeft, thirdPollLeft, fourthPollLeft, firstPollRight, secondPollRight,thirdPollRight,fourthPollRight; uint16 totalTorqueLeft=0, totalTorqueRight=0; // OLD CODE USING ARRAYS leftTorqueArray[torqueIndex] = leftServoTorque; // stores ADC values in array rightTorqueArray[torqueIndex] = rightServoTorque; do { totalTorqueLeft += leftTorqueArray[j]; totalTorqueRight += rightTorqueArray[j]; j++; } while(j<SAMPLE_AMMOUNT); torqueIndex++; if(torqueIndex==SAMPLE_AMMOUNT) torqueIndex=0; // keeps track of the index so it remains 0 - 3*/ // NEW CODE WITHOUT ARRAYS switch(torqueIndex){ case 0: firstPollLeft = leftServoTorque; firstPollRight = rightServoTorque; break; case 1: secondPollLeft = leftServoTorque; secondPollRight = rightServoTorque; break; case 2: thirdPollLeft = leftServoTorque; thirdPollRight = rightServoTorque; break; case 3: fourthPollLeft = leftServoTorque; fourthPollRight = rightServoTorque; break;} totalTorqueLeft = firstPollLeft + secondPollLeft + thirdPollLeft + fourthPollLeft; totalTorqueRight = firstPollRight + secondPollRight + thirdPollRight + fourthPollRight; if(monitorLeftTorque==true) torqueLeft = totalTorqueLeft * 25 / TORQUEFACTORLEFT; // if we need to monitor torque values.. else torqueLeft = 0; if(monitorRightTorque==true) torqueRight = totalTorqueRight * 25 / TORQUEFACTORRIGHT; else torqueRight = 0; }
Yes, this forum's spam handling is complete rubbish!
View all questions in Keil forum