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 */}