/******************************************************************************
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();
}
}
Copyright © 2002-2006 SourceBoost Technologies