Xin giúp code cảm biến nhiệt độ DS18B20

cenakhoa

em thích màu hồng
sau đây là đoạn code cảm biến nhiệt độ em viết để làm bài giữa khóa, chân ra0 làm chân dq, build thành công ( tất nhiên là ko chạy ), sử dụng ds18b20 nguồn ngoài, mcu pic 16f887. mong mọi người vào thảo luận giúp đỡ em, em đã cố gắng ghi chú thích càng nhiều càng tốt :(

PHP:
#include <time.h>
#include <htc.h>
#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & SWBOREN & IESODIS & FCMDIS & LVPDIS & DEBUGDIS); //1st config. Word
__CONFIG(BORV21); //2st config. Word
#define _XTAL_FREQ 	4000000 //TAN SO THACH ANH
// CHAN DIEU KHIEN LA RA0


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

unsigned char temp,temp2,i,phay,d;
unsigned int data=0,j=0,n=0;

void ds1820_init(void);            //   VI CO QUA NHIEU HAM LONG VAO NHAU NEN CHUNG TA PHAI KHAI BAO TRUOOC
void write_byte(unsigned char d); //    DE TRANH XUNG DOT GIUA CAC HAM
void write0(void);
void write1(void);
void decode(void);
void read_byte(void);

void lcd_init();
unsigned char lcd_busy();
unsigned char lcd_get_byte(unsigned char rs);
void lcd_put_byte(unsigned char a,unsigned char b);
void lcd_gotoxy(unsigned char col, unsigned char row);
void lcd_putc(char c);
void lcd_puts(const char* s);
void lcd_clear();

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ds1820_init(void)  //   KHOI DONG CAM BIEN+SKIP ROM
{
					   	//chuong trinh khoi dong ds18s20
						//keo bus low >480us
						//release bus 15-60us
						//ds18s20 keo bus low 60-240us
TRISA0=0;
RA0=0;
__delay_ms(480);
RA0=1;
__delay_ms(70);
TRISA0=1;
while(RA0==1);
while(RA0==0);

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void write_byte(unsigned char d1)     //GHI 1 BYTE DU LIEU
{
										//;chuong trinh ghi bit vao ds18s20
										//;ghi tu LSB-MSB
										//;neu bus duoc giu o muc thap nhieu hon 480us --> reset
temp=d1; //BIEN TEMP LA GIA TRI DAU CUA TIN HIEU CAN GHI
for(i=0;i=7;i++)//LAP 8 LAN
{
d1=d1|(0b00000001<<i);    /// dung mask de lay bit thu i trong data
d1=d1>>i;

if (d1==1) 
{
write1();
d1=temp;// TRA D1 VE GIA TRI BAN DAU
}

else 
{
write0();
d1=temp;//TRA D1 VE GIA TRI BAN DAU
}

}

}


void write0(void)
{
//qua trinh ghi bit 0 vao ds1820: chan DQ o muc thap 120us sau do len muc cao

TRISA0=0;
RA0=0;
__delay_ms(120);
RA0=1;
}

void write1(void)
{
//qua trinh ghi bit 1 vao ds1820: chan dq o muc thap 1us; 
TRISA0=0;
RA0=0;
RA0=1;
__delay_ms(120);
RA0=1;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void decode(void)    /// GIAI MA TIN HIEU NHIET DO :">

{
phay=data|0x01;//GIAI MA NHIET DO CHINH XAC DEN 0.5 DO, NEU PHAY=1 THI TIN HIEU .5 DO
data>>1;
n=data;
while (data)
    {
        j++;// J LA SO CHU SO CAN HIEN THI
        data=data/10;
    }

for (i=1;i=j;i++)
{
lcd_put_byte(0,0b00011111); // DICH CON TRO LCD SANG PHAI J LAN
}

for (i=j;i>=1;i--)
    {
        lcd_putc(48+n%10);
		lcd_put_byte(0,0b00011011);//VIET NGUOC TU TRAI SANG PHAI GIA TRI NHIET DO
        n=n/10;
    }

for (i=0;i=j;i++)//  DICH CON TRO SANG PHAI J+1 LAN
{
lcd_put_byte(0,0b00011111);
}

if (phay==1) 
{
lcd_puts(".5");
}
else 
{
lcd_puts(".0");   
}

}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void read_byte(void) // DOC TIN HIEU NHIET DO TU LSB DEN MSB
						//;master keo bus low >1us xong release bus
						//;master phai lay mau bus <15us tu khi keo bus low
						//;delay them >45us
{

for(i=0;i=11;i++)// DOC VE 12 BIT GIA TRI NHIET DO TU LSB DEN MSB
{
TRISA0=0;
RA0=1;
RA0=0;
RA0=1;
__delay_ms(11);
TRISA0=1;
temp2=RA0<<i;
data=data|temp2;
__delay_ms(50);
}

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void main(void)
{
lcd_init();// KHOI DONG MAN HINH LCD
__delay_ms(200);


ds1820_init();//KHOI DONG CAM BIEN NHIET DO
d=0xcc;     // lenh SKIP ROM
write_byte(d);
d=0x4e;     // CONFIGURATION
write_byte(d);
d=0x00;     // CONFIGURATION TH
write_byte(d);
d=0x00;     // CONFIGURATION TL
write_byte(d);
d=0b01111111;     // CONFIGURATION BYTE
write_byte(d);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
while(1)
{
ds1820_init();//KHOI DONG CAM BIEN NHIET DO
d=0xcc;     // lenh SKIP ROM
write_byte(d);
d=0x44;
write_byte(d);//YEU CAU XU LI GIA TRI NHIET DO
__delay_ms(750);
ds1820_init(); //RESET CAM BIEN NHIET DO
d=0xcc;     // lenh SKIP ROM
write_byte(d);
d=0xbe;
write_byte(d);// YEU CAU READ SCRACPAD
read_byte();
data>>3;// VI DATA MAC DINH CO 12 BIT, CHUNG TA CHI SU DUNG 8 BIT
lcd_puts("NHIET DO PHONG LA: ");
decode();
}

}
 
Hồi xưa có viết qua cái này. Lúc đó xài đúng cái code của MCH build ra không chạy được vì hàm Wrapper nhiều làm tràn stack ( đoán vậy).
Sau đó anh đã thử viết lại các hàm đã wrap vào trong chương trình đọc chính cho cảm biến ( unwrap hàm đó mà) thì chạy ngon.
Bây giờ em có thể gọi các hàm wrapper dạng nội tuyến có thể tiết kiệm được stack ( __inline). Tùy trình dịch mà cái này có tác dụng hay không.
Nếu không thì em làm theo cách unwrap thông thường. Nói trước là lâu quá anh không nhớ rõ cách thức timing trong 1wire nữa cho nên ý kiến của anh chỉ có thể dùng được khi em đã làm đúng timing mà nó vẫn không chạy.
 

cenakhoa

em thích màu hồng
dạ, em sẽ coi lại, cám ơn anh, em sẽ sửa lại khi làm xong, có lẽ em hiểu nhầm code dịch lcd nên không hiển thị lên màn hình :(
 

cenakhoa

em thích màu hồng
hiện em đã làm được cảm biến ds18b20 rùi, xin cám ơn tất cả mọi người, bài của em sai 1 số lỗi như sau: một số chỗ quên release bus :P code dịch con trỏ lcd em viết nhầm thành code dịch màn hình lcd nên hiển thị bị sai

hiện tại thì đề tài cảm biến 1 dây của anh tùng có chú thích rất rõ ràng, dễ hiểu, em không có bổ xung j thêm

http://www.payitforward.edu.vn/4rum/showthread.php?92-Cảm-biến-nhiệt-độ-DS18B20-(Giao-tiếp-1-wire)-và-LM35-(ADC)-PIC16F887
 

cenakhoa

em thích màu hồng
Một lỗi nghiêm trọng mà em mới phát hiện ra là khi read từ ds18b20 thì phải read hết 8 byte dù muốn hay không, không thể read 2 byte nhiệt độ rồi ngưng :P
 

tungbk

Cố Vấn CLB
Staff member
Các giao tiếp I2C, SPI, CAN, Ethernet, 1-dây... luôn có 1 phần quan trọng là cách thức kết nối mạng gồm nhiều IC lại với nhau (mỗi IC có 1 ID riêng). Giải thuật dò ra ID của các IC 1 dây trên cùng 1 đường truyền nó gọi là "SEARCH ROM ALGORITHM". Phần này anh có làm rồi nhưng chưa đưa vào TUT nếu e muốn "vặt" tới cùng giao thức 1 dây này thì anh cho e mượn thêm 2 con DS18B20 nữa để thử và viết các hàm con để sau này dùng.
 

cenakhoa

em thích màu hồng
em hiện có 2 con DS18B20 rùi, cái này là mỗi con có 1 số rom riêng không trùng nhau phải không ạ, em có thấy trong code mẫu mà anh viết ??? để mai em thử xem sao, nếu bí em sẽ nhờ anh :P hjhj
 
Top