|
|
View previous topic :: View next topic |
Author |
Message |
young
Joined: 24 Jun 2004 Posts: 285
|
wrong temperature reading |
Posted: Thu Jul 01, 2004 4:18 pm |
|
|
I am using the ds1820 sensor, my program just got wrong reading, what possiblly caused this error. temperature is always 15 or 10 . |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
DS1820 |
Posted: Thu Jul 01, 2004 4:32 pm |
|
|
Young,
You have posted on here enough to know now that you need to supply the code you are using if you want some kind of decent answer. I am not aware of anyone here who is a mind reader. |
|
|
Guest
|
code |
Posted: Fri Jul 02, 2004 5:58 am |
|
|
What I am using is exactly a copy from Jds-pic http://www.ccsinfo.com/forum/viewtopic.php?t=19520. This program is for ds1822, I did not make any change. except that #define one_wire_pin PIN_E2. I tried to make some change, but what ever I made, the result is same. I also run a sample file provided by the easyPIC2 company, it just out put 85 degree c. sorry about my ambiguous question. |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Fri Jul 02, 2004 6:43 am |
|
|
Can you read the serial number or use any other features of the chip? If you have a logic analyzer or storage scope you may be able to eavesdrop on the one-wire signal and see if valid data is leaving the ds1822. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
Guest
|
|
Posted: Fri Jul 02, 2004 7:43 am |
|
|
Hi SherpaDoug:
I do got the serial number as 000800576236. |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Fri Jul 02, 2004 1:35 pm |
|
|
Anonymous wrote: | Hi SherpaDoug:
I do got the serial number as 000800576236. |
Sounds reasonable. Do you get the same serial number each time? Can you change chips and get a different serial number? I am not familliar with the 1822. Is there any registers or RAM you can read & write? If that all works I would look for an analog problem. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
DS1822 |
Posted: Fri Jul 02, 2004 1:59 pm |
|
|
Again, without YOUR code we cannot tell a lot and we are guessing...
Are you setting it to 9, 10, 11 or 12 bit mode?
How you are handling the result after you get it from the device read routine?
Getting back the serial number consistantly indicates the device and comms are working properly which points back to your code as being the likely problem. |
|
|
Kenny
Joined: 07 Sep 2003 Posts: 173 Location: Australia
|
|
Posted: Fri Jul 02, 2004 3:02 pm |
|
|
The code is the same for either DS1822 or DS18x20. I have had it working with four DS1822 and two DS18B20 on the same bus. Also, in parasitic mode.
The other code you tried is working. 85 deg C is the default data in the temperature reg. To get the the temperature, a Convert command (0x44) has to be be sent to the device first, then there needs to be a delay of 750mS before reading the temperature.
Re 64 bit identifier, the family identifier should be there on the end - it's 22 for the DS1822 and 28 for the DS18B20 I think (I'm not a work now to check).
There's a lot of code on this forum, including some I posted not long ago.
It's just a simple test routine, not a final application.
http://www.ccsinfo.com/forum/viewtopic.php?t=19255&highlight= |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
Re: code |
Posted: Wed Jul 07, 2004 6:43 pm |
|
|
first you wrote:
Anonymous wrote: | I am using the ds1820 sensor, my program just got wrong reading, what possiblly caused this error. temperature is always 15 or 10. |
then you wrote:
did it occur to you to read the ds1820 datasheet and figure out the differences between it and the ds1822 that i posted the library for? that maybe, just maybe, the method i used to configure the temperature resolution for the (variable resolution) ds1822 was writing into RESERVED bits in scratchpad bytes 4 and 5 on the (fixed resolution) ds1820?
and maybe, just maybe, if that alone didn't hose it up, the fact that i read back that very same register after initiating the temperature measurement but prior to reading the result -- such that time spent waiting on the measurement is precalculated and thus minimized -- *might* not be a good strategy for the ds1820 since it has a fixed temperature resolution and a mandatory >500ms conversion time?
please RTFM/RTFDS before your next posting. if you don't read the component datasheets you'll have lots of frustatration with trial-and-error debugging. sp print out the datasheet, get out a colored pen, and mark up all of the important points. and i'll ask (again) that you post code with your questions rather than having folks guess at it.
jds-pic |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Thu Jul 08, 2004 6:05 am |
|
|
here is my testing file with a most recently modified onewire program, please check it out for me. thank you again for helping
#include <16F877A.h>
#use delay(clock=2000000)
#fuses HS, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT, NOLVP
#byte port_c=7
#define led1 PIN_C3
#define led2 PIN_C4
#define led3 PIN_D3
#define led4 PIN_D4
#include <lcd420_1.c>
#include <onewire.h>
int temperature;
float temper;
int loop;
void main()
{
lcd_init();
set_tris_c(0x00);
//port_c=0;
printf(lcd_putc," ");
lcd_gotoxy(1,1);
printf(lcd_putc,"* Temperature *");
//printf(__DATE__);
do{
if(onewire_init_with_error_check())
{
onewire_ds1822_set_temperature_resolution(9);
temperature=onewire_ds1822_read_temp_c_lite();
temper=(float)temperature;
LCD_gotoxy(1,2);
printf(lcd_putc,"Temp=%5.2f%1cC", temper,0xdf);
// printf(lcd_putc,"Widge/Ver%04Lx",(int16)FW_VERSION);
// printf(lcd_putc,"S ");
// for(loop=6;loop>=1;loop--)
// printf(lcd_putc,"%x",onewire_ds1822_read_rom(loop));
}
else
{
LCD_gotoxy(1,2);
printf(lcd_putc,"No Temp Sensor!!");
}
output_low(led4);
output_high(led1);
delay_ms(40);
output_low(led1);
output_high(led2);
delay_ms(40);
output_low(led2);
output_high(led3);
delay_ms(40);
output_low(led3);
output_high(led4);
delay_ms(40);
}while(1);
}
following is /* onewire.h file */
// onewire library, for dallas onewire devices
// currently includes:
// - generic onewire functions (init, readbyte, sendbyte, crc, etc.)
// - ds1822 dallas-semi econo-thermometer
// (C) copyright 2003 j.d.sandoz / jds-pic !at! losdos.dyndns.org
// released under the GNU GENERAL PUBLIC LICENSE (GPL)
// refer to http://www.gnu.org/licenses/gpl.txt
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
/******* define one wire pin ********/
#define one_wire_pin PIN_E2
// ds1822 scratchpad registers
#define DS1822_SP_TLSB 0
#define DS1822_SP_TMSB 1
#define DS1822_SP_HLIM 2
#define DS1822_SP_LLIM 3
/* marked by young #define DS1822_SP_CFG 4
#define DS1822_SP_RES0 5
#define DS1822_SP_RES1 6
#define DS1822_SP_RES2 7 */
#define DS1822_SP_RES0 4
#define DS1822_SP_RES1 5
#define DS1822_SP_CREM 6
#define DS1822_SP_CPER 7
#define DS1822_SP_CRC 8
// ds1822 rom registers
#define DS1822_ROM_DEVTYPE 0
#define DS1822_ROM_SERIAL1 1
#define DS1822_ROM_SERIAL2 2
#define DS1822_ROM_SERIAL3 3
#define DS1822_ROM_SERIAL4 4
#define DS1822_ROM_SERIAL5 5
#define DS1822_ROM_SERIAL6 6
#define DS1822_ROM_CRC 7
// ds1822 command set
#define DS1822_CMD_READROM 0x33
#define DS1822_CMD_SKIPROM 0xCC
#define DS1822_CMD_CONVERTTEMP 0x44
#define DS1822_CMD_WRITESCRATCHPAD 0x4E
#define DS1822_CMD_READSCRATCHPAD 0xBE
#define DS1822_CMD_COPYSCRATCHPAD 0x48
// note that not all applications need to disable interrupts when
// performing onewire transactions. but, if unmasked interrupts
// cause onewire timing violations, returned data will be suspect
// or there may be other, hard-to-reproduce problems.
void onewire_disable_interrupts(int disable) {
if (disable)
disable_interrupts(GLOBAL);
else
enable_interrupts(GLOBAL);
}
short int onewire_init_with_error_check() {
onewire_disable_interrupts(TRUE);
output_low(ONE_WIRE_PIN);
delay_us( 500 ); // pull 1-wire low for reset pulse
output_float(ONE_WIRE_PIN); // float 1-wire high
delay_us( 5 ); // allow pin to stabilize
if (!input(ONE_WIRE_PIN)) {
onewire_disable_interrupts(FALSE);
return ( FALSE ); // error (1-wire leads shorted)
}
delay_us( 80 ); // wait for presence pulse, allowing for device variation
if (input(ONE_WIRE_PIN)) {
onewire_disable_interrupts(FALSE);
return ( FALSE ); // error (no 1-wire devices present)
}
delay_us( 420 ); // wait-out remaining initialisation window.
output_float(ONE_WIRE_PIN);
//printf(debug_putc,"<>ok >onewire_init\n\r");
onewire_disable_interrupts(FALSE);
return ( TRUE ); // device(s) present and initialised.
}
void onewire_init() { // OK if just using a single permanently connected device
onewire_disable_interrupts(TRUE);
output_low(ONE_WIRE_PIN);
delay_us( 500 ); // pull 1-wire low for reset pulse
output_float(ONE_WIRE_PIN); // float 1-wire high
delay_us( 80 ); // wait for presence pulse, allowing for device variation
delay_us( 420 ); // wait-out remaining initialisation window.
output_float(ONE_WIRE_PIN);
onewire_disable_interrupts(FALSE);
}
void onewire_sendbyte(int data) {
int count;
//static int debugS;
//printf(debug_putc,"0x%x >onewire_sendbyte(%u)\n\r",data,debugS++);
onewire_disable_interrupts(TRUE);
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_disable_interrupts(FALSE);
}
int onewire_readbyte() {
int count, data;
//static int debugR;
onewire_disable_interrupts(TRUE);
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.
}
//printf(debug_putc,"0x%x >onewire_readbyte(%u)\n\r",data,debugR++);
onewire_disable_interrupts(FALSE);
return( data );
}
int onewire_ds1822_read_scratchpad(int field) { /* returns config bitfield */
int data[9];
onewire_init();
onewire_sendbyte(DS1822_CMD_SKIPROM);
onewire_sendbyte(DS1822_CMD_READSCRATCHPAD);
data[DS1822_SP_TLSB]=onewire_readbyte(); // 0 Tlsb
data[DS1822_SP_TMSB]=onewire_readbyte(); // 1 Tmsb
data[DS1822_SP_HLIM]=onewire_readbyte(); // 2 Thlim
data[DS1822_SP_LLIM]=onewire_readbyte(); // 3 Tllim
/* data[DS1822_SP_CFG]=onewire_readbyte(); // 4 Config
data[DS1822_SP_RES0]=onewire_readbyte(); // 5 RES0
data[DS1822_SP_RES1]=onewire_readbyte(); // 6 RES1
data[DS1822_SP_RES2]=onewire_readbyte(); // 7 RES2 */
data[DS1822_SP_RES0]=onewire_readbyte(); // 4 RES0
data[DS1822_SP_RES1]=onewire_readbyte(); // 5 RES1
data[DS1822_SP_CREM]=onewire_readbyte(); // 6 RES0
data[DS1822_SP_CPER]=onewire_readbyte(); // 7 RES1
data[DS1822_SP_CRC]=onewire_readbyte(); // 8 CRC
if (field > 8) {
//printf(debug_putc,"ERR! >scratchpad field 0x%x out of range (ds1822)\n\r",field);
return(0);
}
else {
//printf(debug_putc,"0x%x >scratchpad field 0x%x (ds1822)\n\r",data[field],field);
return(data[field]);
}
}
int onewire_ds1822_read_rom(int field) { /* rtns ROM info, one byte at a time */
int data[8];
if (!onewire_init_with_error_check())
return (0);
onewire_sendbyte(DS1822_CMD_READROM);
data[DS1822_ROM_DEVTYPE]=onewire_readbyte(); // 0 family code
data[DS1822_ROM_SERIAL1]=onewire_readbyte(); // 1 serial number LSB
data[DS1822_ROM_SERIAL2]=onewire_readbyte(); // 2 serial number
data[DS1822_ROM_SERIAL3]=onewire_readbyte(); // 3 serial number
data[DS1822_ROM_SERIAL4]=onewire_readbyte(); // 4 serial number
data[DS1822_ROM_SERIAL5]=onewire_readbyte(); // 5 serial number
data[DS1822_ROM_SERIAL6]=onewire_readbyte(); // 6 serial number MSB
data[DS1822_ROM_CRC]=onewire_readbyte(); // 7 CRC
if (field > 7) {
//printf(debug_putc,"ERR! >rom field 0x%x out of range (ds1822)\n\r",field);
return(0);
}
else {
//printf(debug_putc,"0x%x >rom field 0x%x (ds1822)\n\r",data[field],field);
return(data[field]);
}
}
the following is the lcd420_1.c program
///////////////////////////////////////////////////////////////////////////
//// LCD420.C ////
//// Driver for common 4x20 LCD modules ////
//// ////
//// lcd_init() Must be called before any other function. ////
//// ////
//// lcd_putc(c) Will display c on the next position of the LCD. ////
//// The following have special meaning: ////
//// \f Clear display ////
//// \n Go to start of second line ////
//// \b Move back one position ////
//// ////
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) ////
//// ////
//// lcd_getc(x,y) Returns character at position x,y on LCD ////
//// ////
////////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,1997 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
////////////////////////////////////////////////////////////////////////////
// As defined in the following structure the pin connection is as follows:
// B0 enable //provided by Microchip
// B1 rs
// B2 rw
// B4 D4
// B5 D5
// B6 D6
// B7 D7
//
// LCD pins D0-D3 are not used and PIC B3 is not used.
//Provided
// As defined in the following structure the pin connection is as follows:
// //provided by Microchip
// B2 rs
// B3 enable
// B4 D4
// B5 D5
// B6 D6
// B7 D7
//
// LCD pins D0-D3 are not used and PIC B3 is not used.
struct lcd_pin_map { // This structure is overlayed
BOOLEAN unused0; // on to an I/O port to gain
BOOLEAN rw; // access to the LCD pins.
BOOLEAN rs; // The bits are allocated from
BOOLEAN enable; // low order up. ENABLE will
int data : 4; // be pin B0.
} lcd;
#byte lcd = 6 // This puts the entire structure
// on to port B (at address 6)
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
BYTE lcdline;
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_b(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_b(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
set_tris_b(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0, LCD_INIT_STRING[i]);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
switch(y) {
case 1 : address=0x80;break;
case 2 : address=0xc0;break;
case 3 : address=0x94;break;
case 4 : address=0xd4;break;
}
address+=x-1;
lcd_send_byte(0,address);
}
void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
lcdline=1;
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,++lcdline); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
} |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
Posted: Thu Jul 08, 2004 6:44 am |
|
|
(1)
you missed cutting and pasting some code, e.g. what happened to the definitions of
onewire_ds1822_set_temperature_resolution()
and
onewire_ds1822_read_temp_c_lite() ??????????????
ya think these might be important?
(2)
please learn to use the "Code" button which is located above the composition window. it sets off your code and uses a fixed width font, both of which make it easier to view and debug your code with. just press the "Code" button once, then paste in your code, then press the "Code" button again to close up the block. the results look like, for example,
Code: | #include <16F877A.h>
#use delay(clock=2000000)
#fuses HS, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT, NOLVP
|
(3)
please post or otherwise document the output of your code; this aids greatly in debugging.
jds-pic |
|
|
Jerry I
Joined: 14 Sep 2003 Posts: 96 Location: Toronto, Ontario, Canada
|
Re: code |
Posted: Thu Jul 08, 2004 6:46 am |
|
|
I have used both these chips ds18s20 and ds1822.
The code was not the same. Take a look at data sheet. The digital output value is different for temperature change.
Thake a look at the chart.
Anonymous wrote: | What I am using is exactly a copy from Jds-pic http://www.ccsinfo.com/forum/viewtopic.php?t=19520. This program is for ds1822, I did not make any change. except that #define one_wire_pin PIN_E2. I tried to make some change, but what ever I made, the result is same. I also run a sample file provided by the easyPIC2 company, it just out put 85 degree c. sorry about my ambiguous question. |
|
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
Posted: Thu Jul 08, 2004 6:50 am |
|
|
but i can see one problem with your code right off the bat.
in the original driver itself,
Code: | config=((onewire_ds1822_read_scratchpad(DS1822_SP_CFG) && 0b01100000)>>5);
// each addn'l resolution bit needs twice the base conversion time!
if (!onewire_init_with_error_check())
return (0);
onewire_sendbyte(DS1822_CMD_SKIPROM);
onewire_sendbyte(DS1822_CMD_CONVERTTEMP);
delaymult=1<<config;
//printf(debug_putc,"0x%x >delay_mult (ds1822)\n\r",delaymult);
while (delaymult--)
delay_ms(100); // allow worst case time for temp. conversion.
|
now that you have commented out the code for retrieving DS1822_SP_CFG (see your posted code above) it's probably the case (as was alluded to previously by another poster and me) that your PIC is not waiting sufficient time to allow the DS1820 to complete the temperature measurement.
instead, simplify and in place of the entire block above, use:
Code: |
if (!onewire_init_with_error_check())
return (0);
onewire_sendbyte(DS1822_CMD_SKIPROM);
onewire_sendbyte(DS1822_CMD_CONVERTTEMP);
delay_ms(500); // allow worst case time for DS1820 temp. conversion.
|
jds-pic
ps
don't even think of posting "that didn't work, any more suggestions?" without attaching your complete modified driver and the output of your program. |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Thu Jul 08, 2004 7:22 am |
|
|
Thank you guys, I am a newbie for this forum and for PIC. I am learning from your response. |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Thu Jul 08, 2004 8:14 am |
|
|
Here is the code that I modified:
Code: |
// onewire library, for dallas onewire devices
// currently includes:
// - generic onewire functions (init, readbyte, sendbyte, crc, etc.)
// - ds1822 dallas-semi econo-thermometer
// (C) copyright 2003 j.d.sandoz / jds-pic !at! losdos.dyndns.org
// released under the GNU GENERAL PUBLIC LICENSE (GPL)
// refer to http://www.gnu.org/licenses/gpl.txt
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
/******* define one wire pin ********/
#define one_wire_pin PIN_E2
// ds1822 scratchpad registers
#define DS1822_SP_TLSB 0
#define DS1822_SP_TMSB 1
#define DS1822_SP_HLIM 2
#define DS1822_SP_LLIM 3
/* marked by young #define DS1822_SP_CFG 4
#define DS1822_SP_RES0 5
#define DS1822_SP_RES1 6
#define DS1822_SP_RES2 7 */
#define DS1822_SP_RES0 4
#define DS1822_SP_RES1 5
#define DS1822_SP_CREM 6
#define DS1822_SP_CPER 7
#define DS1822_SP_CRC 8
// ds1822 rom registers
#define DS1822_ROM_DEVTYPE 0
#define DS1822_ROM_SERIAL1 1
#define DS1822_ROM_SERIAL2 2
#define DS1822_ROM_SERIAL3 3
#define DS1822_ROM_SERIAL4 4
#define DS1822_ROM_SERIAL5 5
#define DS1822_ROM_SERIAL6 6
#define DS1822_ROM_CRC 7
// ds1822 command set
#define DS1822_CMD_READROM 0x33
#define DS1822_CMD_SKIPROM 0xCC
#define DS1822_CMD_CONVERTTEMP 0x44
#define DS1822_CMD_WRITESCRATCHPAD 0x4E
#define DS1822_CMD_READSCRATCHPAD 0xBE
#define DS1822_CMD_COPYSCRATCHPAD 0x48
// note that not all applications need to disable interrupts when
// performing onewire transactions. but, if unmasked interrupts
// cause onewire timing violations, returned data will be suspect
// or there may be other, hard-to-reproduce problems.
void onewire_disable_interrupts(int disable) {
if (disable)
disable_interrupts(GLOBAL);
else
enable_interrupts(GLOBAL);
}
short int onewire_init_with_error_check() {
onewire_disable_interrupts(TRUE);
output_low(ONE_WIRE_PIN);
delay_us( 500 ); // pull 1-wire low for reset pulse
output_float(ONE_WIRE_PIN); // float 1-wire high
delay_us( 5 ); // allow pin to stabilize
if (!input(ONE_WIRE_PIN)) {
onewire_disable_interrupts(FALSE);
return ( FALSE ); // error (1-wire leads shorted)
}
delay_us( 80 ); // wait for presence pulse, allowing for device variation
if (input(ONE_WIRE_PIN)) {
onewire_disable_interrupts(FALSE);
return ( FALSE ); // error (no 1-wire devices present)
}
delay_us( 420 ); // wait-out remaining initialisation window.
output_float(ONE_WIRE_PIN);
//printf(debug_putc,"<>ok >onewire_init\n\r");
onewire_disable_interrupts(FALSE);
return ( TRUE ); // device(s) present and initialised.
}
void onewire_init() { // OK if just using a single permanently connected device
onewire_disable_interrupts(TRUE);
output_low(ONE_WIRE_PIN);
delay_us( 500 ); // pull 1-wire low for reset pulse
output_float(ONE_WIRE_PIN); // float 1-wire high
delay_us( 80 ); // wait for presence pulse, allowing for device variation
delay_us( 420 ); // wait-out remaining initialisation window.
output_float(ONE_WIRE_PIN);
onewire_disable_interrupts(FALSE);
}
void onewire_sendbyte(int data) {
int count;
//static int debugS;
//printf(debug_putc,"0x%x >onewire_sendbyte(%u)\n\r",data,debugS++);
onewire_disable_interrupts(TRUE);
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_disable_interrupts(FALSE);
}
int onewire_readbyte() {
int count, data;
//static int debugR;
onewire_disable_interrupts(TRUE);
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.
}
//printf(debug_putc,"0x%x >onewire_readbyte(%u)\n\r",data,debugR++);
onewire_disable_interrupts(FALSE);
return( data );
}
int onewire_ds1822_read_scratchpad(int field) { /* returns config bitfield */
int data[9];
onewire_init();
onewire_sendbyte(DS1822_CMD_SKIPROM);
onewire_sendbyte(DS1822_CMD_READSCRATCHPAD);
data[DS1822_SP_TLSB]=onewire_readbyte(); // 0 Tlsb
data[DS1822_SP_TMSB]=onewire_readbyte(); // 1 Tmsb
data[DS1822_SP_HLIM]=onewire_readbyte(); // 2 Thlim
data[DS1822_SP_LLIM]=onewire_readbyte(); // 3 Tllim
/* data[DS1822_SP_CFG]=onewire_readbyte(); // 4 Config
data[DS1822_SP_RES0]=onewire_readbyte(); // 5 RES0
data[DS1822_SP_RES1]=onewire_readbyte(); // 6 RES1
data[DS1822_SP_RES2]=onewire_readbyte(); // 7 RES2 */
data[DS1822_SP_RES0]=onewire_readbyte(); // 4 RES0
data[DS1822_SP_RES1]=onewire_readbyte(); // 5 RES1
data[DS1822_SP_CREM]=onewire_readbyte(); // 6 RES0
data[DS1822_SP_CPER]=onewire_readbyte(); // 7 RES1
data[DS1822_SP_CRC]=onewire_readbyte(); // 8 CRC
if (field > 8) {
//printf(debug_putc,"ERR! >scratchpad field 0x%x out of range (ds1822)\n\r",field);
return(0);
}
else {
//printf(debug_putc,"0x%x >scratchpad field 0x%x (ds1822)\n\r",data[field],field);
return(data[field]);
}
}
int onewire_ds1822_read_rom(int field) { /* rtns ROM info, one byte at a time */
int data[8];
if (!onewire_init_with_error_check())
return (0);
onewire_sendbyte(DS1822_CMD_READROM);
data[DS1822_ROM_DEVTYPE]=onewire_readbyte(); // 0 family code
data[DS1822_ROM_SERIAL1]=onewire_readbyte(); // 1 serial number LSB
data[DS1822_ROM_SERIAL2]=onewire_readbyte(); // 2 serial number
data[DS1822_ROM_SERIAL3]=onewire_readbyte(); // 3 serial number
data[DS1822_ROM_SERIAL4]=onewire_readbyte(); // 4 serial number
data[DS1822_ROM_SERIAL5]=onewire_readbyte(); // 5 serial number
data[DS1822_ROM_SERIAL6]=onewire_readbyte(); // 6 serial number MSB
data[DS1822_ROM_CRC]=onewire_readbyte(); // 7 CRC
if (field > 7) {
//printf(debug_putc,"ERR! >rom field 0x%x out of range (ds1822)\n\r",field);
return(0);
}
else {
//printf(debug_putc,"0x%x >rom field 0x%x (ds1822)\n\r",data[field],field);
return(data[field]);
}
}
int onewire_crc(int oldcrc, int newbyte) {
// see http://pdfserv.maxim-ic.com/arpdf/AppNotes/app27.pdf
int shift_reg, data_bit, sr_lsb, fb_bit, j;
shift_reg=oldcrc;
for(j=0; j<8; j++) { // for each bit
data_bit = (newbyte >> j) & 0x01;
sr_lsb = shift_reg & 0x01;
fb_bit = (data_bit ^ sr_lsb) & 0x01;
shift_reg = shift_reg >> 1;
if (fb_bit)
shift_reg = shift_reg ^ 0x8c;
}
return(shift_reg);
}
int onewire_ds1822_set_temperature_resolution(int resolution) { /* set up for nbit resolution */
int resolution_cfgfield;
if ((resolution < 9) || (resolution > 12))
resolution=9;
resolution_cfgfield=((resolution-9)<<5); // see DS1822 datasheet page 7
if (!onewire_init_with_error_check())
return (0);
onewire_sendbyte(DS1822_CMD_SKIPROM);
onewire_sendbyte(DS1822_CMD_WRITESCRATCHPAD);
onewire_sendbyte(0b01111101); // set max TH threshold (125'C)
onewire_sendbyte(0b11001001); // set min TL threshold (-55'C)
//marked by young onewire_sendbyte(resolution_cfgfield); // Temp resolution, set to nbit
onewire_init(); // reset
onewire_sendbyte(DS1822_CMD_SKIPROM);
onewire_sendbyte(DS1822_CMD_COPYSCRATCHPAD);
delay_ms(15); // allow time for flash memory write.
return( (onewire_ds1822_read_scratchpad(DS1822_SP_CFG) & 0b01100000)>>5 ); //something is wrong here there is not ds1822_SP_CFG), but it does not matter to the system, right?
}
int onewire_ds1822_read_temp_c_lite() { /* 0 to 125'C byte rtnd, nonparasitic mode */
int temperatureLSB, temperatureMSB, config, delaymult;
if (!onewire_init_with_error_check())
return (0);
onewire_sendbyte(DS1822_CMD_SKIPROM);
onewire_sendbyte(DS1822_CMD_CONVERTTEMP);
delay_ms(500); // allow worst case time for DS1820 temp. conversion.
// marked by young config=((onewire_ds1822_read_scratchpad(DS1822_SP_CFG) && 0b01100000)>>5);
// each addn'l resolution bit needs twice the base conversion time!
/* if (!onewire_init_with_error_check())
return (0);
onewire_sendbyte(DS1822_CMD_SKIPROM);
onewire_sendbyte(DS1822_CMD_CONVERTTEMP);
//marked by young delaymult=1<<config;
//printf(debug_putc,"0x%x >delay_mult (ds1822)\n\r",delaymult);
while (delaymult--)
delay_ms(100); // allow worst case time for temp. conversion.
*/
temperatureLSB = onewire_ds1822_read_scratchpad(DS1822_SP_TLSB);
temperatureMSB = onewire_ds1822_read_scratchpad(DS1822_SP_TMSB);
if (temperatureMSB & 0b11111000) // if temp is negative rtn 0
return(0);
else { // else rtn the positive temp
temperatureLSB=((temperatureLSB & 0b11110000)>>4);
temperatureMSB=((temperatureMSB & 0b00000111)<<4); //0b00000111
}
return(temperatureMSB | temperatureLSB); // OR msb&lsb
}
|
after I changed the program according to Jid-PIC's last posting, right now I got only 10 degree c reading, 15 degree c reading is gone. I read the datasheet many time, and compared 1820 and 1822, the above chnaging is what I can only find out |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|