PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > Các ngôn ngữ lập trình khác (CCS C, HT PIC,...)

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 13-01-2010, 09:15 PM   #1
motu
Đệ tử 4 túi
 
Tham gia ngày: Oct 2007
Bài gửi: 79
:
DS1820 khó quá....

Mình đang làm mạch để điều khiển nhiệt độ hồ cá, không có thời gian làm mạch in nên lấy con EasyPIC chơi luôn, nhưng ác cái là con EasyPIC xài cảm biến DS1820, con này giao tiếp 1-wire khó chơi quá (mình là gà mà), search tá lả trên mạng cuôí cùng viết đoạn code sau:
Code:
#include <16F877A.h> 
#device *=16 
#device adc=8 
#include <def_877a.h>

#FUSES NOWDT, HS, PUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT      
#use delay(clock=20000000) 
#include <1wire.c> 
#include <ds1820.c>
int8 x0,x1,x2,x3;
int hms[6];

void tachso(int16 x)
{
x0=x%10;            //chu so hang don vi
x1=((x-x0)/10)%10;         //chu so hang chuc
x2=((x-10*x1-x0)/100)%10;      //chu so hang tram
x3=((x-100*x2-10*x1-x0)/1000)%10;   //chu so hang nghin
}

int BCD(int data)
   {                                 
      int xx;                     
      switch (data)
         {
         case 0:
            xx=0xC0;
            break;
         case 1:
            xx=0xF9;
            break;
         case 2:
            xx=0xA4;
            break;
         case 3:
            xx=0xB0;
            break;
         case 4:
            xx=0x99;
            break;
         case 5:
            xx=0x92;
            break;
         case 6:
            xx=0x82;
            break;
         case 7:
            xx=0xF8;
            break;
         case 8:
            xx=0x80;
            break;
         case 9:
            xx=0x90;
            break;
         default:
            xx=0x7F;
         }
      return(xx);    
   } 
   
void showLed(int data[6])
{
   int k,j,t;
   k=1;
   for (j=0;j<6;j++)
   {  
      PORTA = ~k;
      switch (j)
         {
         case 1:
            t=BCD(data[j]) & 0x7F;
            break;
         case 3:
            t=BCD(data[j]) & 0x7F;
            break;
         default:
            t=BCD(data[j]);
         }   
      PORTB = t;
      delay_us(600);    
      k=k<<1;
   }
}

void xulidulieu(int16 dt)
   {
      tachso(dt);
      hms[0] = 0x00;
      hms[1] = 0x00;
      hms[2] = x0;
      hms[3] = x1;
      hms[4] = x2;
      hms[5] = x3;
    }  
                  
void main() 
{ 
   int16 tem; 
   trisc=0x00;
   portc=0x00;
   TRISB = 0x00;    
   TRISA = 0b00000000;
   PORTB = 0xFF;    
   PORTA = 0;   
   tem = (int16) ds1820_read();
   delay_ms(10);
while (1)
{ 
  tem = (int16) ds1820_read();
  delay_ms(10);
  xulidulieu(tem);
  showLed(hms);
}
}
1wire.c (chôm trên mạng)
Code:
// (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

/***********************1Wire Class***********************/
/*Description: This class handles all communication */
/* between the processor and the 1wire */
/* sensors.
/*********************************************************/

/*-------1-wire definitions-------*/
#define ONE_WIRE_PIN PIN_E2       //mình dùng EasyPIC, set chân E2 nên sửa code lại chỗ này, file mặc định là #define ONE_WIRE_PIN PIN_A5

/*******************1-wire communication functions********************/

/************onewire_reset*************************************************/
/*This function initiates the 1wire bus */
/* */
/*PARAMETERS: */
/*RETURNS: */
/*********************************************************************/

void onewire_reset()  // OK if just using a single permanently connected device
{
 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( 500 ); // wait-out remaining initialisation window.
 output_float(ONE_WIRE_PIN);
}

/*********************** onewire_write() ********************************/
/*This function writes a byte to the sensor.*/
/* */
/*Parameters: byte - the byte to be written to the 1-wire */
/*Returns: */
/*********************************************************************/

void onewire_write(int data)
{
 int 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.
 }
}

/*********************** read1wire() *********************************/
/*This function reads the 8 -bit data via the 1-wire sensor. */
/* */
/*Parameters: */
/*Returns: 8-bit (1-byte) data from sensor */
/*********************************************************************/

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.c (cái này cũng là tài sản trên internet - chưa có tiền trả bản quyền )
Code:
float ds1820_read()
{
 int8 busy=0, temp1, temp2;
 signed int16 temp3;
 float result;

 onewire_reset();
 onewire_write(0xCC);
 onewire_write(0x44);

 while (busy == 0)
  busy = onewire_read();

 onewire_reset();
 onewire_write(0xCC);
 onewire_write(0xBE);
 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 with 0.1 deg C resolution
 
 delay_ms(200);
 return(result);
}
Nạp vô EasyPIC hiện lên sáu số 0 tròn trĩnh, ai đã từng test thực tế con DS1820 có thể giải thích lỗi trong code của mình hoặc cho mình 1 đoạn code đầy đủ để thử con DS1820 khó tính này (mình sử dụng EasyPIC nên dùng chân RE1 hoặc RA5 cho 1wire)
THk mọi người! không được chắc đổi qua LM35 cho dễ chơi quá!
P/S: Mấy đoạn code show led của mình hơi gà mọi người đừng cười
motu vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 15-01-2010, 08:54 AM   #2
picpen
Đệ tử 5 túi
 
picpen's Avatar
 
Tham gia ngày: Jun 2008
Bài gửi: 112
:
Code:
/*-------1-wire definitions-------*/ 
#define ONE_WIRE_PIN PIN_E2

/*******************1-wire communication functions********************/ 

/************onewire_reset*************************************************/ 
/*This function initiates the 1wire bus */ 
/* */ 
/*PARAMETERS: */ 
/*RETURNS: */ 
/*********************************************************************/ 

void onewire_reset()  // OK if just using a single permanently connected device 
{ 
 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( 500 ); // wait-out remaining initialisation window. 
 output_float(ONE_WIRE_PIN); 
} 

/*********************** onewire_write() ********************************/ 
/*This function writes a byte to the sensor.*/ 
/* */ 
/*Parameters: byte - the byte to be written to the 1-wire */ 
/*Returns: */ 
/*********************************************************************/ 

void onewire_write(int data) 
{ 
 int 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. 
 } 
} 

/*********************** read1wire() *********************************/ 
/*This function reads the 8 -bit data via the 1-wire sensor. */ 
/* */ 
/*Parameters: */ 
/*Returns: 8-bit (1-byte) data from sensor */ 
/*********************************************************************/ 

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 ); 
} 


float ds1820_read()
{ 
 int8 busy=0, temp1, temp2; 
 signed int16 temp3; 
 float result; 

 onewire_reset(); 
 onewire_write(0xCC); 
 onewire_write(0x44); 

 while (busy == 0) 
  busy = onewire_read(); 

 onewire_reset(); 
 onewire_write(0xCC); 
 onewire_write(0xBE); 
 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 with 0.1 deg C resolution 
  
 delay_ms(200); 
 return(result); 
}
Chương trình này bạn nạp vào mạch của bạn là chạy ok ngay.

Bạn muốn giao tiếp với bất kỳ chân nào của chíp, chỉ cần cấu hình lại chân giao tiếp bằng dòng lệnh này: #define ONE_WIRE_PIN PIN_E2
__________________
** xin hãy cho tôi là tượng đá
** Để muôn đời không nhớ thương ai ..!!
picpen vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 16-01-2010, 05:18 PM   #3
motu
Đệ tử 4 túi
 
Tham gia ngày: Oct 2007
Bài gửi: 79
:
Thk bạn, để thử lại rồi báo cáo...
motu vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 17-01-2010, 11:29 AM   #4
motu
Đệ tử 4 túi
 
Tham gia ngày: Oct 2007
Bài gửi: 79
:
Vẫn chưa làm được, cho mình hỏi khi sử dụng thư viện trên và chọn chân RE2
#define ONE_WIRE_PIN PIN_E2
thì trong chương trình chính mình set port E như thể nào, là in hay out???
chân RE2 có cần kéo lên hay kéo xuống không??
kết quả trả về của hàm ds1820_read() là giá trị nhiệt độ, số thực hay số nguyên???
hình như mình chưa giao tiếp được 1wire nên toàn trả về số 0.

thay đổi nội dung bởi: motu, 17-01-2010 lúc 11:31 AM. Lý do: edit
motu vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 12-03-2010, 10:13 PM   #5
motu
Đệ tử 4 túi
 
Tham gia ngày: Oct 2007
Bài gửi: 79
:
Với sự giúp đỡ của bạn tmd đã giải quyết được vấn đề, giờ phải làm hồ cá thôi, mấy tháng nay bỏ bê tép chết quá trời. Thk bạn tmd!
motu vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-06-2010, 11:17 AM   #6
silvadk2
Đệ tử 2 túi
 
Tham gia ngày: Nov 2008
Bài gửi: 42
:
Mình cũng đang mắc ở con ds18b20 này mà chưa xử lý được. Đọc trao đổi của 2 bạn, thấy code của người góp ý và code của người hỏi ko khác gì nhau cả. Bạn Motu đã xử lý ntn vậy ? Mình mô phỏng nhưng giá trị nhiệt độ đọc được chỉ là 0.0 thôi, nghĩa là quá trình đọc từ ds18b20 chưa ổn.
silvadk2 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 02-11-2010, 12:37 AM   #7
akatsu
Đệ tử 2 túi
 
Tham gia ngày: Aug 2010
Bài gửi: 27
:
thử cái này của mình xem

mình đã test mạch easyPIC thấy chạy cũng ok...code này dùng để điều khiển nhiệt độ luôn 32 độ c...bạn xem thử rồi cho ý kiến nha.thân,mình còn làm rs232 nữa nếu bạn cần thì mình sẽ share code VB...chúc bạn nghiên cứu tốt
File Kèm Theo
File Type: rar DS1820_____RS232.rar (3.6 KB, 112 lần tải)
akatsu vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 13-03-2011, 03:29 PM   #8
motu
Đệ tử 4 túi
 
Tham gia ngày: Oct 2007
Bài gửi: 79
:
theo kinh nghiệm của e thì đa phần thực hành giao tiếp không được với con ds1820 là do set clock không đúng dẫn đến lệnh delay không cho thời gian chính xác, không đáp ứng yêu cầu về thời gian của con DS1820 --> kết quả toàn ra số 0.
#use delay(clock=4000000)
e không hiểu dòng lệnh trên có ý nghĩa gì, nhưng sử dụng với thạch anh 4MHz thì cho kết quả như ý muốn.
__________________
Dao nao cung la dao, dao cao dai cung la dao.
motu vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 21-04-2011, 08:32 AM   #9
zippro
Nhập môn đệ tử
 
Tham gia ngày: Mar 2011
Bài gửi: 2
:
bạn ơi cho mình hỏi dùng code

result = (float) temp3 / 2.0; //Calculation for DS18S20 with 0.5 deg C resolution
// result = (float) temp3 / 16.0; //Calculation for DS18B20 with 0.1 deg C resolution

có ý nghĩa là gì vậy bạn,bạn có thể giải thích rõ ràng được k?
thanks
zippro vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 03:43 PM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam