robert-gd
Newbie level 2
Hi I have a problem, I don't know how to set correctly timers and delays for this simple thermometr, when I set correct multiplex DS18b20 wouldn't read correctly temperature, when DS18b20 work good multiplexing is very bad :/
Code:
#include <16f84a.h>
#USE DELAY( CLOCK=4000000 ) /* Using a 4 Mhz clock */
#FUSES XT,NOWDT,NOPROTECT,NOPUT
/* Use XT mode, No Watch Dog, No Code Protect, No Power-up Timer */
#byte port_b=6 /* define the location of register port_b */
#byte port_a=5 /* define the location of register port_b */
#byte timer0low = 0xfd6
byte CONST LED_MAP[12] = {0x24,0xe7,0x4c,0x45,0x87,0x15,0x14,0x67,0x04,0x05,0xfb,0xdf};
byte CONST LED_POSITION[4] = {0x04,0x02,0x01,0x08};
unsigned int minus, less_than_one, single_number, tens;
/*
* One wire (1-wire) driver for CCS C compiler. Suitable for use with devices
* such as the DS18B20 1-wire digital temperature sensor.
*/
float value = 0.0;
float temp;
#define ONE_WIRE_PIN PIN_A4
/*
* onewire_reset()
* Description: Initiates the one wire bus.
*/
// OK if just using a single permanently connected device
void onewire_reset() {
output_low(ONE_WIRE_PIN); // pull the bus low for reset
delay_us(500);
output_float(ONE_WIRE_PIN); // float the bus high
delay_us(500); // wait-out remaining initialisation window
output_float(ONE_WIRE_PIN);
}
/*
* onewire_write(int8 data)
* Arguments: a byte of data.
* Description: writes a byte of data to the device.
*/
void onewire_write(int8 data) {
int8 count;
for(count = 0; count < 8; ++count) {
output_low(ONE_WIRE_PIN);
delay_us(2); // pull 1-wire low to initiate write time-slot.
output_bit(ONE_WIRE_PIN, shift_right(&data, 1, 0)); // set output bit on 1-wire
delay_us(60); // wait until end of write slot.
output_float(ONE_WIRE_PIN); // set 1-wire high again,
delay_us(2); // for more than 1us minimum.
}
}
/*
* onewire_read()
* Description: reads and returns a byte of data from the device.
*/
int onewire_read() {
int count, data;
for(count = 0; count < 8; ++count) {
output_low(ONE_WIRE_PIN);
delay_us(2); // pull 1-wire low to initiate read time-slot.
output_float(ONE_WIRE_PIN); // now let 1-wire float high,
delay_us(8); // let device state stabilise,
shift_right(&data, 1, input(ONE_WIRE_PIN)); // and load result.
delay_us(120); // wait until end of read slot.
}
return data;
}
/*
* ds1820_read()
* Description: reads the ds18x20 device on the 1-wire bus and returns
* the temperature
*/
float ds1820_read() {
int8 busy=0, temp1, temp2;
signed int16 temp3;
float result;
//ds1820_configure(0x00, 0x00, 0x00); //9 bit resolution
onewire_reset();
onewire_write(0xCC); //Skip ROM, address all devices
onewire_write(0x44); //Start temperature conversion
while(busy == 0) //Wait while busy (bus is low)
busy = onewire_read();
onewire_reset();
onewire_write(0xCC); //Skip ROM, address all devices
onewire_write(0xBE); //Read scratchpad
temp1 = onewire_read();
temp2 = onewire_read();
temp3 = make16(temp2, temp1);
//result = (float) temp3 / 2.0; //Calculation for DS18S20 with 0.5 deg C resolution
result = (float) temp3 / 16.0; //Calculation for DS18B20
delay_ms(200);
return(result);
}
/*
* ds1820_configure(int8 TH, int8 LH, int8 config)
* Description: writes configuration data to the DS18x20 device
* Arguments: alarm trigger high, alarm trigger low, configuration
*/
void ds1820_configure(int8 TH, int8 TL, int8 config) {
onewire_reset();
onewire_write(0xCC); //Skip ROM, address all devices
onewire_write(0x4E); //Write to scratchpad
onewire_write(TH);
onewire_write(TL);
onewire_write(config);
}
void show_xy(int position, int single_number)
{
port_a=LED_POSITION[position];
port_b=LED_MAP[single_number];
}
main(){
//setup_timer_0 ( RTCC_DIV_256 | RTCC_INTERNAL );
setup_timer_0 (RTCC_INTERNAL | RTCC_8_BIT | RTCC_DIV_256);
set_timer0 (0);
enable_interrupts (GLOBAL );
enable_interrupts (INT_TIMER0);
set_tris_b(0); /* set port_b as outputs */
set_tris_a(0); /* set port_a as output */
port_b = 0; /* ZERO port_a & port_b */
port_a = 0;
while(1)
{
value = ds1820_read();
if(value<0)
{
minus=0;
value=value*-1;
}
else minus=1;
single_number= (int)value%10;
tens=(int)value/10;
//temp=value-(int)value;
delay_ms(400);
}
}
#USE DELAY( CLOCK=4000000 )
#INT_TIMER0
void multiplexing_isr() {
if(minus!=1) {show_xy(3,11);}
delay_us(3210);
if(tens!=0) {show_xy(2,tens);}
delay_us(3210);
show_xy(1,single_number);
delay_us(3210);
show_xy(1,10);
delay_us(3210);
show_xy(0,less_than_one);
delay_us(3210);
}