Problem polega na tyn, że odczytana z czujnika temperatura wynosi niezmiennie 85 C. Po wydaniu rozkazu konwersji odczekuje 1 sekundę zanim zacznę odczyt temp. czas wydaje mi sie wystarczająco długi, żeby ds zdążył z konwersją. Próbowałem również po wydaniu rozkazu konwersji próbkować stan linii danych i przechodziłem do odczytu, gdy ds zwolnił magistrale. W kółko to samo 85 C.
Odczytane z ds'a zawartości rejestrów po komendzie read scratchpad zgadzają sie z domyślnymi. Komenda read rom również zwraca poprawna wartość. Ponadto probowałem zapisać scratchpad i potem go odczytać. Niestety odczytana wartość nie zgadza sie z zapisaną. Może to nasuwać wniosek, że coś jest źle z funkcją zapisu, ale przecież wykorzystuje się ją również przy wydawaniu komend rom, a w tym przypadku wszytko wydaje się być ok.
Zgodnie z dokumentacją pull-up mam 4,7k, ale czytałem, że można zastosować mniejsze, tylko na jakiej podstawie ? Producent nic o tym nie pisze. Czy zbyt duży rezystor może być przyczyną tych problemów ?
Może ktoś miał podobny problem i znalazł rozwiązanie ? Będę wdzięczny za pomoc.
kod programu ( linia danych na PD1, kwarc 16MHz, zasilanie z Vdd)
Odczytane z ds'a zawartości rejestrów po komendzie read scratchpad zgadzają sie z domyślnymi. Komenda read rom również zwraca poprawna wartość. Ponadto probowałem zapisać scratchpad i potem go odczytać. Niestety odczytana wartość nie zgadza sie z zapisaną. Może to nasuwać wniosek, że coś jest źle z funkcją zapisu, ale przecież wykorzystuje się ją również przy wydawaniu komend rom, a w tym przypadku wszytko wydaje się być ok.
Zgodnie z dokumentacją pull-up mam 4,7k, ale czytałem, że można zastosować mniejsze, tylko na jakiej podstawie ? Producent nic o tym nie pisze. Czy zbyt duży rezystor może być przyczyną tych problemów ?
Może ktoś miał podobny problem i znalazł rozwiązanie ? Będę wdzięczny za pomoc.
kod programu ( linia danych na PD1, kwarc 16MHz, zasilanie z Vdd)
#include<avr/io.h>
#include<avr/delay.h>
#include<stdlib.h>
#include "temp.h"
#include "mylcd.h"
#define SET_DQ DDRD &=~_BV(1)
#define CLR_DQ DDRD |=_BV(1)
#define BUS_IN DDRD &=~ _BV(1)
#define PULL_BUS PORTD |= _BV(PD1)
#define BUS_OUT DDRD |= _BV(1)
#define DQ_IN PIND & _BV(1)
// ROM COMMANDS
#define READ_ROM 0x33
#define SKIP_ROM 0xcc
// FUNCTION COMMANDS
#define WRITE_SCRATCHPAD 0x4e
#define CONV_TEMP 0x44
#define READ_SCRATCHPAD 0xbe
uint8_t ow_reset(void)
{
uint8_t presence;
CLR_DQ; // DQ = 0, generuj reset
_delay_loop_2(2000); // czekaj > 480us; tutaj 500us
SET_DQ; // zwolnij linie danych
_delay_loop_2(280); // czekaj az linie sie podciagnie i slave odpowie, tutaj 70us
presence = DQ_IN; // sprawsz stan linii (czy slave odpowiedzial)
_delay_loop_2(1640); // czekaj az slave zwolni linie; 410 us
if(DQ_IN) // czy slave zwolnil linie ?
presence = 0; // tak
else presence = 1; // nie
SET_DQ;
return presence;
}
uint8_t read_bit(void)
{
uint8_t bit = 1;
CLR_DQ; // DQ = 0;
_delay_loop_2(8); // czekaj > 1 us; 2us
SET_DQ;
_delay_loop_2(8); // czekaj < 15 us od poczatku slotu, 2 us na podciagniecie linii
if(!(DQ_IN))
bit = 0;
_delay_loop_2(280); // czekaj do konca slotu; 70 us
SET_DQ;
return bit;
}
void write_bit(char bit)
{
if(bit) // zapisz "1"
{ CLR_DQ; // DQ = 0;
_delay_loop_2(28); // czekaj > 1us; 7us
SET_DQ; // DQ = 1;
_delay_loop_2(280); // czekaj < 60 us; 70us
}
else // zapisz "0"
{ CLR_DQ; // DQ = 0;
_delay_loop_2(280); // czekaj x, 60us < x < 120us; 70
SET_DQ; // DQ = 1;
_delay_loop_2(12); // czekaj az linia sie podcianie, > 1us; 3us
}
SET_DQ;
}
uint8_t read_byte(void)
{
uint8_t i;
uint8_t value = 0;
for(i = 0; i < 8; i++)
{
value >>= 1;
if(read_bit())
value |= 0x80;
}
_delay_loop_2(8);
return value;
}
void write_byte(char byte)
{
uint8_t i;
for(i = 0; i < 8; i++)
{
write_bit(byte & 0x01);
byte >>= 1;
_delay_loop_2(8); // czekaj na recovery miedzy slotami > 1us; 2us
}
}
int main(void)
{
uint8_t data_tab[9]; // tablica danych pobranych z ds'a
uint8_t i;
uint8_t buffer[8];
uint8_t tmp;
lcd_init();
PORTD = 0x00;
while(1)
{
if(!ow_reset())
{
write_byte(SKIP_ROM);
write_byte(CONV_TEMP);
_delay_ms(250); // czekaj az skonczy konwersje
_delay_ms(250);
_delay_ms(250);
}
//while(!DQ_IN){} // probkuj linie DQ, czekaj na koniec konwersji ;DQ= 1
if(!ow_reset())
{
write_byte(SKIP_ROM);
write_byte(READ_SCRATCHPAD);
for(i = 0; i < 9; i++)
{
data_tab[i] = read_byte();
}
tmp= ((data_tab[1] << 4) & 0xf0) | ((data_tab[0] >> 4) & 0x0f);
write_command(0x01);
write_text("TEMP: ");
write_text(itoa(tmp, buffer,10)); // wyswietla temp na lcd
write_text(" C");
}
_delay_ms(1000); // czekaj sekunde przed nastepnym pobraniem temperatury
}
return 0;
}