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

[ATmega8][AVR-GCC]Odczyt wartosci z calego portu

Pajczi 18 Cze 2008 09:50 8750 21
REKLAMA
  • #1 5259411
    Pajczi
    Poziom 14  
    Mam problem z odczytaniem wartości całego portu co wydawać mogło by sie śmieszne ale po całej nocy spędzonej nad tym zdecydowałem się zadać to pytanie na elektrodzie. W czym rzecz : Chcę próbkować cały port D i ten wynik porównywać z wcześniejszym stanem PORTU D jeżeli coś się zmieni (XOR) to załączany jest timer itp itd . Jednocześnie wykorzystuję przerwanie której jest na porcie D - INT0 (myślę ze to sie nie kłóci zeby odczytywać stan portu ). W próbie desperacji sprawdzałem if'em czy PIND jest różny od zera i nawet gdy cały PORTD był wolny dioda sie zapalała czyli warunek się wykonywał. Inaczej było gdy tego if'a robiłem dla całego portu D wtedy dioda się nie paliła również gdy wymuszałem na którymś pinie stan wysoki poprzez dołączenie go do VCC .Jedynie poprawnie dioda sie zapała w warunku kiedy w programie wymusiłem stan wysoki poprzez przypisanie PORTD=0xFF wtedy działało tak jak należy ale mi zależy na zaczytaniu wartości z portu i reagowanie na zmiany na nim .
    Ustawienia portu mam takie :
    
    LEDDDR= 1<<LED  ; //Dioda na porcieB
    DDRD=0x00 ;//PORTD jako wyjście
    //PORTD=0xFF; //wtedy działa ale jak 0x00 i wymuszanie poprzez dołaczenie któregoś z PIND do VCC nie dziala :(
    if(PORTD)
       LEDPORT=_BV(LED);
    
  • REKLAMA
  • Pomocny post
    #2 5259441
    szelus
    Poziom 34  
    Aby sprawdzić stan wejścia czyta sie PIND, a nie PORTD.
  • REKLAMA
  • #3 5259468
    Pajczi
    Poziom 14  
    szelus napisał:
    Aby sprawdzić stan wejścia czyta sie PIND, a nie PORTD.


    To dlaczego jak zrobie if(PIND) dioda sie swieci choc do portu nic nie ma podlaczone ?
  • REKLAMA
  • Pomocny post
    #5 5259554
    szelus
    Poziom 34  
    Jeżeli nie masz włączonych pull-up-ów na porcie i port "wisi w powietrzu" to, z uwagi na wysoką imedancję wejściową, port "łapie" śmieci i przy odczycie masz przypadkowe wartości. Szansa, że odczytasz same zera i dioda zgaśnie jest raczej nikła.
    Jeżeli włączysz pull-up-y, to oczywiście wymusisz stan wysoki.
  • #6 5259564
    Pajczi
    Poziom 14  
    Tak słyszałem ale nawet gdy zrobię wcześniej przed if'em PORD=0x00 lub PIND=0x00 to dioda mi się zapli a niby ustalilem stan niski !!! W tym jest problem ze jakoś nie chce mi ładnie czytać tego PORTU a może ktoś ma przykłady obróbki takiego portu chętnie popatrzę jak to inni implementują

    Dodano po 2 [minuty]:

    szelus napisał:

    Jeżeli włączysz pull-up-y, to oczywiście wymusisz stan wysoki.

    Pull-up załącze poprzez wpisanie stanu wysokiego na port gdy to jest wejście czyli PORTD=0xFF; i teraz musze na każdym wymusic stan niski dobrze rozumiem ?? BO chyba tu jest mój błąd
  • #7 5259598
    szelus
    Poziom 34  
    Pajczi napisał:
    Tak słyszałem ale nawet gdy zrobię wcześniej przed if'em PORD=0x00 lub PIND=0x00 to dioda mi się zapli a niby ustalilem stan niski !!!

    Na PIND możesz pisać do woli ;) - jest tylko do odczytu.
    Jeżeli na PORTD wpiszesz 0, a jest ustawiony jako wejście, to tylko wyłączysz pull-up, ale nie wymusisz stanu niskiego.

    Cytat:

    Pull-up załącze poprzez wpisanie stanu wysokiego na port gdy to jest wejście czyli PORTD=0xFF; i teraz musze na każdym wymusic stan niski dobrze rozumiem ??

    Tu dobrze.
  • #8 5266852
    Pajczi
    Poziom 14  
    Witam to pięknie działa z tym odczytem portu, ale mam inny problem z tym związany, a mianowicie inicjuję przerwanie na INT0 zboczem narastającym:
    
    		GIMSK=_BV(INT0);
    		MCUCR=_BV(ISC01)|(ISC00);
    


    Po wejściu w przerwanie chciałbym zobaczyć kiedy port zmieni się na zero bo po zboczu narastającym przez parę chwil (wystarczająco długo (przebieg wypełnienie 20% f=100Hz) utrzymuje sie stan wysoki. Chciałbym odczytać w przerwaniu wartość PORTu a czytam dokładnie tak zmienna=PIND; i cały czas jest 0x00 nawet próbując tak że w przerwaniu po stanie portu różnym od 0 zapali sie dioda - to dioda się nie zapala :(
    
    if(PIND)LEDPORT=_BV(LED);
    

    Natomiast dioda się zapali jak zdejmę ten przebieg 100Hz z nóżki INT0 i za chwile (nie ma znaczenia kiedy) załączę go jeszcze raz do nóżki INT0 no ale wiadomo w urządzeniu nikt nie będzie czegoś takiego robił. Zastanawia mnie o co w tym chodzi.To mi przypomina taki problem z dyrektywą volatile przed zmienną. Tak jakby zmienna PIND była sobie gdzieś i w momencie wejścia do przerwania procesor nie załada jej zmiany.Chociaż tak nie do końca bo jak dotkniemy jeszcze raz nóżki to procek odczyta wartość różną od zera i zapali diodę. Po za przerwaniem jeżeli damy przebieg o częstotliwości zmian widocznych dla ludzkiego oka to widać, że dioda gaśnie (0x00) i zapala się (!0x00). Na 80%90% coś jest nie tak w przerwaniu zaznaczam że innego kodu w tym przerwaniu nie ma kod jest taki jak podałem czyli najprostszy !

    Już zauważyłem gdzie jest błąd :
    Cytat:
    MCUCR=_BV(ISC01)|(ISC00);
    :(:( Nieuwaga
  • #9 5269008
    ZbeeGin
    Poziom 39  
    szelus napisał:
    Na PIND możesz pisać do woli ;) - jest tylko do odczytu.

    Zależy w jakim procesorze. Nowsze ATMega wykonują wtedy dodatkową funkcję - Toggle. Zatem proszę nie pisać, że tylko do odczytu.
  • #10 5276633
    szelus
    Poziom 34  
    ZbeeGin napisał:
    Zależy w jakim procesorze. Nowsze ATMega wykonują wtedy dodatkową funkcję - Toggle. Zatem proszę nie pisać, że tylko do odczytu.

    Być może. Ale w tym wątku mówimy o ATmega8. A w nim jest tylko do odczytu.
  • #11 6285785
    Konto nie istnieje
    Konto nie istnieje  
  • #13 6288807
    Konto nie istnieje
    Konto nie istnieje  
  • #15 6288997
    Konto nie istnieje
    Konto nie istnieje  
  • #16 6289123
    szelus
    Poziom 34  
    Ale zadajesz pytania, na które odpowiedź znajdziesz w KAŻDEJ książce dotyczącej programowania w C i pewnie w każdym kursie internetowym. Wystarczy przeczytać jakie są dostępne operatory i jak działają. I chwilę pomyśleć.
    Korzystanie z forum nie zwalnia od samodzielnego myślenia.
  • #17 6289269
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #18 6289282
    Freddie Chopin
    Specjalista - Mikrokontrolery
    ta instukcja ktora przytoczyles raczej nie zrobi tego o co ci chodzi...

    piszesz teraz o symfonii C++... czy na AVRach stosujesz C++? czy kompilujesz swoj program przy uzyciu avr-cpp, czy moze avr-gcc?

    bit_is_clear() to nie zadna 'komenda' tylko makro z bibliotek standardowych z pakietu winavr.

    
    #define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit)))
    


    (opis z dokumentacji do avr-libc - czas sie z nia zaprzyjaznic)

    powiedzialem ci czego szukac, a ty dalej czekaj sobie na to, az ktos po raz milion-pierwszy napisze jak to zrobic. i gwarantuje ci, ze w KAZDYM kursie C (C++ tez) beda informacje o operacjach bitowych (and, or, xor). zreszta - wystarczyloby przejrzec 10 tematow o AVRach i bys znalazl tam stosowne przyklady...

    4\/3!!
  • #19 6289297
    Konto nie istnieje
    Konto nie istnieje  
  • #20 6289306
    Freddie Chopin
    Specjalista - Mikrokontrolery
    no to uzywaj sobie jej dalej [; nie wiem jaki to ma sens, zeby uzywac dwoch operacji logicznych, skoro wystarczy jedna. widac tak bardzo odrzuca cie od poszukania informacji o tych operacjach logicznych, ze wolisz stosowac cos czego w ogole nie rozumiesz.

    4\/3!!
  • #21 6289466
    Konto nie istnieje
    Konto nie istnieje  
  • #22 6289824
    kaktus_c++
    Poziom 18  
    chyba się jednak da
    a=0x01&(PIND>>n);
    gdzie n to numer pinu (od 0 do 7)
REKLAMA