logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATTINY2313][c]PINx i sprawdzenie if

smajlas 22 Paź 2010 00:51 1411 5
REKLAMA
  • #1 8648729
    smajlas
    Poziom 12  
    Witam
    Napisałem wsad, w którym ma zostać obsłużony pilot (w systemie - prawdopodobnie JVC, nie wiem na pewno - przebiegi sprawdziłem na oscyloskopie). Ale mniejsza z tym. Po długotrwałych bojach okazało się, że PINB, jak również PIND nie działa.
    Do D0 podłączyłem switch, mam możliwość ustawienia tam określonego stanu.
    Sprawdzam stan na porcie B2 i B3, niestety, bez względu na to, co zadane jest na D0 to mam odpowiedzi tylko na B3. I bez względu na to, czy na D0 jest jedynka, czy zero, mam ZAWSZE odpowiedź na B3. Ktoś spotkał się z czymś takim?

    Część kodu:
    
    DDRB=0x0C;		// B jako WE, tylko B3 i B2 wy 0000 1100
    DDRD=0x78;		// D ma 0111 1000, czyli tylko D3,D4iD5 i D6 Wy.
    PORTB=0x0C;		// B2 i B3 jedynki
    PORTD=0x00;		// D bez podc.
    
    //--- sprawdzanie stanu pinu--
    if (PIND0)
    PORTB^=0x04; //0000 0100 B2
    else
    PORTB^=0x08; //0000 1000 B3



    Jak dla mnie - wszystko ok, połączenia sprawdziłem, stany wysokie/niskie na D0 są jak sobie ustawię.
    Nie wiem, czy nie mąci wszystkiego sprawa taka, że ten warunek sprawdzany jest podczas realizacji przerwania - ale jak zaczynam obsługę przerwania, to je wyłączam (cli).

    Sprawdzałem też sprawdzanie stanu na innych portach, tj na B0, oraz B1. Reakcje takie same, więc raczej to nie wina padniętego wejścia.
  • REKLAMA
  • REKLAMA
  • Pomocny post
    #3 8648807
    Braindeath
    Poziom 11  
    smajlas napisał:
    Witam

    Część kodu:
    
    DDRB=0x0C;		// B jako WE, tylko B3 i B2 wy 0000 1100
    DDRD=0x78;		// D ma 0111 1000, czyli tylko D3,D4iD5 i D6 Wy.
    PORTB=0x0C;		// B2 i B3 jedynki
    PORTD=0x00;		// D bez podc.
    
    //--- sprawdzanie stanu pinu--
    if (PIND0)
    PORTB^=0x04; //0000 0100 B2
    else
    PORTB^=0x08; //0000 1000 B3



    Jak dla mnie - wszystko ok, połączenia sprawdziłem, stany wysokie/niskie na D0 są jak sobie ustawię.
    Nie wiem, czy nie mąci wszystkiego sprawa taka, że ten warunek sprawdzany jest podczas realizacji przerwania - ale jak zaczynam obsługę przerwania, to je wyłączam (cli).

    Sprawdzałem też sprawdzanie stanu na innych portach, tj na B0, oraz B1. Reakcje takie same, więc raczej to nie wina padniętego wejścia.


    Trochę mało czytelny ten kod, ale pierwsze co się rzuca w oczy, to w warunku if masz

    mam nadzieje, że masz to gdzieś wcześniej zdefiniowane, np jako
    
    #define PIND0 (PIND & (1<<PD0))
    


    Polecam Ci stosowanie, zamiast
    
    DDRB=0x0C;		// B jako WE, tylko B3 i B2 wy 0000 1100
    DDRD=0x78;		// D ma 0111 1000, czyli tylko D3,D4iD5 i D6 Wy.
    PORTB=0x0C;		// B2 i B3 jedynki
    PORTD=0x00;		// D bez podc.
    
    //czegoś takiego
    DDRB=(1<<PB3)|(1<<PB2);
    DDRD=(1<<PD6)|(1<<PD5)|(1<<PD4)|(1<<PD3);
    PORTB=(1<<PB3)|(1<<PB2);
    // PORTD itak po resecie jest ustawiany na 0x00, więc można pominąć
    //
    // niektórzy preferują zamiast (1<<X) zapis _BV(X), ostatecznie, w C jest jeszcze zapis bitowy w stylu 0b00001100 zamiast 0x0C (mało czytelnego)
    


    Pozdrawiam
  • REKLAMA
  • Pomocny post
    #4 8649525
    gaskoin
    Poziom 38  
    smajlas napisał:

    Nie wiem, czy nie mąci wszystkiego sprawa taka, że ten warunek sprawdzany jest podczas realizacji przerwania - ale jak zaczynam obsługę przerwania, to je wyłączam (cli).


    Obsługa ISR automatycznie na czas jego wykonania blokuje przerwania więc nie ma potrzeby blokować ich po raz drugi.


    Braindeath napisał:

    Trochę mało czytelny ten kod, ale pierwsze co się rzuca w oczy, to w warunku if masz

    mam nadzieje, że masz to gdzieś wcześniej zdefiniowane, np jako
    
    #define PIND0 (PIND & (1<<PD0))
    




    Standardowo w avrlibc PIND0 jest już zdefiniowany w bibliotekach jako:

    #define    PIND0     0


    więc warunek jaki napisał autor nie jest sprawdzany nigdy. Rozwiązanie, jak to ma wyglądać podał kolega wyżej, z resztą w przytoczonym przeze mnie cytacie też się ono znajduje.

    Możesz też wrzucić cały kod, bo wydaje mi się, że błędów będzie więcej
  • REKLAMA
  • Pomocny post
    #5 8650863
    janbernat
    Poziom 38  
    A nie lepiej użyć gotowego makra:
    bit_is_clear(sfr, bit )
    albo:
    bit_is_set(sfr, bit )
    P.S.
    #include<avr/sfr_defs.h>
  • #6 8728380
    smajlas
    Poziom 12  
    Rzeczywiście, nie miałem zdefiniowanego PIND0, miałem po prostu nadzieję, że PIND0 to rejestr, który będzie można po prostu odczytać, czyli wrzucając go do warunku, będzie możliwe szybkie sprawdzenie stanu na pinie.
    Dziękuję za pomoc.
REKLAMA