#include /* Example code for C18 compiler and PIC18F452, author: Jindong Liu, 23/07/2004 Compass board uses address 1100000 - 0xc0 This code shows how to program a PIC18F452 to communicate with the compass module via the I2C bus. It uses the hardware I2C port on the PIC, this is the MSSP. The PIC is assumed to use an 8MHz crystal, otherwise adjust SSPADD in the setup routine. */ void setup(void); void read_compass(unsigned char *buffer); int compass_high; int compass_low; int compass; unsigned char compasschar[4]; unsigned char version, compassbyte; void main(void) { setup(); while(1) { read_compass(compasschar); version = compasschar[0]; compassbyte = compasschar[1]; compass_low = compasschar[3]; compass_high = compasschar[2]; compass = (compass_high<<8) + compass_low; //the compass range: 0-3599, compassbyte range: 0-255. } } //COMPASS ROUTINE void read_compass(unsigned char *buffer) { SSPCON2bits.SEN = 1; // send start bit while(SSPCON2bits.SEN); // and wait for it to clear SSPCON2bits.ACKDT = 0; // acknowledge bit PIR1bits.SSPIF = 0; SSPBUF = 0xC0; // 11000000 - write command while(!PIR1bits.SSPIF); // wait for interrupt PIR1bits.SSPIF = 0; // then clear it. SSPBUF = 0; // read from address 0 while(!PIR1bits.SSPIF); // PIR1bits.SSPIF = 0; // SSPCON2bits.RSEN = 1; // send repeated start bit while(SSPCON2bits.RSEN); // and wait for it to clear PIR1bits.SSPIF = 0; SSPBUF = 0xC1; // 11000001 - read command while(!PIR1bits.SSPIF); // wait for interrupt PIR1bits.SSPIF = 0; // then clear it. SSPCON2bits.RCEN = 1; // start receiving while(!SSPSTATbits.BF); // wait for data buffer[0] = SSPBUF; // and get it SSPCON2bits.ACKEN = 1; // start acknowledge sequence while(SSPCON2bits.ACKEN); // wait for ack. sequence to end SSPCON2bits.RCEN = 1; // start receiving while(!SSPSTATbits.BF); // wait for data buffer[1] = SSPBUF; // and get it SSPCON2bits.ACKEN = 1; // start acknowledge sequence while(SSPCON2bits.ACKEN); // wait for ack. sequence to end SSPCON2bits.RCEN = 1; // start receiving while(!SSPSTATbits.BF); // wait for data buffer[2] = SSPBUF; // and get it SSPCON2bits.ACKEN = 1; // start acknowledge sequence while(SSPCON2bits.ACKEN); // wait for ack. sequence to end SSPCON2bits.RCEN = 1; // start receiving while(!SSPSTATbits.BF); // wait for data buffer[3] = SSPBUF; // and get it SSPCON2bits.ACKDT = 1; // not acknowledge for last byte SSPCON2bits.ACKEN = 1; // start acknowledge sequence while(SSPCON2bits.ACKEN); // wait for ack. sequence to end SSPCON2bits.PEN = 1; // send stop bit while(SSPCON2bits.PEN); // } void setup(void) { char x; TRISC = 0x18; // RC3-4 are inputs SSPSTAT = 0x80; // slew rate disabled for Standard Speed mode (100 kHz and 1 MHz) SSPCON1 = 0x38; // I2C Master mode, clock = FOSC / (4 * (SSPADD+1)) SSPCON2 = 0x00; // not a lot SSPADD = 19; // baud rate in address reg 100k in 8Mhz, clock = Fosc/(4*(SSPADD+1)) x = SSPBUF; // dummy read clears BF }