RTV forum PL | NewsGroups PL

Problem z odczytem danych z 1-Wire przy użyciu AVR-GCC - potrzebna analiza kodu

avr-gcc i 1wire - ponownie

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Problem z odczytem danych z 1-Wire przy użyciu AVR-GCC - potrzebna analiza kodu

Saper/nolin11
Guest

Fri May 18, 2007 11:08 pm   



Witam,

Teraz przysiadłem się do oprogramowania i testowania 1wire.
I mam problem, otóż taką mam procedurę główną:
<code>
for (;Wink {
for (tmp=0;tmp<8;tmp++) ds_nr[tmp] = 0x00;
if (ow_reset() == 0) {
ow_write_byte(0x33); // read rom
for (tmp=0;tmp<8;tmp++) ds_nr[tmp] = ow_read_byte();
lcd_setPos(2,0);
lcd_str_P((prog_char*)PSTR("1W_RESET=0"));
} else {
lcd_setPos(2,0);
lcd_str_P((prog_char*)PSTR("1W_RESET=1"));
}

lcd_setPos(1,0);
for (tmp=0;tmp<8;tmp++) lcd_hex_byte(ds_nr[tmp]);

delay1ms(5);

}
</code>
I z ds_nr mam same 0x08, co do czasów resetu i pozostałych myślę że są
dobre (na przykładnaie układu reaguje) ale z odczytem mam już głupoty :/

Może zjadzie się osoba co mogła rzucić by okiem:
<code unit="1wire.c">
void ow_delay(uint16_t t) {
while (t>0) {
// ~250ns
asm volatile("nop":Smile;
asm volatile("nop":Smile;
// ~250ns
asm volatile("nop":Smile;
asm volatile("nop":Smile;
// ~250ns
asm volatile("nop":Smile;
asm volatile("nop":Smile;
// ~250ns
asm volatile("nop":Smile;
asm volatile("nop":Smile;
// + --- " --- = 1us
--t;
}
}

void ow_write_bit(uint8_t bit) {

DDR(OW_PORT) |= 1 << OW_PIN; // port=OUT
PORT(OW_PORT) &= ~(1 << OW_PIN); // port=0
ow_delay(3); // poczekaj chwile i:
if (bit != 0) { // jeśli ma być wystawiona 1 to port=1 jeśli nie to port
pozostanie w "0"
PORT(OW_PORT) |= 1 << OW_PIN;
}
ow_delay(70); // poczekaj az ramka bitu moze sie zakonczyc (t>60us)
DDR(OW_PORT) &= ~(1 << OW_PIN); // port=IN
PORT(OW_PORT) |= 1 << OW_PIN; // port=1
}

uint8_t ow_read_bit(void) {
static uint8_t tmp;

PORT(OW_PORT) &= ~(1 << OW_PIN); // port=0
DDR(OW_PORT) |= 1 << OW_PIN; // port=OUT
// przełacz port=0
ow_delay(3);
PORT(OW_PORT) &= ~(1 << OW_PIN); //port=IN
ow_delay(7); // poczekaj na slave'a az przejmie kontorle i:

tmp = PIN(OW_PORT) & (1<<OW_PIN); // odczytaj stan

ow_delay(80); // poczekaj na bezpieczny czas zakonczenia trnasmisji bitu

return tmp;
}

// --------------------------------------
// --------------------------------------
// -------- funkcje główne
// --------------------------------------
// --------------------------------------

void ow_init(void) {
DDR(OW_PORT) &= ~(1 << OW_PIN);
PORT(OW_PORT) |= 1 << OW_PIN;
}

uint8_t ow_reset(void) {
uint8_t tmp;

DDR(OW_PORT) |= 1 << OW_PIN;
PORT(OW_PORT) &= ~(1 << OW_PIN);
// 1W - RESET PULSE
ow_delay(500); // delay 500us
// teraz przelacz port na wejscie i sprawdz czy cos sie dziej
DDR(OW_PORT) &= ~(1 << OW_PIN); // port=IN
PORT(OW_PORT) |= 1 << OW_PIN; // port=1 (pull-up)
ow_delay(30); // poczekaj az slave przjemie kontorle nad linia i sciągnie
ją do masy
tmp = PIN(OW_PORT) & (1 << OW_PIN); // odczytaj jeślo tmp=0 to jest coś na
1w Smile
// jeszcze sobie poczekamy...
ow_delay(500);
return tmp;
}

void ow_write_byte(uint8_t data) {
uint8_t tmp;
for (tmp=0;tmp<8;tmp++) {
ow_write_bit(data & 0x01);
data >>= 1;
}
}

uint8_t ow_read_byte(void) {
uint8_t tmp, tmp2=0;
for (tmp=0;tmp<8;tmp++) {
tmp2 |= (ow_read_bit() << tmp);
}
return tmp;
}
</code>

Z notą w ręce sprawdziłem 2x ow_write_bit i ow_read_bit czy są dobrze i
czasy są też w granicach tak więc nie mam już pomysłu. A znowu kopiowanie
czyjegoś kodu nie spacjalnie lubię, "bo" preferuję się czegoś nauczyć.
Aha F_CPU=8MHz i MCU=attiny2313

--
Saper/nolin11
majl:nolin11_USUN_TO_@interia.pl
gg:4476700

T.M.F.
Guest

Sat May 19, 2007 8:06 am   



Quote:
Może zjadzie się osoba co mogła rzucić by okiem:
code unit="1wire.c"
void ow_delay(uint16_t t) {
while (t>0) {
// ~250ns
asm volatile("nop":Smile;
asm volatile("nop":Smile;
// ~250ns
asm volatile("nop":Smile;
asm volatile("nop":Smile;
// ~250ns
asm volatile("nop":Smile;
asm volatile("nop":Smile;
// ~250ns
asm volatile("nop":Smile;
asm volatile("nop":Smile;
// + --- " --- = 1us
--t;
}
}
Jaki masz zegar? Wnioskuje, ze 8MHz? Moze lepiej skorzystac z delay z

biblioteki standardowej gcc?


Quote:
uint8_t ow_read_bit(void) {
static uint8_t tmp;

PORT(OW_PORT) &= ~(1 << OW_PIN); // port=0
DDR(OW_PORT) |= 1 << OW_PIN; // port=OUT
// przełacz port=0
ow_delay(3);
PORT(OW_PORT) &= ~(1 << OW_PIN); //port=IN
^^^^^^^^^^^^^

A tu chyba ma byc DDR, a nie port. Bo tak wystawiasz silne 0 na
magistrale i nie dajesz mozliwosci wymuszenia stanu przez slave 1-wire.

Quote:
ow_delay(7); // poczekaj na slave'a az przejmie kontorle i:
Troche za krotko, bezpieczniej bedzie poczekac z 15us, bo 1-wire co

prawda szybciej zwykle wystawia wartosc, ale nie zapominaj, ze szyna
pracuje z pull-upem i potrzebuje troche czasu na przejscie z 0 do 1.
Quote:

tmp = PIN(OW_PORT) & (1<<OW_PIN); // odczytaj stan

ow_delay(80); // poczekaj na bezpieczny czas zakonczenia trnasmisji bitu
Bezpieczniej bedzie czekac az pojawi sie ponownie "1". To ma tez ta

kozysc, ze mozesz skrocic czas transmisji bitu "1", co ci przyspieszy
cala transmisje po 1-wire.

Quote:
return tmp;
}

// --------------------------------------
// --------------------------------------
// -------- funkcje główne
// --------------------------------------
// --------------------------------------

void ow_init(void) {
DDR(OW_PORT) &= ~(1 << OW_PIN);
PORT(OW_PORT) |= 1 << OW_PIN;
}

To nie blad, ale mozna zastosowac maly myk. Wpisujac 0 do port,
wystawianie 0 lub 1 na 1-wire bedzie polegalo po prostu na przelaczaniu
tylko DDR. Czyli DDR 1->out, na wyjsciu masz 0, jesli chcesz 1 to DDR=0
i szyna jest w stanie "1" utrzymywanym przez zewnetrzny pull=up.

Quote:

uint8_t ow_reset(void) {
uint8_t tmp;

DDR(OW_PORT) |= 1 << OW_PIN;
PORT(OW_PORT) &= ~(1 << OW_PIN);
// 1W - RESET PULSE
ow_delay(500); // delay 500us
// teraz przelacz port na wejscie i sprawdz czy cos sie dziej
DDR(OW_PORT) &= ~(1 << OW_PIN); // port=IN
PORT(OW_PORT) |= 1 << OW_PIN; // port=1 (pull-up)
ow_delay(30); // poczekaj az slave przjemie kontorle nad linia i sciągnie
ją do masy
tmp = PIN(OW_PORT) & (1 << OW_PIN); // odczytaj jeślo tmp=0 to jest coś na
1w Smile

Tu musisz poczekac az szyna po 0 wroci do 1, inaczej pierwsze transmisje
po 1-wire moga trafic jeszcze na presence pulse.

Quote:
// jeszcze sobie poczekamy...
ow_delay(500);
return tmp;
}

void ow_write_byte(uint8_t data) {
uint8_t tmp;
for (tmp=0;tmp<8;tmp++) {
ow_write_bit(data & 0x01);
data >>= 1;


Dodaj male opoznienie. Bo write_bit konczy sie szybko i jesli wystawia
"0" to szyna przed nastepnym bitem moze nie zdazyc wrocic do "1".

Quote:
}
}

uint8_t ow_read_byte(void) {
uint8_t tmp, tmp2=0;
for (tmp=0;tmp<8;tmp++) {
tmp2 |= (ow_read_bit() << tmp);

Tutaj analogicznie, read_bit nie czekasz az szyna wroci do "1" i jesli
ds dluzej trzyma niz 80us szyne to masz kaszane.

Quote:
}
return tmp;
}
/code

--

Inteligentny dom - http://idom.wizzard.one.pl
Teraz takze forum dyskusyjne
Zobacz, wyslij uwagi, dolacz sie do projektu.

Saper/nolin11
Guest

Sat May 19, 2007 10:32 pm   



T.M.F. wrote:
Quote:
Może zjadzie się osoba co mogła rzucić by okiem:

PORT(OW_PORT) &= ~(1 << OW_PIN); //port=IN
^^^^^^^^^^^^^
A tu chyba ma byc DDR, a nie port. Bo tak wystawiasz silne 0 na
magistrale i nie dajesz mozliwosci wymuszenia stanu przez slave 1-wire.

no fakt (już późno jak pisałem)... ale to i tak nic nie zmieniło wciąż to
samo (0x08 odczytuje :/ - sprawdziałm na bascomie czy układ dobry - działa)

Quote:

}

To nie blad, ale mozna zastosowac maly myk. Wpisujac 0 do port,
wystawianie 0 lub 1 na 1-wire bedzie polegalo po prostu na przelaczaniu
tylko DDR. Czyli DDR 1->out, na wyjsciu masz 0, jesli chcesz 1 to DDR=0
i szyna jest w stanie "1" utrzymywanym przez zewnetrzny pull=up.

Widziałem to w innych modułach które podglądałem.

Poprawiłem to i kod wrzuciłem na serwer:
http://nolin11.w.interia.pl/1w/

Jeszcze raz jutro porównam z innym kodem (głównie czasy).


--
Saper/nolin11
majl:nolin11_USUN_TO_@interia.pl
gg:4476700

Saper/nolin11
Guest

Sun May 20, 2007 9:45 pm   



Saper/nolin11 wrote:
Quote:
T.M.F. wrote:
Może zjadzie się osoba co mogła rzucić by okiem:

PORT(OW_PORT) &= ~(1 << OW_PIN); //port=IN
^^^^^^^^^^^^^

TMF masz browarka u mnie Smile za błąd.
I moim problemem jednak były czasy za długie zbytnio opierałem się na
wyliczeniach czasu ,a przecież wywołanie ow_delay, dekrementacja czasu,
warunek sprawdzenia t>0 to dodatkowe takty tak więc czasy skróciłem mocno i
działa Smile) jak ktoś chętny to się podziele kodem. Sprawdzny kod na ds2401,
ds2405 i ds1990. Sprawdzałem tylko komendę 0x33 ale z innymi też powinno
działąć.

Chyba udało mi siędopieścić czasy tak że mi działają wszystkie ukłądy jakie
mam i przy zmianie kwarcu zmieniam tylko ilość nop'ów w ow_delay()

--
Saper/nolin11
majl:nolin11_USUN_TO_@interia.pl
gg:4476700

Saper/nolin11
Guest

Mon May 21, 2007 6:45 pm   



Saper/nolin11 wrote:
Quote:
Saper/nolin11 wrote:
T.M.F. wrote:
Może zjadzie się osoba co mogła rzucić by okiem:

PORT(OW_PORT) &= ~(1 << OW_PIN); //port=IN
^^^^^^^^^^^^^

TMF masz browarka u mnie Smile za błąd.
I moim problemem jednak były czasy za długie zbytnio opierałem się na
wyliczeniach czasu ,a przecież wywołanie ow_delay, dekrementacja czasu,
warunek sprawdzenia t>0 to dodatkowe takty tak więc czasy skróciłem
mocno i działa Smile) jak ktoś chętny to się podziele kodem. Sprawdzny kod
na ds2401, ds2405 i ds1990. Sprawdzałem tylko komendę 0x33 ale z innymi
też powinno działąć.

Chyba udało mi siędopieścić czasy tak że mi działają wszystkie ukłądy
jakie mam i przy zmianie kwarcu zmieniam tylko ilość nop'ów w ow_delay()

Ok. źródełko tutaj:
http://www.del2el.friko.pl/Projects/Stuff/index.php?pid=4 tylko serwer
"zasrywa" strone reklamami :/ troche



--
Saper/nolin11
majl:nolin11_USUN_TO_@interia.pl
gg:4476700

T.M.F.
Guest

Mon May 21, 2007 7:02 pm   



Quote:
Chyba udało mi siędopieścić czasy tak że mi działają wszystkie ukłądy
jakie mam i przy zmianie kwarcu zmieniam tylko ilość nop'ów w ow_delay()

Ok. źródełko tutaj:
http://www.del2el.friko.pl/Projects/Stuff/index.php?pid=4 tylko serwer
"zasrywa" strone reklamami :/ troche

Jakies info o licencji na jakiej to udostepniasz dodaj, bo takie czasy,
ze strach cos sciagac z netu Smile
Dobra robota, tylko dodaj jeszcze SearchROM i MatchROM (to drugie latwe
do zaimplementowania). Bo bez tego trudno z tego korzystac. No i jesli
chce ci sie bawic przerob te wymuszanie stanow tak, zeby wystarczylo
zmieniac DDR, bez PORT, zawsze to pare bajtow mozna zaoszczedzic.
Ale gratuluje roboty.


--
Inteligentny dom - http://idom.wizzard.one.pl
Teraz takze forum dyskusyjne
Zobacz, wyslij uwagi, dolacz sie do projektu.

Saper/nolin11
Guest

Mon May 21, 2007 11:19 pm   



T.M.F. wrote:
Quote:
Chyba udało mi siędopieścić czasy tak że mi działają wszystkie ukłądy
jakie mam i przy zmianie kwarcu zmieniam tylko ilość nop'ów w
ow_delay()

Ok. źródełko tutaj:
http://www.del2el.friko.pl/Projects/Stuff/index.php?pid=4 tylko serwer
"zasrywa" strone reklamami :/ troche

Jakies info o licencji na jakiej to udostepniasz dodaj, bo takie czasy,
ze strach cos sciagac z netu Smile

Skoro wrzuciłem to rób co chcesz Smile nie mam nic przeciwko Smile)

Quote:
Dobra robota, tylko dodaj jeszcze SearchROM i MatchROM (to drugie latwe
do zaimplementowania). Bo bez tego trudno z tego korzystac. No i jesli

Sam napisz Smile) i wklej kawałek kodu tutaj Smile) do doklejej do tego co już
jest Smile)

Quote:
chce ci sie bawic przerob te wymuszanie stanow tak, zeby wystarczylo
zmieniac DDR, bez PORT, zawsze to pare bajtow mozna zaoszczedzic.

EEE tak jest przejżyściej, wiem można zmienić głównie ow_write_bit() na
troche szybszą ale i tak narazie używam dużych procesorów (m48, m32, m8535,
,a do tiny2313 z obsługą lcd wejdzie i zostanie jeszcze ze 600b wolnego
Smile) )

Quote:
Ale gratuluje roboty.

dziękuje Smile)

elektroda NewsGroups Forum Index - Elektronika Polska - Problem z odczytem danych z 1-Wire przy użyciu AVR-GCC - potrzebna analiza kodu

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map