1-wire DS18B20 + ATMega64 výpis na USART

Ahoj.

Už si nevím rady.
Napsal jsem si vlastní funkce pro 1-wire:

  • RESET/PRESENCE
  • zápis bajtu
  • čtení teploty z čidla DS18B20
    Zde jsou uvedeny:

**1. RESET/PRESENCE - pokud vrátí err=0 je vše v pořádku a obvod komunikuje - OPRAVENO !! (funkční)

[code]char onewire_rst_pre (void)
{
char err=1;

SREG &= ~(1<<7); //zakazani preruseni
DDRE |= (1<<3); //DIGIT_TEMP jako vystup (OUT)
DIGIT_TEMP_OUT = 0; //RESET signal 480 us
delay_us(480);
DDRE &= ~(1<<3); //DIGIT_TEMP jako vstup (IN)
delay_us(60);
err = DIGIT_TEMP_IN; //cti presence pulz
if (DIGIT_TEMP_IN == 0){ //pulz pritomen
err = 0;
}
else{
err = 1; //1W obvod nekomunikuje
}
delay_us (480);
SREG |= (1<<7); //povoleni preruseni
return err;
}[/code]

2. ZÁPIS BAJTU - zapisuji od LSB po MSB - OPRAVENO !! (funkční)

[code]void send_byte (char byte_to_send)
{
char i=0;

SREG &= ~(1<<7); //zakazani preruseni
DDRE |= (1 << 3); //DIGIT_TEMP jako vystup (OUT)
for (i=0; i<=7; i++) { //smycka pro 8 opakovani (1byte)
DIGIT_TEMP_OUT = (byte_to_send & BITPOS_0); //zapis na DIGIT_TEMP nejnizsi bit
if (DIGIT_TEMP_OUT == 0){ //pokud je bit 0
delay_us(60); //nech nastaveno DIGIT_TEMP na 0 po 60 us
DIGIT_TEMP_OUT = 1; //vrat do log. 1
}
else{ //pokud je bit 1
DIGIT_TEMP_OUT = 0; //5us impulz do 0
delay_us(2);
DIGIT_TEMP_OUT = 1; //nastav zpatky log. 1 a drz 55 us
delay_us(60);
}
byte_to_send >>= 1; //zarotuj doprava
delay_us(1); //cekej 1 us
}
DDRE &= ~(1 << 3); //DIGIT_TEMP jako vstup (IN)
SREG |= (1<<7); //povoleni preruseni
return;
}[/code]

3. ČTENÍ TEPLOTY (16 bitů) - postupně zapisuji na MSB 16bitového “temperature” a odsouvám doprava, až naplním všech 16 bitů - OPRAVENO !! (funkční)

[code]unsigned int read (void)
{
char i;
unsigned int temperature = 0;

SREG &= ~(1<<7); //zakazani preruseni
for (i=0; i<=15; i++) {
DDRE |= (1 << 3); //DIGIT_TEMP jako vystup (OUT)
DIGIT_TEMP_OUT = 0; //1 us impulz do nuly
delay_us(1);
DIGIT_TEMP_OUT = 1;
DDRE &= ~(1 << 3); //DIGIT_TEMP jako vstup (IN)
delay_us(15); //cekani 12 us
if (DIGIT_TEMP_IN == 1){ //pokud je na sbernici log. 1
temperature |= (1 << 15); //uloz na MSB “1”
}
else{
temperature &= ~(1 << 15); //jinak uloz na MSB “0”
}
delay_us(60);
temperature >>=1; //rotace doprava
}
SREG |= (1<<7); //povoleni preruseni
return temperature; //vrati 16bitove cislo s vysledkem zarovnanym doprava
}[/code]

Výsledkem je, že RESET/PRESENCE funguje, tam mi MCU správně signalizuje (ne)přítomnost čidla, dál se ale neděje nic - resp. někde v čtení teploty se to zasekne a program se v main ani nedokončí. (pokud to volání na čtení teploty dám do komentáře, tak se alespoň program dokončí, ale pochopitelně zobrazí nesmysl).
Problémem je, že ani nevím, jestli je zápis v pořádku…
Chtěl bych poprosit někoho kdo již vyřešil 1wire jestli mi to může shlédnout. Snažil jsem se jít dle dostupných zdrojů o tom, jak 1-wire funguje.

Díky

EDIT: Opraveno !!! Měl jsem špatně časování - teď už to chodí :smiley:

Nicméně se objevil problém v tom, že čidlo ukazuje o cca. 10°C míň než reálně je…**

Takže funkce jsou opraveny a teplota se konečně začala na terminál vypisovat. Při zahřátí vzroste a poté opět samovolně klesá.
Jediný problém je, že ukazuje o cca. 10 °C míň než ve skutečnosti je…