ds75.c

Sample project for SX28 that reads the temperature of a component I2C, the DS75, and posts it on a LCD (by B. Billy).



/******************************************************************************
 This program is an example how to use the C2C-Pic-Compiler 

 Author: B. Billy  billytch@yahoo.fr
 Version 1.0
 Date: 25 jul 2003
 
 Required hardware: SX18-28 or 52 , a Dallas DS75 and a LCD-display
 Required files:   
                  - lcd_8.h   functions for lcd
                  
 Description:
 read the temperature from 2 (or more !) I2C device (here, dallas DS75) . The
 result is posted on LCD.
 **********************************************************************************/

#pragma TURBO_MODE 1
#pragma CLOCK_FREQ 4000000

//-------------------------------------------
// Hardware design
#define BP 3   //button for backlight ON/OFF
#define PORT_BP RA

//LCD DEFINE
#define LCDDATA RC
#define LCDCTL    RB
#define RS     5 
#define RW     6
#define E      7
#define BLIGHT 0

//I2C DEFINES
#define PORT_I2C RB 
#define SDA 3
#define SCL 4

//DS75 Adress
#define DS75_1 1
#define DS75_2 2
//-------------------------------------------

//Variables
char msb_temp=0; char lsb_temp=0;


//port direction (modified by i2c_out() and i2c_in() then DDRB is global)
char DDRA=8; //ra3 input (Button)
char DDRB=0;
char DDRC=0;

//lcd functions
#include "lcd_8.h"

void i2c_out (void) {
    set_mode(0x0F); //port direction
    clear_bit(DDRB,SDA);
    set_tris_b(DDRB); //SDA output
    delay_us(5);
}

void i2c_in (void) {
    set_mode(0x0F); //port direction
    set_bit(DDRB,SDA);
    set_tris_b(DDRB); //SDA input
    delay_us(5);
}

void i2c_go (void) {
   i2c_out();
   set_bit(PORT_I2C,SCL);
    set_bit(PORT_I2C,SDA);
    delay_us(55);
    clear_bit(PORT_I2C,SDA);
    delay_us(15);
    clear_bit(PORT_I2C,SCL);
    delay_us(15);
}

void i2c_stop (void) {
    i2c_out();
    set_bit(PORT_I2C,SCL);
    delay_us(25);
    set_bit(PORT_I2C,SDA);
    delay_us(15);
}

void write_i2c (char wr_byte) {
    char i=0;
    i2c_out();
    while(i++<8)    //1 OCTET
    {
        if (wr_byte & 0x80 )  set_bit(PORT_I2C,SDA);
        else clear_bit(PORT_I2C,SDA);

        wr_byte = wr_byte << 1;
        //clock
        set_bit(PORT_I2C,SCL);
        delay_us(15);
        clear_bit(PORT_I2C,SCL);
        delay_us(15);
     }
}

char read_i2c (void) {
    char i=0;
    char result=0;
    i2c_in();

    for(i=0;i<8;i++) {
        delay_us(15);
        set_bit(PORT_I2C,SCL);
        delay_us(15);

     if ( (PORT_I2C>>SDA) & 1) result = result+1; //test if PORT_IC2.SDA==1
        if (i<7) result = result << 1;

        delay_us(15);
        clear_bit(PORT_I2C,SCL);
    }
    return result;
}

void ack(void) {
   i2c_in();
   set_bit(PORT_I2C,SCL);
   delay_us(25);
   clear_bit(PORT_I2C,SCL);
   delay_us(15);
}

void mnack (void) {
   i2c_out();
   set_bit(PORT_I2C,SDA);
   delay_us(10);
   set_bit(PORT_I2C,SCL);
   delay_us(25);
   clear_bit(PORT_I2C,SCL);
   delay_us(15);
    clear_bit(PORT_I2C,SDA);
    delay_us(25);
}

void mack(void) {
   i2c_out();
   clear_bit(PORT_I2C,SDA);
   delay_us(15);
   set_bit(PORT_I2C,SCL);
   delay_us(45);
   clear_bit(PORT_I2C,SCL);
   delay_us(15);
}

//functions for DS75
void ds75_start(char adress) {
    //pointer on temperature reader
   i2c_go();
   write_i2c(10010000b | (adress<<1) );
   ack();
   write_i2c(0);
   ack();
   i2c_stop();
   delay_us(15);
}

void ds75_config(char adress, char data) {
    //pointer on configuration
   i2c_go();
   write_i2c(10010000b | (adress<<1) );
   ack();
   write_i2c(1); //config register
   ack();
    write_i2c(data);
    ack();
   i2c_stop();
   delay_us(10);
}

void read_temp_ds75(char adress) {
   i2c_go();
   write_i2c(10010001b | (adress<<1) );
   ack();
   msb_temp=read_i2c();

   mack();
   lsb_temp=read_i2c();
   mnack();
   i2c_stop();
}
char printf_temp_ds75() {
   char dix_byte;
   char unit_byte;

    if (lsb_temp>0xF0)  //error, DS75 is not connected
    {
        msb_temp='N';
        lsb_temp='C';
    return 0xFF;
    }

    if ( (msb_temp==0xFF) && (lsb_temp==0x00) ) //0°C too
    {
        msb_temp=0;
    }

    if (lsb_temp>0)
    {
     lsb_temp = (lsb_temp>>4);
    lsb_temp=((lsb_temp*6)/10);  //approximation of (lsb_temp*0.625)
   }

    dix_byte=msb_temp/10;  //ten
    unit_byte=msb_temp%10; //unit
    dix_byte=dix_byte+0x30;   //ten in ascii for LCD
    unit_byte=unit_byte+0x30; //unit in ascii for LCD

    lsb_temp=lsb_temp+0x30; //decimal in ascii

   put_lcd(dix_byte);
   put_lcd(unit_byte);
   printf_lcd(",");
   put_lcd(lsb_temp);

   put_lcd(11011111b); // ° for LCD
   printf_lcd("C");
   return 0;
}

void printf( const char* text )
{
    char i=0;
    while( text[i] != 0 ) putchar( text[i++] );
}

main()
{

    char LIGHT=0;

   //Hardware Initialization
    set_mode(0x0F);        //port_direction
   set_tris_a(DDRA);
    set_tris_b(DDRB);
    set_tris_c(DDRC);

    set_mode(0x0E);        //pull_up
   set_tris_b(11110111b); //pull_up sda
    set_tris_a(11110111b); //pull_up BP on RA3

    init_lcd();
    clr_lcd();
    home_lcd();


    while(1) {
        if (!( (PORT_BP>>BP) & 1))
            {
            delay_ms(250);
             if (!( (PORT_BP>>BP) & 1)) LIGHT = (LIGHT ^ 0xFF);
            }
        if (LIGHT)  set_bit(RB,BLIGHT);         //back light ON if light=0xFF
        else clear_bit(RB,BLIGHT);            //back light OFF 

        ds75_config(DS75_1,00100000b);  //configuration DS75 n°1 ; 11bit conversion
        ds75_start(DS75_1);            //start conversion
        ds75_config(DS75_2,00100000b);  //configuration DS75 n°1 ; 11bit conversion
        ds75_start(DS75_2);            //start conversion

        delay_s(1);
       home_lcd();

          read_temp_ds75(DS75_1); //result in msb_temp and lsb_temp
        printf_lcd("DS1:");
      printf_temp_ds75();

      lcd_line2();
          read_temp_ds75(DS75_2); //result in msb_temp and lsb_temp
        printf_lcd("DS2: ");
      printf_temp_ds75();
   }
}



http://www.sourceboost.com/home.html

Copyright © 2002-2006 SourceBoost Technologies