Hướng dẫn đo nhiệt độ hiển thị lên LCD bằng DS18B20 và PIC16F887

khanhthan

Sinh viên đại học
#1
GIAO TIẾP VỚI DS18B20 DÙNG PIC16F887
Xin chào tất cả các bạn, hôm nay tôi sẽ chia sẽ với các bạn cách thức đo nhiệt độ dùng cảm biến nhiệt độ DS18B20 hiễn thị lên LCD16x02. Cảm biến này trả về giá trị nhiệt độ theo dạng số, có nghĩa là chúng ta không cần phải chuyển đổi ADC như con cảm biến LM35 mà chỉ cần đọc giá trị mà DS18B20 trả về rồi xuất ra LCD là xong. Để đọc được giá trị nhiệt độ mà cảm biến trả về, chúng ta dùng vi điều khiển (vđk) để giao tiếp với cảm biến theo chuẩn 1-dây (one-wire).
Đề tài này không còn gì là mới mẽ cả. Trước đây, khi tôi mới bắt đầu giao tiếp với con DS18B20 này cũng gặp không ít khó khăn, code trên mạng khá nhiều nhưng đều viết bằng CCS nên thực ra tôi đọc cũng không hiểu lắm. Bí quá tôi đành đọc datasheet, vì vốn tiếng anh hạn hẹp nên vừa đọc vừa tra từ thành ra hơi vất vã.
I.Đầu tiên, tôi xin nói về cảm biến DS18B20.
1.1.Vài lời về DS18B20
Theo như nguồn tin chính xác nhất là datasheet của nhà sản xuất thì trên mỗi con DS18B20 cómột mã định danh duy nhất 64 bit chứa trong bộ nhớ ROM trên chip (on chip), giá trị nhị phân được khắc bằng tia laze. Vì thế các bạn có thể dùng nhiều con cảm biến để đo nhiệt độ nhiều nơi và chỉ cần một con vđk để đọc nhiệt độ từng con là được. đối với bài này tôi chỉ dùng 1 con cảm biến nên cũng không cần quan tâm đến mã địa chỉ làm gì. Thêm một số thông tin từ datasheet để các bạn tham khảo:
• Sử dụng giao diện một dây nên chỉ cần có một chân ra để truyền thông.
• Có thể đo nhiệt độ trong khoảng -55 ÷ +125 oC.Với khoảng nhiệt độ là -10°C ÷ +85°C thì độ chính xác ±0.5°C.Có chức năng cảnh báo nhiệt độ vược qua giá trị cho trước.
• Điện áp sử dụng : 3 ÷ 5.5 V,có thể cấu hình mã hóa nhiệu độ từ 9 ÷ 12 bit số bit càng lớn thì độ chính xác cao hơn.Thời gian chuyển đổi nhiệt độ tối đa là 750ms cho mã hóa 12 bit
• Dòng tiêu thụ tại chế độ nghỉ cực nhỏ.
• Nếu cấu hình cho DS18B20 theo 9,10,11,12 bit thì ta có độ chính xác tương ứng là : 0.5°C , 0.25°C ,0.125°C, 0.0625°C.Theo mặc định của nhà sản xuất nếu chúng ta không cấu hình chế độ chuyển đổi thì nó sẽ tự cấu hình là 12 bit.
Cảm biến DS18b20 thường được sử dụng gồm có 3 chân: VCC, GND, DATA như hình dưới:
Trong đó:
  • Vdd là chân cấp nguồn từ 3 ÷ 5.5 VDC, thông thường là 5 VDC cùng nguồn với vđk.
  • GND là chân nối mass 0 VDC
  • DQ là chân tín hiệu, chân này nối với vđk để giao tiếp.
  • N.C là chân not connect có nghĩa là không kết nối, để trống.
1.2.Cách kết nối DS18B20 với vđk
Để cho cảm biến có thể làm việc thì chúng ta cần kết nối như sau, theo nhà sản xuất thì có 3 cách kết nối, các bạn xem hình:
Cách 1: cách này ít dùng
Cách 2: cách này hay dùng nhất.
Cách 3: cách này cũng ít dùng
1.3.Các tập lệnh của DS18B20
- READ ROM (33h)
Cho phép đọc ra 8 byte mã đã khắc bằng laser trên ROM, bao gồm: 8 bit mã định tên linh kiện (10h), 48 bit số xuất xưởng, 8 bit kiểm tra CRC. Lệnh này chỉ dùng khi trên bus có 1 cảm biến DS1820, nếu không sẽ xảy ra xung đột trên bus do tất cả các thiết bị tớ cùng đáp ứng.
- MATCH ROM (55h)
Lệnh này được gửi đi cùng với 64 bit ROM tiếp theo, cho phép bộ điều khiển bus chọn ra chỉ một cảm biến DS1820 cụ thể khi trên bus có nhiều cảm biến DS1820 cùng nối vào. Chỉ có DS1820 nào có 64 bit trên ROM trung khớp với chuỗi 64 bit vừa được gửi tới mới đáp ứng lại các lệnh về bộ nhớ tiếp theo. Còn các cảm biến DS1820 có 64 bit ROM không trùng khớp sẽ tiếp tục chờ một xung reset. Lệnh này được sử dụng cả trong trường hợp có một cảm biến một dây, cả trong trường hợp có nhiều cảm biến một dây.
- SKIP ROM (CCh)
Lệnh này cho phép thiết bị điều khiển truy nhập thẳng đến các lệnh bộ nhớ của DS1820 mà không cần gửi chuỗi mã 64 bit ROM. Như vậy sẽ tiết kiệm được thời gian chờ đợi nhưng chỉ mang hiệu quả khi trên bus chỉ có một cảm biến.
- SEARCH ROM (F0h)
Lệnh này cho phép bộ điều khiển bus có thể dò tìm được số lượng thành viên tớ đang được đấu vào bus và các giá trị cụ thể trong 64 bit ROM của chúng bằng một chu trình dò tìm.
- ALARM SEARCH (ECh)
Tiến trình của lệnh này giống hệt như lệnh Search ROM, nhưng cảm biến DS1820 chỉ đáp ứng lệnh này khi xuất hiện điều kiện cảnh báo trong phép đo nhiệt độ cuối cùng. Điều kiện cảnh báo ở đây được định nghĩa là giá trị nhiệt độ đo được lớn hơn giá trị TH và nhỏ hơn giá trị TL là hai giá trị nhiệt độ cao nhất và nhiệt độ thấp nhất đã được đặt trên thanh ghi trong bộ nhớ của cảm biến.
Sau khi thiết bị chủ (thường là một vi điều khiển) sử dụng các lệnh ROM để định địa chỉ cho các cảm biến một dây đang được đấu vào bus, thiết bị chủ sẽ đưa ra các lệnh chức năng DS1820. Bằng các lệnh chức năng thiết bị chủ có thể đọc ra và ghi vào bộ nhớ nháp (scratchpath) của cảm biến DS1820. khởi tạo quá trình chuyển đổi giá trị nhiệt độ đo được và xác định chế độ cung cấp điện áp nguồn. Các lệnh chức năng có thể được mô tả ngắn gọn như sau:
- WRITE SCRATCHPAD (4Eh)
Lệnh này cho phép ghi 2 byte dữ liệu vào bộ nhớ nháp của DS1820. Byte đầu tiên được ghi vào thanh ghi TH (byte 2 của bộ nhớ nháp) còn byte thứ hai được ghi vào thanh ghi TL (byte 3 của bộ nhớ nháp). Dữ liệu truyền theo trình tự đầu tiên là bit có ý nghĩa nhất và kế tiếp là những bit có ý nghĩa giảm dần. Cả hai byte này phải được ghi trước khi thiết bị chủ xuất ra một xung reset hoặc khi có dữ liệu khác xuất hiện.
- READ SCRATCHPAD (BEh)
Lệnh này cho phép thiết bị chủ đọc nội dung bộ nhớ nháp. Quá trình đọc bắt đầu từ bit có ý nghĩa nhấy của byte 0 và tiếp tục cho đến byte rhứ 9 (byte 8 – CRC). Thiết bị chủ có thể xuất ra một xung reset để làm dừng quá trình đọc bất kỳ lúc nào nếu như chỉ có một phần của dữ liệu trên bộ nhớ nháp cần được đọc.
- COPYSCRATCHPAD (48h)
Lệnh này copy nội dung của hai thanh ghi TH và TL (byte 2 và byte 3) vào bộ nhớ EEPROM. Nếu cảm biến được sử dụng trong chế dộ cấp nguồn l bắt đầu việc đo.
- CONVERT T (44h)
Lệnh này khởi động một quá trình đo và chuyển đổi giá trị nhiệt độ thành số (nhị phân). Sau khi chuyển đổi giá trị kết quả đo nhiệt độ được lưu trữ trên thanh ghi nhiệt độ 2 byte trong bộ nhớ nháp Thời gian chuyển đổi không quá 200 ms, trong thời gian đang chuyển đổi nếu thực hiện lệnh đọc thì các giá trị đọc ra đều bằng 0.
- READ POWER SUPPLY (B4h)
Một lệnh đọc tiếp sau lệnh này sẽ cho biết DS1820 đang sử dụng chế độ cấp nguồn như thế nào, giá trị đọc được bằng 0 nếu cấp nguồn bằng chính đường dẫn dữ liệu và bằng 1 nếu cấp nguồn qua một đường dẫn riêng.
Đối với bài này, chúng ta chỉ cần quan tâm đến hai lệnh đó là: read và write.
II.Bây giờ là Vi Điều Khiển
Đối với vđk, các bạn có thể dùng hãng nào, con nào cũng được. Ở đây tôi dùng con PIC16f887 của MICROCHIP. Phần mềm viết code là MPLAB-IDE và trình biên dịch là Hi-Tech C.
Như vậy là phần cứng đã xong, bây giờ chỉ cần viết code là được.
III.Cuối cùng là phần viết code
Code để giao tiếp với DS18B20 cũng không khó lắm, các bạn chịu khó theo giỏi.
3.1.Khởi tạo DS18B20
Đây là sơ đồ mà nhà sản xuất chỉ cho chúng ta biết cách reset và khởi tạo DS18B20, nó có đầy đủ trong datasheet.
Theo đó, để reset và khởi tạo DS18B20 chúng ta cần: khởi tạo chân DQ (là một chân I/O bất kỳ của vđk, chân này được nối với chân DQ của DS18B20. Ví dụ ở đây tôi dùng chân RA4) là ngõ ra, sau đó set chân này ở mức “0” ít nhất là 480µs, sau đó khởi tạo chân DQ là ngõ vào rồi delay một khoảng ít nhất là 480µs.
Các bạn xem code:
Mã:
void onewire_reset()
{
TDQ=0; // khởi tạo chân DQ là ngõ ra
DQ = 0; //set DQ là mức “0”
__delay_us(500); //chờ ít nhất là 480µs
TDQ=1;DQ=1; // khởi tạo chân DQ là ngõ vào
__delay_us(500); //chờ ít nhất là 480µs
}
3.2.Viết lệnh xuống DS18B20
Để gửi lệnh xuống DS18B20 ta xem sơ đồ sau:
Như vậy, để ghi mức “0” thì chỉ cần cho chân DQ của vđk xuống mức “0” ít nhất là 60µs và lớn nhất là 120µs. Còn để ghi mức “1” thì 1µs < TREC < ∞. TREC là thời gian ghi. Vậy thời gian ghi là vô cùng nên chúng ta lấy chung thời gian cho hai mức logic là 60 ÷ 120µs.
Đây là code:
Mã:
void write_byte(unsigned char data)
{
unsigned char i=0; //khai báo biến i cho vòng lặp for
for (i=8; i>0; i--) //dùng vòng lặp for để viết 8bit xuống DS18B20
{
TDQ=0; //DQ là ngõ ra
DQ = 0; //set DQ là mức “0”
DQ = (data&0x01); //so sánh dữ liệu để viết “0” hoặc “1” xuống DS18B20
__delay_us(60); //chờ một khoảng thời gian để DS18B20 ghi mức logic
DQ = 1; // set DQ là mức “1”
data>>=1; //chuyển qua bit kế tiếp
} //lặp 8 lần thì chúng ta đã ghi được 8bit
}
3.3.Đọc giá trị nhiệt độ từ DS18B20
Đọc giá trị cũng giống như ghi, các bạn xem hình:

Các bạn xem code luôn
Mã:
int read_byte()
{
unsigned char i=0;
unsigned char data = 0;
for (i=8;i>0;i--)
{
TDQ=0;
DQ = 0;
data>>=1;
DQ = 1;
TDQ=1;DQ=1; //DQ là ngõ vào
if(DQ)
data|=0x80;
__delay_us(120);
}
return(data); //trả về giá trị data
}
Như vậy là đã xong những hàm cơ bản để giao tiếp với DS18B20. Bây giờ chúng ta hãy tập hợp chúng lại để tạo thành một hàm vừa khởi tạo, ghi, đọc và tình kết quả luôn. Các bạn xem code:
float ds18b20_read()
{
unsigned char busy=0, temp1, temp2;
int temp3;
float result;
onewire_reset();
write_byte(0xCC); //Skip ROM, address all devices
write_byte(0x44); //Start temperature conversion
__delay_us(200);
onewire_reset();
write_byte(0xCC); //Skip ROM, address all devices
write_byte(0xBE); //Read scratchpad
temp1 = read_byte();
temp2 = read_byte();
temp3 = (temp2*256+temp1);
result = (float) temp3 / 16.0; //Calculation for DS18B20 with 0.1 deg C resolution
__delay_ms(200); // ??????
return(result);
}
Những câu lệnh như:
Write_byte(0xCC); các bạn quay ngược lên trên, mục “1.3. Các tập lệnh của DS18B20” để xem 0xCC là lệnh gì nha.
Như vậy là xong, chỉ cần viết thêm hàm main để cho vđk làm việc. Đây là hàm main:
Mã:
void main()
{
lcd_init();
// lcd_gotoxy(0,0);
printf("\fHOANG KHANH THAN");
__delay_ms(1000);
lcd_gotoxy(0,1);
printf(" DH-SPKT");
__delay_ms(2500);
// lcd_gotoxy(0,0);
printf("\f");
float temperature;
while(1)
{
temperature=ds18b20_read();
lcd_gotoxy(0,0);
printf("NHIET DO: %3.2f",temperature);
}
}
Về phần hiển thị lên LCD các bạn tự tham khảo hoặc tải source code tại: LCD16x2_Hi-Tech_C.rar
Như vậy là kết thúc phiên giao dịch với DS18B20 một cách thành công tốt đẹp. Chúc các bạn thành công.
Mọi ý kiến đóng góp hay thắc mắc các bạn hãy gửi vào email: khanhthan.hoang@gmail.com thân ái!

 

Đính kèm

chungtvtt

Học sinh phổ thông
#5
anh ơi em làm giống như anh..mô phỏng chạy rồi nhưng sao em nạp chip nó lại hiện lên LCD là NHIETDO: -0.062.. VÀ K THAY ĐỔI..LỖI GÌ ANH GIÚP EM VỚI
 

daithang

Học sinh phổ thông
#7
cho e hỏi code có chạy cho pic18f4550 ko ạ
lúc chạy nó báo lỗi TDQ, DQ not been define
 

daithang

Học sinh phổ thông
#8
cho e hỏi code có chạy cho pic18f4550 ko ạ
lúc chạy nó báo lỗi TDQ, DQ not been define
 

Quảng cáo Google