Witam, chciałbym przedstawić swój problem, może któryś z użytkowników będzie wiedział jak mi pomóc. Jako że zacząłem niedawno swoją przygodę z mikro-kontrolerami zaczynam od najprostszych projektów. Po udanej próbie obsługi wyświetlacza (na sterowniku HD44780) wziąłem się za pisanie obsługi czujnika temperatury firmy Dallas Semiconductors DS18B20.
Czujnik pracuje w systemie 1-wire, podłączony jest normalnie (Vcc do napięcia 4,8V; GND do masy i DQ do uC) a nie w trybie pasożytniczym. Komunikacja z czujnikiem zachodzi i sądzę że czujnik przesyła informacje prawidłowo. Niestety wadliwy jest chyba fragment odpowiedzialny za przeliczanie temperatury (z hex do dec). Objawia się to tym że w temperaturze ok 19-10 stopni C (na parapecie w zimny deszczowy dzień) wyświetla ok 960.2 stopni. przy podnoszeniu temperatury do pokojowej temperatura podnosi się do 1024 po czym zmienia znak na - i zaczyna opadać od -1024 do ok -930 .. -876. Poniżej zamieszczam kody źródłowe "temp.c" i "temp.h". Chciałbym zaznaczyć że przejrzałem już sporą ilość tematów poruszających ten problem na innych forach.
temp.c
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include "temp.h"
#include "lcd.h"
int main(void){
lcdInit();
lcdClear();
lcdText("termometr");
_delay_ms(4000);
for(;;){
unsigned char buf[12];
float temp=0;
lcdGoto(0,0);
temp=read_temp();
if(temp!=1111.1){
dtostrf(temp,1,1,buf);
lcdClear();
lcdText(buf);
}else{
lcdClear();
lcdText("cisza...");
}
_delay_ms(200);
}
return 0;
}
temp.h
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#define we 7
#define port1wire PIND
#define ddr1wire DDRD
#define set1wire ddr1wire&=~_BV(we)
#define clr1wire ddr1wire|=_BV(we)
unsigned char reset_pulse(void){
unsigned char ob=0;
clr1wire;
_delay_us(480);
set1wire;
_delay_us(30);
if(bit_is_clear(port1wire, we)) ob=1; else ob=0;
_delay_us(470);
if(bit_is_set(port1wire, we)) ob=1; else ob=0;
return ob;
}
void send(char bit){
clr1wire;
_delay_us(5);
if(bit==1)
set1wire;
_delay_us(80);
set1wire;
}
unsigned char read(void){
unsigned char ob=0;
clr1wire;
_delay_us(2);
set1wire;
_delay_us(16);
if(bit_is_set(port1wire, we)) ob=1; else ob=0;
return ob;
}
void send_byte(char byte){
unsigned char i;
unsigned char pom;
for(i=0;i<8;i++){
pom=byte>>i;
pom&=0x01;
send(pom);
}
_delay_us(100);
}
unsigned char read_byte(void){
unsigned char i;
unsigned char val=0;
for(i=0;i<8;i++){
if(read())
val|=0x01<<i;
_delay_us(16);
}
return val;
}
float read_temp(void){
unsigned char spr=0;
char temp1=0, temp2=0;
float temp=0;
spr=reset_pulse();
if(spr==1){
send_byte(0xCC); //skip rom
send_byte(0x44); //convert t
_delay_ms(250);
_delay_ms(250);
spr=reset_pulse();
send_byte(0xCC); //skip rom
send_byte(0xBE); //read scratchpad
temp1=read_byte();
temp2=read_byte();
spr=reset_pulse();
temp=(float)(temp1+(temp2*256))/16;
}else
temp=1111.1;
return temp;
}
tak, rezystor przepisowe 4,7k jest.