Witam. Jako że nie chcę korzystać z gotowców, postanowiłem spróbować napisać obsługę dla transmisji 1Wire. Naskrobałem coś takiego:
Funkcje obsługi "1wire.h":
I proste ciało programu:
W pliku moje.h załączone są wszystkie niezbędne pliki, oraz definicje typów zmiennych:
Linia DQ znajduje się na PD0.
Sama obsługa typu odbierz bajt wyślij bajt wydają mi się w porządku, za to mam wrażenie że odbieram nie ten bajt co trzeba. Przy zmianie temperatury dostaję co prawda inne wyniki starszego bajtu, lecz młodszy bajt zawsze jest taki sam(10101010) oraz nie pasują one do tego czym powinny być. Rzekome bity znaku nie są takie same. Podam przykładowe odczyty z portu b (starszych bajtów, bo młodszy taki sam) np dla 20st: 11011010, 21st: 01101101, 22st: 01101110, 23st: 10110111. Aha no i cały ten grajdołek na razie istnieje tylko w symulatorze Proteusa.
Nie mam pojęcia co to za dziwadła. Z góry dzięki za ewentualną pomoc.
Dodano po 35 [minuty]:
Ustawiony był za krótki czas opóźnienia pomiędzy odczytem poszczególnych bitów w funkcji recivebyte() zmiana z 35 na 50 pomogła. Zamykam.
Funkcje obsługi "1wire.h":
#include <moje/moje.h> //Załącz potrzebne biblioteki
#define DDR1W DDRD //Rejestry specjalne portu wykorzystywanego do komunikacji 1wire
#define PORT1W PORTD //...
#define PIN1W PIND //...
#define DQ_MASK 0x01 //Gotowa maska pinu DQ
#define INITDQ PORT1W&=~(DQ_MASK); //Initializacja rejestru PORTx portu wykorzystywanego do komunikacji 1wire (stan niski)
#define DQOUT DDR1W|=(DQ_MASK); //Ustaw DQ jako wyjście
#define DQIN DDR1W&=~(DQ_MASK); //Ustaw DQ jako wejście
u08 init1w(void) //Initializacja transmisji (wyślij "RESET" i jeśli jest "PRESENCE PULSE" zwraca 0)
{
u08 ret;
INITDQ
DQOUT
_delay_us(600);
DQIN
_delay_us(70);
ret = (PIN1W&(DQ_MASK));
_delay_us(200); //Czekaj na zwolnienie linii
return ret; //Zwróć wynik poprawności initializacji (0 jeśli ok, 1 jeśli brak odpowiedzi)
}
void sendbyte(u08 data) //Wyślij bajt danych
{
u08 licznik;
INITDQ
for(licznik=0;licznik!=8;licznik++) //Wykonaj 8 razy
{
if((1<<licznik)&(data)) //Sprawdź bit danej o numerze "licznik"
{ //Jeśli jeden:
DQOUT
_delay_us(10);
DQIN
_delay_us(90);
} //Jeśli zero:
else
{
DQOUT
_delay_us(90);
DQIN
_delay_us(10);
}
_delay_us(50);
}
_delay_us(100);
}
u08 recivebyte(void) //Odbierz bajt danych
{
u08 licznik, data=0;
INITDQ
for(licznik=0;licznik!=8;licznik++) //Wykonaj 8 razy
{
DQOUT
_delay_us(2);
DQIN
_delay_us(10);
if(PIN1W&DQ_MASK) //Sprawdź odebrany bit, jeśli 1 ustaw odpowiedni bit zmiennej data, jeśli 0 nic nie rób
data|=(1<<licznik);
_delay_us(35); //Czekaj na zwolnienie linii
}
_delay_us(100);
return data; //Zwróć odebrane dane
}
I proste ciało programu:
#include "1wire.h"
ISR(INT0_vect)
{
init1w();
sendbyte(0xCC);
sendbyte(0x44);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
init1w();
sendbyte(0xCC);
sendbyte(0xBE);
recivebyte();
PORTB=recivebyte();
}
int main(void)
{
DDRB=0xFF;
PORTB=0x00;
PORTD|=(1<<2);
GICR|=(1<<INT0);
MCUCR|=(1<<ISC01);
sei();
while(1);
}
W pliku moje.h załączone są wszystkie niezbędne pliki, oraz definicje typów zmiennych:
typedef unsigned char u08; // 8 bitów bez znaku (int8_t)
typedef char s08; // 8 bitów ze znakiem (uint8_t)
typedef unsigned short u16; // 16 bitów bez znaku (int16_t)
typedef short s16; // 16 bitów ze znakiem (uint16_t)
typedef unsigned long u32; // 32 bity bez znaku (int32_t)
typedef long s32; // 32 bity ze znakiem (uint32_t)
typedef unsigned long long u64; // 64 bity bez znaku (int64_t)
typedef long long s64; // 64 bity ze znakiem (uint64_t)
Linia DQ znajduje się na PD0.
Sama obsługa typu odbierz bajt wyślij bajt wydają mi się w porządku, za to mam wrażenie że odbieram nie ten bajt co trzeba. Przy zmianie temperatury dostaję co prawda inne wyniki starszego bajtu, lecz młodszy bajt zawsze jest taki sam(10101010) oraz nie pasują one do tego czym powinny być. Rzekome bity znaku nie są takie same. Podam przykładowe odczyty z portu b (starszych bajtów, bo młodszy taki sam) np dla 20st: 11011010, 21st: 01101101, 22st: 01101110, 23st: 10110111. Aha no i cały ten grajdołek na razie istnieje tylko w symulatorze Proteusa.
Nie mam pojęcia co to za dziwadła. Z góry dzięki za ewentualną pomoc.
Dodano po 35 [minuty]:
Ustawiony był za krótki czas opóźnienia pomiędzy odczytem poszczególnych bitów w funkcji recivebyte() zmiana z 35 na 50 pomogła. Zamykam.