Witam,
Mam maly problem z moim kodem obslugujacym magistrale 1Wire. Jak dotad napisalem takie cos:
<src_code_mode="on">#include "1wire.h"
unsigned char onewire_reset(void) { unsigned char i = 200; sbi(DDRD, 4); cbi(PORTD, 4); delay_us(500); cbi(DDRD, 4); sbi(PORTD, 4); delay_us(50);
while(i--) { if (bit_is_clear(PIND, 4)) { delay_us(500); return ONEWIRE_OK; } delay_1us(); }
return ONEWIRE_BUS_ERROR; }
void onewire_write(unsigned char byte) { unsigned char i = 0;
for(i = 0; i < 8; i++) { sbi(DDRD, 4); cbi(PORTD, 4); delay_us(5); if ((byte & 0x01) == 1) { cbi(DDRD, 4); sbi(PORTD, 4); } delay_us(60); cbi(DDRD, 4); sbi(PORTD, 4); delay_2us(); byte >>= 1; }
cbi(DDRD, 4); cbi(PORTD, 4); }
unsigned char onewire_read(void) { unsigned char byte = 0; unsigned char i = 0;
for(i = 0; i < 8; i++) { sbi(DDRD, 4); cbi(PORTD, 4); delay_1us(); cbi(DDRD, 4); sbi(PORTD, 4); delay_us(18); byte |= (bit_is_set(PIND, 4) ? 1 : 0) << i; delay_us(45); }
return byte; }
<src_code_mode="off">Program jest pisany pod at90s2313, kompiluje w avr-gcc 3.3. Zegar 4MHz. Rezystorek podciagajacy 4,7k, DS18b20 jest podlaczony 3 krotkimi przewodami (+, -, data). Opoznienia sa realizowane w makrach: dla 1 i
2us sa to nop'y, a dla wiekszych petla (zazwyczaj opoznienie jest +2us wieksze od zadeklarowanego). Narazie nie uzywam przerwan ani timer'kow. Tylko reset dziala - ds18b20 zglasza sie prawidlowo, reszta juz nie (tzn. wysylam mu 0xcc, 0x44, czekam >100ms, wysylam 0xcc, 0xbe, odbieram co nadaje - dostaje same jedynki, ds18b20 chyba nie zinterpretowal albo nie przyjal rozkazu). Napisalem program wyswietlajacy temperature w Bascom'ie, dziala wysmienicie - znaczy sie ze sprzet jest zmontowany dobrze. Czemu nie zrobie tego w Bascomie? Jak do niczego nie dojde, to dopiero wtedy, ale wole to napisac w bardziej czytelnym c.Podejrzewam ze problem tkwi w opoznieniach w slotach read & write. W dokumentacji przeczytalem takie cos (poprawcie mnie jesli sie myle):
a) slot write
- dla 0: pin (w avr) do masy przez ~60us, potem uaktywnienie pull-up'a
- dla 1: pin do masy przez 1us, potem przez ~60us uaktywnienie pull-up'a, czyli jedynka na pin'ie
b) slot read: pin do masy przez 1us, zmiana stanu na odbior, poczekanie >15us, odczytanie stanu linii, poczekanie ~45us na koniec slot'u
A teraz co robie zle ze nie dziala?? Mecze sie z tym juz kolejny tydzien. Szukalem rozwiazania na sieci - usenet, avrfreaks, google. Znalazlem rozne przyklady, ale nie dzialaly. W dodatku w kazdym byly inne timmingi :/ W swoim kodzie tez zmienialem czasy, ale nie pomoglo.
Bede wdzieczny za wszelkie konstruktywne porady.
Pozdrawiam, Krzysiek