I2C mam za sobą i próbowałem dziś napisać sterownik 1-Wire. Na płytce ewaluacyjnej mam MEGĘ16 (16Mhz), DS18B20, który na pewno działa. Problemem u mnie jest wątpliwa inicjalizacja i brak komunikacji. Co może być źle ?
Napisałem "biblioteczkę", są komentarze, powinno się wygodnie czytać.
Biblioteczki używam :
Wyniki readByte1Wire(); są zupełnie bzdurne. W większości 255'tki.
Napisałem "biblioteczkę", są komentarze, powinno się wygodnie czytać.
#include <avr/io.h>
#include <util/delay.h>
////////////////////////////////
// makrodefinicje///////////////
#define N1Wire 0
#define PORT1WireIn PINA
#define PORT1WireOut PORTA
#define SET1WireOut DDRA|=(1<<N1Wire) // DDRX jako wyjscie
#define SET1WireIn DDRA&=~(1<<N1Wire) // DDRX jako wejscie
////////////////////////////////
unsigned char reset1Wire(void) {
unsigned char counter=10;
////
SET1WireOut; // DDRX jako wyjscie
PORT1WireOut&=~(1<<N1Wire); // w stanie niskim
_delay_us(500); // przynajmniej na 480us, nastepnie
SET1WireIn; // DDRX jako wejscie
PORT1WireOut|=(1<<N1Wire); // w stanie wysokim
_delay_us(50); // relaksacja pinow
while((PORT1WireIn&(1<<N1Wire)) && (counter>0)) { // sprawdzam, czy pomimo pullup'a magistrala 0
counter--; // i licznik >0
_delay_us(30);
}
_delay_us(500);
if (counter<=0) { // nie zgloszenie sie w czasie jest rownoznaczne
return 0; // z brakiem aktywnego czujnika na magistrali
} else {
return 1;
}
}
////////////////////////////////
void sendByte1Wire(unsigned char data) {
for(int i=0;i<8;i++) { // dla kolejnych bitow
SET1WireIn; //
_delay_us(1); // przerwa >= 1us
SET1WireOut; // ustaw port jako wyjscie
PORT1WireOut&=~(1<<N1Wire); // w stanie niskim
_delay_us(5); // poczekaj
if (data&(1<<i)) { // WYSYLAM logiczne 1
SET1WireIn; // zwalniam magistrale
PORT1WireOut|=(1<<N1Wire); // w stanie wysokim
_delay_us(50);
} else { // WYSYLAM logiczne 0
_delay_us(50); // >60us
SET1WireIn; // zwalniam magistrale
PORT1WireOut|=(1<<N1Wire); // w stanie wysokim
}
}
}
////////////////////////////////
unsigned char readByte1Wire() {
unsigned char bitTmp,data=0;
unsigned char counter=15;
for(int i=0;i<8;i++) { // dla kolejnych bitow
bitTmp=1; // zalozenie, ze bit tymczasowy wynosi 1 (x)
////
SET1WireIn;
_delay_us(1);
SET1WireOut; // port 1 Wire jako wyjscie
PORT1WireOut&=~(1<<N1Wire); // w stanie niskim
_delay_us(1);
SET1WireIn; // jako wejscie...
PORT1WireOut|=(1<<N1Wire); // w stanie wysokim
_delay_us(10);
//////////////////////////////////////
while((PORT1WireIn&(1<<N1Wire)) && (counter>0)) {
_delay_us(1); // poczekaj ->
counter--;
}
if (counter<=0) {
bitTmp = 1;
} else {
bitTmp = 0;
}
data|=(bitTmp<<i); // ustawienie odebranego bitu
//*/
//data|=((PORT1WireIn&(1<<N1Wire))<<i); // ustawienie odebranego bitu
_delay_us(60); // czekanie na koniec okresu odczytywania
}
return data;
}
////////////////////////////////
Biblioteczki używam :
unsigned char returned, returned1[8];
/////
returned=reset1Wire(); //-> dostaje sygnał presence
sendByte1Wire(0x33); // proszę o zameldowanie swojego numeru ROM
for(int x=0;x<8;x++) {
returned1[x]=readByte1Wire(); // -> zapisuje kolejno
}Wyniki readByte1Wire(); są zupełnie bzdurne. W większości 255'tki.
