//====================== DS18B20 - DQ->PD6 =======================
#include <avr/io.h>
#include <util/delay.h>
#include "lcd.h"
int8_t digit;
#define THERM_PORT PORTD
#define THERM_DDR DDRD
#define THERM_PIN PIND
#define THERM_DQ PD6
#define THERM_INPUT_MODE() THERM_DDR&=~(1<<THERM_DQ)
#define THERM_OUTPUT_MODE() THERM_DDR|=(1<<THERM_DQ)
#define THERM_LOW() THERM_PORT&=~(1<<THERM_DQ)
#define THERM_HIGH() THERM_PORT|=(1<<THERM_DQ)
#define THERM_CMD_CONVERTTEMP 0x44
#define THERM_CMD_RSCRATCHPAD 0xBE
#define THERM_CMD_WSCRATCHPAD 0x4E
#define THERM_CMD_CPYSCRATCHPAD 0x48
#define THERM_CMD_RECEEPROM 0xB8
#define THERM_CMD_RPWRSUPPLY 0xB4
#define THERM_CMD_SEARCHROM 0xF0
#define THERM_CMD_READROM 0x33
#define THERM_CMD_MATCHROM 0x55
#define THERM_CMD_SKIPROM 0xCC
#define THERM_CMD_ALARMSEARCH 0xEC
uint8_t therm_reset()
{
uint8_t i;
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(480);
THERM_INPUT_MODE();
_delay_us(60);
i=(THERM_PIN & (1<<THERM_DQ));
_delay_us(420);
return i;
}
void therm_write_bit(uint8_t bit)
{
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(1);
if(bit) THERM_INPUT_MODE();
_delay_us(60);
THERM_INPUT_MODE();
}
uint8_t therm_read_bit(void)
{
uint8_t bit=0;
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(1);
THERM_INPUT_MODE();
_delay_us(14);
if(THERM_PIN & (1<<THERM_DQ)) bit=1;
_delay_us(45);
return bit;
}
uint8_t therm_read_byte(void)
{
uint8_t i=8,n=0;
while(i--)
{
n>>1;
n|=(therm_read_bit()<<7);
}
return n;
}
void therm_write_byte(uint8_t byte)
{
uint8_t i=8;
while(i--)
{
therm_write_bit(byte&1);
byte>>=1;
}
}
void therm_read_temperature(void)
{
uint8_t temperature[2];
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_CONVERTTEMP);
while(!therm_read_bit());
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_RSCRATCHPAD);
temperature[0]=therm_read_byte();
temperature[1]=therm_read_byte();
therm_reset();
digit=temperature[0]>>4;
digit|=(temperature[1]&0x07)<<4;
}
void main (void)
{
Init_LCD();
while(1)
{
therm_read_temperature();
Ghi_data((digit/100)+48);
Ghi_data(((digit/10)%10)+48);
Ghi_data((digit%10)+48);
Ghi_chuoi(" C");
}
}
//================================================== ======
Theo mình hiểu thì lúc này biến digit=0 X X X X X X X và đây là nhiệt độ! Nhưng khi hiển thị ra LCD lại nhận được con số 008 trong khi DS18B20 có nhiệt độ khác!
Các bác cho em hỏi có phải vấn đề của code là do mình chọn _delay_us() cho các hàm phải thật chính xác không, có phải giao tiếp 1 wire cần cái đó không?
#include <avr/io.h>
#include <util/delay.h>
#include "lcd.h"
int8_t digit;
#define THERM_PORT PORTD
#define THERM_DDR DDRD
#define THERM_PIN PIND
#define THERM_DQ PD6
#define THERM_INPUT_MODE() THERM_DDR&=~(1<<THERM_DQ)
#define THERM_OUTPUT_MODE() THERM_DDR|=(1<<THERM_DQ)
#define THERM_LOW() THERM_PORT&=~(1<<THERM_DQ)
#define THERM_HIGH() THERM_PORT|=(1<<THERM_DQ)
#define THERM_CMD_CONVERTTEMP 0x44
#define THERM_CMD_RSCRATCHPAD 0xBE
#define THERM_CMD_WSCRATCHPAD 0x4E
#define THERM_CMD_CPYSCRATCHPAD 0x48
#define THERM_CMD_RECEEPROM 0xB8
#define THERM_CMD_RPWRSUPPLY 0xB4
#define THERM_CMD_SEARCHROM 0xF0
#define THERM_CMD_READROM 0x33
#define THERM_CMD_MATCHROM 0x55
#define THERM_CMD_SKIPROM 0xCC
#define THERM_CMD_ALARMSEARCH 0xEC
uint8_t therm_reset()
{
uint8_t i;
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(480);
THERM_INPUT_MODE();
_delay_us(60);
i=(THERM_PIN & (1<<THERM_DQ));
_delay_us(420);
return i;
}
void therm_write_bit(uint8_t bit)
{
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(1);
if(bit) THERM_INPUT_MODE();
_delay_us(60);
THERM_INPUT_MODE();
}
uint8_t therm_read_bit(void)
{
uint8_t bit=0;
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(1);
THERM_INPUT_MODE();
_delay_us(14);
if(THERM_PIN & (1<<THERM_DQ)) bit=1;
_delay_us(45);
return bit;
}
uint8_t therm_read_byte(void)
{
uint8_t i=8,n=0;
while(i--)
{
n>>1;
n|=(therm_read_bit()<<7);
}
return n;
}
void therm_write_byte(uint8_t byte)
{
uint8_t i=8;
while(i--)
{
therm_write_bit(byte&1);
byte>>=1;
}
}
void therm_read_temperature(void)
{
uint8_t temperature[2];
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_CONVERTTEMP);
while(!therm_read_bit());
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_RSCRATCHPAD);
temperature[0]=therm_read_byte();
temperature[1]=therm_read_byte();
therm_reset();
digit=temperature[0]>>4;
digit|=(temperature[1]&0x07)<<4;
}
void main (void)
{
Init_LCD();
while(1)
{
therm_read_temperature();
Ghi_data((digit/100)+48);
Ghi_data(((digit/10)%10)+48);
Ghi_data((digit%10)+48);
Ghi_chuoi(" C");
}
}
//================================================== ======
Theo mình hiểu thì lúc này biến digit=0 X X X X X X X và đây là nhiệt độ! Nhưng khi hiển thị ra LCD lại nhận được con số 008 trong khi DS18B20 có nhiệt độ khác!
Các bác cho em hỏi có phải vấn đề của code là do mình chọn _delay_us() cho các hàm phải thật chính xác không, có phải giao tiếp 1 wire cần cái đó không?