Witam
Wiem, że ostatnio był wysyp podobnych tematów ale mam problem z czujnikiem DS18B20, którego sam nie dam rady rozwiązać.
Otóż po włączeniu układu na wyświetlaczu pojawia się temperatura ok 25 stopni, która rzeczywiście odpowiada temperaturze otoczenia. Następnie co 300ms na wyświetlaczu ma się pojawiać aktualna temperatura niestety następne odczyty są błędne i na lcd pojawia mi się ok 85 stopni (czasami ok 127 i to już od razu po włączeniu przy pierwszym pomiarze). Poniżej przedstawiam listingi
onewire.c:
main.c gdzie uC co 300ms ma aktualizować tempetarurę
Z góry dziękuje za pomoc
Wiem, że ostatnio był wysyp podobnych tematów ale mam problem z czujnikiem DS18B20, którego sam nie dam rady rozwiązać.
Otóż po włączeniu układu na wyświetlaczu pojawia się temperatura ok 25 stopni, która rzeczywiście odpowiada temperaturze otoczenia. Następnie co 300ms na wyświetlaczu ma się pojawiać aktualna temperatura niestety następne odczyty są błędne i na lcd pojawia mi się ok 85 stopni (czasami ok 127 i to już od razu po włączeniu przy pierwszym pomiarze). Poniżej przedstawiam listingi
onewire.c:
#include <avr\io.h>
#include <inttypes.h>
#include <util/delay.h>
#include "one_wire.h"
#include "harddef.h"
#include "makra.h"
/////////////////////
//Definicje funkcji
////////////////////
/* Definicje w pliku harddef.h
#define ONE_WIRE 0
#define ONE_WIRE_PORT C
*/
// Reset
unsigned char one_wire_reset (void)
{
unsigned char presence; // zmienna przetrzymujaca
// odpowiedź slave
// Wyzerowanie one wire
DDR(ONE_WIRE_PORT) |= _BV(ONE_WIRE);
_delay_us(700);
// Zwolnienie magistrali
DDR(ONE_WIRE_PORT) &= ~_BV(ONE_WIRE);
// Oczekiwanie na ustawienie lini w stan niski
// przez slave
_delay_us(80);
// Sprawdzamy poziom lini one wire,
// presence = 1 jeśli linia w stanie niskim
if (!(PIN(ONE_WIRE_PORT)&_BV(ONE_WIRE)))
{
// Odczekanie przez master 470 ms na koniec okresu nie aktywności
_delay_us(400);
// Sprawdzenie czy SLAVE podciągął linię do zasilania
if (PIN(ONE_WIRE_PORT)&_BV(ONE_WIRE))
presence = 1 ;
else
presence = 0;
return presence;
}
// Zwrot bitu potwierdzenia
else
{
presence = 0;
//_delay_us(470);
return presence;
}
}
// wysyłanie do układu pojedyńczego bitu
void one_wire_write_bit (char bit)
{
cli(); // Wyłączenie przerwań
// Ustawienie linii w stan niski
DDR(ONE_WIRE_PORT) |= _BV(ONE_WIRE);
_delay_us(10);
// Jeśli bit = 1 to po 5ms
// podćiągnięcie lini do zasilania
// i odczekanie 80 ms
if(bit==1)
// Podciągnięcie linii do Vdd
DDR(ONE_WIRE_PORT) &= ~_BV(ONE_WIRE);
_delay_us(80);
// Podciagniecię linii do zasilania
DDR(ONE_WIRE_PORT) &= ~_BV(ONE_WIRE);
// Odblokowanie przerwań
sei();
}
// Wysłanie do układu bajtu
void one_wire_write_byte (char bajt)
{
unsigned char i; // Zmienna licznikowa
unsigned char temp; // Zmienna tymczasowa,
for (i=0; i<8; i++)
{
temp = bajt >> i;
temp &= 0x01;
one_wire_write_bit(temp);
}
_delay_us(100);
}
// Funkcja odczytu bitu
unsigned char one_wire_read_bit (void)
{
unsigned char bit;
cli(); // zablokowanie obsługi przerwań
// na czas odczytu bitu
// Wyzerowanie linii
DDR(ONE_WIRE_PORT) |= _BV(ONE_WIRE);
_delay_us(5);
// Odblokowanie linii
DDR(ONE_WIRE_PORT) &= ~_BV(ONE_WIRE);
_delay_us(5); // Zwłoka przed odczytem
// Odczyt bitu, jeśli 0 to... else...
if (!(PIN(ONE_WIRE_PORT) & _BV(ONE_WIRE)))
{
sei(); // Odblokowanie przerwań
_delay_us(55); //Zwłoka na podciągniecie do Vcc
// +15 us zwłoki w funkcji nadrzednej
// one_wire_read_byte
bit = 0;
return bit; // Zwrot bitu
}
else
{
sei(); // Odblokowanie przerwań
bit = 1;
_delay_us(55);
return bit; // Zwrot bitu
}
}
// Funkcja odczytu bajtu
unsigned char one_wire_read_byte (void)
{
unsigned char bajt; // Zmienna przechowujaca odczytany bajt
unsigned char i;
// Odczyt 8 bitów i złączenie ich w bajt
for (i=0; i<8; i++)
{
// Jeśli odczytany bit = 1 to wpisanie jedynki
if (one_wire_read_bit())
bajt |= 0x01<<i;
_delay_us(15);
}
return bajt;
}
main.c gdzie uC co 300ms ma aktualizować tempetarurę
int main(void)
{
unsigned char sprawdz;
char temp1 = 0, temp2 = 0;
char buf[8];
// Inicjalizacja
lcd_init();
lcd_cls();
// Pętla główna
while(1)
{
sprawdz = one_wire_reset();
if (sprawdz == 1)
{
one_wire_write_byte(0xCC);
one_wire_write_byte(0x44);
_delay_ms(1000);
sprawdz = one_wire_reset();
one_wire_write_byte(0xCC);
one_wire_write_byte(0xBE);
temp1=one_wire_read_byte();
temp2=one_wire_read_byte();
sprawdz = one_wire_reset();
float temp = 0;
temp = (float)(temp1+(temp2*256))/16;
dtostrf(temp,1,1,buf);
lcd_cls();
lcd_str_P((prog_char*)PSTR("temp = "));
lcd_str(buf); // Wyświetlenie temperatury
_delay_ms(300);
}
else
{
lcd_cls();
lcd_command(LCDC_DDA|64);
lcd_str_P((prog_char*)PSTR("cisza = "));
_delay_ms(100);
}
}
return 0;
}Z góry dziękuje za pomoc