Hello,
I am designing for the MC9S12E128. I am working with the input and ouput port of PORTA.
I have a variable that is 2 bytes. In C, how do I perform a complement on both bytes of the variable?
XResult = ~XResult only complements the byte in memory at the higher address.
I need to complement the byte in the lower memory address as well.
XResult is an unsigned int.
Thanks,
Patrick
The code attached is an effort to receive an 11 bit, pulsed value from a Hitachi HM55B compass. I realize there are some better ways to do what I am doing: 1. Use math.h to use the pow() function -- I had trouble importing the math.h. I kept getting errors from the compiler when I would add #include <math.h> (it exists in the defined area of the project). 2. I could probably use input capture on board the chip but it was easier to just read single pin port values. 3. It is also interesting to note that I can't set a breakpoint at XValue = ~XValue, the breakpoint just gets skipped over in the debugger -- optimizations are not turned on. 4. TakeMeasurement() is reading an 11 bit value that is given as 2's complement, MSB first, and I am deciphering that into an integer value.
5. The code is listed below -- thank you for the help!
#include <hidef.h> /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */#include "main_asm.h" /* interface to the assembly module */#include <math.h>// --------------------------------------------// Definitions// -------------------------------------------- // --------------------------------------------// Peripheral Initialization Routine// --------------------------------------------void PeriphInit(void){ DDRA_BIT0 = 1; //Make PortA[0] an output: Enable line DDRA_BIT1 = 1; //Make PortA[1] an ouput: ControlBits (Din from HM55B docs) DDRA_BIT2 = 1; //Make PortA[2] an ouput: Clock for running compass DDRA_BIT3 = 0; //Make PortA[3] an input: ResultData (Dout from HM55B docs) }// --------------------------------------------#include <hidef.h> /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */#include "main_asm.h" /* interface to the assembly module */#include <math.h>// --------------------------------------------// Definitions// -------------------------------------------- // --------------------------------------------// Peripheral Initialization Routine// --------------------------------------------void PeriphInit(void){ DDRA_BIT0 = 1; //Make PortA[0] an output: Enable line DDRA_BIT1 = 1; //Make PortA[1] an ouput: ControlBits (Din from HM55B docs) DDRA_BIT2 = 1; //Make PortA[2] an ouput: Clock for running compass DDRA_BIT3 = 0; //Make PortA[3] an input: ResultData (Dout from HM55B docs) }// --------------------------------------------// Turn Enable Line Low// --------------------------------------------void EnableLow(void) { PORTA_BIT0 = 0; return;}// --------------------------------------------// Turn Enable Line High// --------------------------------------------void EnableHigh(void) { PORTA_BIT0 = 1; return;}// --------------------------------------------// Ouput a Control Code while Clocking// --------------------------------------------void OutputControlCode(unsigned int ControlCode, int NumberOfBits) //implement ControlCode to pass in { unsigned int TempCode = 0b00000001; int i; for(i=1; i <= NumberOfBits; i++) { //Iterate over four bits and output PORTA_BIT2 = 1; //Clock high if (TempCode & ControlCode) { PORTA_BIT1 = 1; //Bit is a 1, output a 1 } else { PORTA_BIT1 = 0; //Bit is a 0, output a 0 } TempCode <<= 1; PORTA_BIT2 = 0; //Clock low } return;} // ---------------------------------------------// Read a Code or Data from the compass while clocking// ---------------------------------------------char ReadCodes(void) //Just tell me how many bits to read { char CompassStatusFlags[4]; char TempReadCode; int i; for(i=1; i <= 4; i++) { //Iterate over four bits and output PORTA_BIT2 = 1; //Clock high if (0b00000000 | PORTA_BIT3) { CompassStatusFlags[i-1] = 1; } else { CompassStatusFlags[i-1]=0; } PORTA_BIT2 = 0; //Clock low } if (CompassStatusFlags[0] == 1 && CompassStatusFlags[1] == 1 && CompassStatusFlags[2] == 0 && CompassStatusFlags[3] == 0) { TempReadCode = 'A'; //Measurement complete, ready to clock out data return TempReadCode; } if (CompassStatusFlags[0] == 0 && CompassStatusFlags[1] == 0) { TempReadCode = 'B'; //Measurement still in progress, or the device has been reset. return TempReadCode; } if (CompassStatusFlags[2] == 0 && CompassStatusFlags[3] == 0) { TempReadCode = 'C'; ///EN did not receive low-high-low signal between start and report commands return TempReadCode; }}// ---------------------------------------------// Reset Compass// ---------------------------------------------void ResetCompass(void) { EnableHigh(); EnableLow(); OutputControlCode(0b00000000, 4); EnableHigh(); }// ---------------------------------------------// Start Measurement// ---------------------------------------------void StartMeasurement(void) { EnableLow(); OutputControlCode(0b00000001, 4); }// ---------------------------------------------// Check Measurement// ---------------------------------------------void CheckMeasurement(void) { char Result; //Initialize result code Result = 'D'; EnableLow(); //Enable Compass OutputControlCode(0b00000011, 4); //Send an "Are you ready?" code //Check to see if we had a valid measurement, "A" means 11 -> Measurement completed; 00 -> no errors while(Result != 'A') { Result = ReadCodes(); } }// ---------------------------------------------// Take Measurement// ---------------------------------------------void ReadMeasurement(void) { signed int XSign, YSign; unsigned int XValue, YValue; //signed int XResult, YResult; XValue = 0; YValue = 0; XSign = 1; YSign = 1; int j, k; //Read in X Values for(j=10; j>=0; j--) { //Iterate over 11 bits PORTA_BIT2 = 1; //Clock high if (0b00000000 | PORTA_BIT3) { if (j==10) { XSign = -1; } if (j==9) { XValue = XValue + 2*2*2*2*2*2*2*2*2; } if (j==8) { XValue = XValue + 2*2*2*2*2*2*2*2; } if (j==7){ XValue = XValue + 2*2*2*2*2*2*2; } if (j==6){ XValue = XValue + 2*2*2*2*2*2; } if (j==5) { XValue = XValue + 2*2*2*2*2; } if (j==4) { XValue = XValue + 2*2*2*2; } if (j==3) { XValue = XValue + 2*2*2; } if (j==2) { XValue = XValue + 2*2; } if (j==1) { XValue = XValue + 2; } if (j==0) { XValue = XValue + 1; } } PORTA_BIT2 = 0; //Clock low } XValue = ~XValue; //XValue = XValue + 1; //Read in Y Values for(k=10; k>=0; k--) { //Iterate over four bits and output PORTA_BIT2 = 1; //Clock high if (0b00000000 | PORTA_BIT3) { if (k==10) { YSign = -1; } YValue = ~YValue; YValue = YValue + 1; } PORTA_BIT2 = 0; //Clock low } }// ---------------------------------------------// Main// ---------------------------------------------void main(void) { /* put your own code here */ //int ResolvedHeading; EnableInterrupts; PeriphInit(); ResetCompass(); StartMeasurement(); // CheckMeasurement(); ReadMeasurement(); for(;;) { _FEED_COP(); /* feeds the dog */ } /* loop forever */ /* please make sure that you never leave main */}// -------------------------------// Turn Enable Line Low// -------------------------------void EnableLow(void) { PORTA_BIT0 = 0; return;}// -------------------------------// Turn Enable Line High// -------------------------------void EnableHigh(void) { PORTA_BIT0 = 1; return;}// -------------------------------------// Ouput a Control Code while Clocking// -------------------------------------void OutputControlCode(unsigned int ControlCode, int NumberOfBits) //implement ControlCode to pass in { unsigned int TempCode = 0b00000001; int i; for(i=1; i <= NumberOfBits; i++) { //Iterate over four bits and output PORTA_BIT2 = 1; //Clock high if (TempCode & ControlCode) { PORTA_BIT1 = 1; //Bit is a 1, output a 1 } else { PORTA_BIT1 = 0; //Bit is a 0, output a 0 } TempCode <<= 1; PORTA_BIT2 = 0; //Clock low } return;} // -------------------------------------// Read a Code or Data from the compass while clocking// -------------------------------------char ReadCodes(void) //Just tell me how many bits to read { char CompassStatusFlags[4]; char TempReadCode; int i; for(i=1; i <= 4; i++) { //Iterate over four bits and output PORTA_BIT2 = 1; //Clock high if (0b00000000 | PORTA_BIT3) { CompassStatusFlags[i-1] = 1; } else { CompassStatusFlags[i-1]=0; } PORTA_BIT2 = 0; //Clock low } if (CompassStatusFlags[0] == 1 && CompassStatusFlags[1] == 1 && CompassStatusFlags[2] == 0 && CompassStatusFlags[3] == 0) { TempReadCode = 'A'; //Measurement complete, ready to clock out data return TempReadCode; } if (CompassStatusFlags[0] == 0 && CompassStatusFlags[1] == 0) { TempReadCode = 'B'; //Measurement still in progress, or the device has been reset. return TempReadCode; } if (CompassStatusFlags[2] == 0 && CompassStatusFlags[3] == 0) { TempReadCode = 'C'; ///EN did not receive low-high-low signal between start and report commands return TempReadCode; }}// -------------------------------------// Reset Compass// -------------------------------------void ResetCompass(void) { EnableHigh(); EnableLow(); OutputControlCode(0b00000000, 4); EnableHigh(); }// -------------------------------------// Start Measurement// -------------------------------------void StartMeasurement(void) { EnableLow(); OutputControlCode(0b00000001, 4); }// -------------------------------------// Check Measurement// -------------------------------------void CheckMeasurement(void) { char Result; //Initialize result code Result = 'D'; EnableLow(); //Enable Compass OutputControlCode(0b00000011, 4); //Send an "Are you ready?" code //Check to see if we had a valid measurement, "A" means 11 -> Measurement completed; 00 -> no errors while(Result != 'A') { Result = ReadCodes(); } }// -------------------------------------// Take Measurement// -------------------------------------void ReadMeasurement(void) { signed int XSign, YSign; unsigned int XValue, YValue; //signed int XResult, YResult; XValue = 0; YValue = 0; XSign = 1; YSign = 1; int j, k; //Read in X Values for(j=10; j>=0; j--) { //Iterate over 11 bits PORTA_BIT2 = 1; //Clock high if (0b00000000 | PORTA_BIT3) { if (j==10) { XSign = -1; } if (j==9) { XValue = XValue + 2*2*2*2*2*2*2*2*2; } if (j==8) { XValue = XValue + 2*2*2*2*2*2*2*2; } if (j==7){ XValue = XValue + 2*2*2*2*2*2*2; } if (j==6){ XValue = XValue + 2*2*2*2*2*2; } if (j==5) { XValue = XValue + 2*2*2*2*2; } if (j==4) { XValue = XValue + 2*2*2*2; } if (j==3) { XValue = XValue + 2*2*2; } if (j==2) { XValue = XValue + 2*2; } if (j==1) { XValue = XValue + 2; } if (j==0) { XValue = XValue + 1; } } PORTA_BIT2 = 0; //Clock low } XValue = ~XValue; //XValue = XValue + 1; //Read in Y Values for(k=10; k>=0; k--) { //Iterate over four bits and output PORTA_BIT2 = 1; //Clock high if (0b00000000 | PORTA_BIT3) { if (k==10) { YSign = -1; } YValue = ~YValue; YValue = YValue + 1; } PORTA_BIT2 = 0; //Clock low } }// -------------------------------------// Main// -------------------------------------void main(void) { /* put your own code here */ //int ResolvedHeading; EnableInterrupts; PeriphInit(); ResetCompass(); StartMeasurement(); // CheckMeasurement(); ReadMeasurement(); for(;;) { _FEED_COP(); /* feeds the dog */ } /* loop forever */ /* please make sure that you never leave main */}
Please disregard the previous reply. I corrected my error, I had the wrong version of the C ansi library referenced. Likewise, I was able to get the complement ooperator to work, but I noticed that statements such as:
XValue = ~XValue;
XValue = XValue + 1;
Would get skipped over by the debugger.
After fixing my code, I no longer have this problem. I will post again in the future with more details when it happens again.
Thank you.