//////////////////////////////////////////////////////////////////////////////// // // PIC16F877 + CMPS03 + LCD03 example // Written October 2005 by Gerald Coe, using HITECH PIC16 compiler // // Displays compass bearing on the LCD03 // Note - assumes a 20MHz crystal // // This code is Freeware - Use it for any purpose you like. // /////////////////////////////////////////////////////////////////////////////// #include #include __CONFIG(0x3b32); // configuration register - see PIC data sheet for details #define CMPS03_ADDR 0xC0 // Factory supplied default address void clrscn(void); // prototypes void cursor(char pos); void print(char *p); void setup(void); unsigned int get_cmps03(void); char s[21]; // buffer used to hold text to print void main(void) { unsigned int bearing; setup(); // sets up the PIC16F877 I2C port clrscn(); // clears the LCD03 disply cursor(2); // sets cursor to 1st row of LCD03 sprintf(s,"CMPS03 Compass Test"); // text, printed into our buffer print(s); // send it to the LCD03 while(1) { // loop forever bearing = get_cmps03(); // get bearing from cmps03 (round trip flight time in 1uS units) cursor(24); // sets cursor to 2nd row of LCD03 sprintf(s,"Bearing = %d.%d ", bearing/10, bearing%10); print(s); // send it to the LCD03 TMR1H = 0; // 52mS delay - this is so that the SRF04 ranging is not too rapid TMR1L = 0; // and the previous pulse has faded away before we start the next one T1CON = 0x31; // 1:8 prescale and running TMR1IF = 0; while(!TMR1IF); // wait for delay time TMR1ON = 0; // stop timer } } unsigned int get_cmps03(void) { unsigned int bearing; SEN = 1; // send start bit while(SEN); // and wait for it to clear ACKDT = 0; // acknowledge bit SSPIF = 0; SSPBUF = CMPS03_ADDR; // cmps03 I2C address while(!SSPIF); // wait for interrupt SSPIF = 0; // then clear it. SSPBUF = 2; // address of register to read from - high byte of result while(!SSPIF); // SSPIF = 0; // RSEN = 1; // send repeated start bit while(RSEN); // and wait for it to clear SSPIF = 0; // SSPBUF = CMPS03_ADDR+1; // cmps03 I2C address - with read bit set while(!SSPIF); // wait for interrupt SSPIF = 0; // then clear it. RCEN = 1; // start receiving while(!STAT_BF); // wait for high byte of bearing bearing = SSPBUF<<8; // and get it ACKEN = 1; // start acknowledge sequence while(ACKEN); // wait for ack. sequence to end RCEN = 1; // start receiving while(!STAT_BF); // wait for low byte of bearing bearing += SSPBUF; // and get it ACKDT = 1; // not acknowledge for last byte ACKEN = 1; // start acknowledge sequence while(ACKEN); // wait for ack. sequence to end PEN = 1; // send stop bit while(PEN); // return bearing; } void clrscn(void) { SEN = 1; // send start bit while(SEN); // and wait for it to clear SSPIF = 0; SSPBUF = 0xc6; // LCD02 I2C address while(!SSPIF); // wait for interrupt SSPIF = 0; // then clear it. SSPBUF = 0; // address of register to write to while(!SSPIF); // SSPIF = 0; // SSPBUF = 12; // clear screen while(!SSPIF); // SSPIF = 0; // SSPBUF = 4; // cursor off while(!SSPIF); // SSPIF = 0; // PEN = 1; // send stop bit while(PEN); // } void cursor(char pos) { SEN = 1; // send start bit while(SEN); // and wait for it to clear SSPIF = 0; SSPBUF = 0xc6; // LCD02 I2C address while(!SSPIF); // wait for interrupt SSPIF = 0; // then clear it. SSPBUF = 0; // address of register to write to while(!SSPIF); // SSPIF = 0; // SSPBUF = 2; // set cursor while(!SSPIF); // SSPIF = 0; // SSPBUF = pos; // while(!SSPIF); // SSPIF = 0; // PEN = 1; // send stop bit while(PEN); // } void print(char *p) { SEN = 1; // send start bit while(SEN); // and wait for it to clear SSPIF = 0; SSPBUF = 0xc6; // LCD02 I2C address while(!SSPIF); // wait for interrupt SSPIF = 0; // then clear it. SSPBUF = 0; // address of register to write to while(!SSPIF); // SSPIF = 0; // while(*p) { SSPBUF = *p++; // write the data while(!SSPIF); // SSPIF = 0; // } PEN = 1; // send stop bit while(PEN); // } void setup(void) { unsigned long x; PORTB = 0xff; TRISB = 0xff; TRISC = 0xff; PORTC = 0xff; SSPSTAT = 0x80; SSPCON = 0x38; SSPCON2 = 0x00; SSPADD = 50; // SCL = 91khz with 20Mhz Osc for(x=0; x<300000L; x++); // wait for LCD03 to initialise }