//////////////////////////////////////////////////////////////////////////////// // // PIC16F877 + SRF08 + LCD03 example // Written October 2005 by Gerald Coe, using HITECH PIC16 compiler // // Performs ranging using same I2C bus as the LCD03 is using // 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 SRF08_ADDR 0xE0 // Factory supplied default address void clrscn(void); // prototypes void cursor(char pos); void print(char *p); void setup(void); unsigned int get_srf08(void); char s[21]; // buffer used to hold text to print void main(void) { unsigned int range; setup(); // sets up the PIC16F877 I2C port clrscn(); // clears the LCD03 disply cursor(2); // sets cursor to 1st row of LCD03 sprintf(s,"SRF08 Ranger Test"); // text, printed into our buffer print(s); // send it to the LCD03 while(1) { // loop forever range = get_srf08(); // get range from srf08 (round trip flight time in 1uS units) cursor(24); // sets cursor to 2nd row of LCD03 sprintf(s,"Range = %dcm ", range/58); // convert to cm print(s); // send it to the LCD03 cursor(44); // sets cursor to 3rd row of LCD03 sprintf(s,"Range = %dinch ", range/148); // convert to inches print(s); // send it to the LCD03 } } unsigned int get_srf08(void) { unsigned int range; // This 1st part send the ranging command to the SRF08 to start it ranging SEN = 1; // send start bit while(SEN); // and wait for it to clear SSPIF = 0; SSPBUF = SRF08_ADDR; // SRF08 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 = 82; // range in uS command while(!SSPIF); // SSPIF = 0; // PEN = 1; // send stop bit while(PEN); // // now wait for the ranging to complete. This delay is a little over 100mS but // can be reduced to 66ms if required. TMR1H = 0; // delay while the srf08 is ranging TMR1L = 0; T1CON = 0x31; // 1:8 prescale and running (1.6uS/clk) TMR1IF = 0; while(!TMR1IF); // wait for delay time TMR1ON = 0; // stop timer // finally get the range from the SRF08 SEN = 1; // send start bit while(SEN); // and wait for it to clear ACKDT = 0; // acknowledge bit SSPIF = 0; SSPBUF = SRF08_ADDR; // SRF08 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 = SRF08_ADDR+1; // SRF08 I2C address - the read bit is set this time while(!SSPIF); // wait for interrupt SSPIF = 0; // then clear it. RCEN = 1; // start receiving while(!STAT_BF); // wait for high byte of range range = 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 range range += 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 range; } 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 = 0xfe; // RB0 (trig) is output TRISB = 0xfe; // and starts low 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 }