Code: Select all
void HMC5843::init()
{
PORTC = 0b00110000; // Use the internal pull up resistors
// Choose 100KHz for the bus. Formula from 21.5.2 in ATmega168 datasheet.
TWSR &= ~((1<<TWPS1)&(1<<TWPS0));
TWBR = (unsigned char)(F_CPU/200000l-8);
// Put the HMC5843 into continuous mode
sendStart();
sendByte(0x3C);
sendByte(0x02);
sendByte(0x00);
sendStop();
// note that you need to wait 100ms after this before first calling recieve
}
Code: Select all
void HMC5843::sendStart(void)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
}
// close i2c
void HMC5843::sendStop(void)
{
waitForReady();
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
// send a byte when the channel is ready
void HMC5843::sendByte(unsigned char data)
{
waitForReady();
TWDR = data;
TWCR = (1<<TWINT)|(1<<TWEN);
}
Code: Select all
void HMC5843::getValues(int *x, int *y, int *z)
{
unsigned char xin, yin, zin;
// start the reading
sendStart();
sendByte(0x3D);
// read out the 3 values, 2 bytes each. lsb first, then msb.
xin = receiveByte();
*x = (xin<<8)|receiveByte();
yin = receiveByte();
*y = (yin<<8)|receiveByte();
zin = receiveByte();
*z = (zin<<8)|receiveByte();
// wrap back around for the next set of reads and close
sendByte(0x3D);
sendStop();
}