logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.
REKLAMA
  • #1 6873449
    20rafalo
    Poziom 19  
    WITAM
    Przeczytałem już trochę kursów odnośnie AVR.
    Mam jednak mętlik w głowie. Otóż po co jest DDRB (w programach często w parze) z PORTB?
    PORTB jedt dla mnie jasny. np:

    Cytat:
    for(i=0;i<8;i++)
    {
    PORTB &=~(1<<i); //gasi kolejno diody
    delay_ms(50);
    }

    A po co jest DDRB w programach, pn


    Wiem, że jedno bez drugiego nie może być.
    Proszę o wyrozumiałość i wyjaśnienie tego...
    Z góry dziękuję.
  • REKLAMA
  • Pomocny post
    #2 6873470
    mirekk36
    Poziom 42  
    hyhyhy dobre pytanie - ale gdybyś gdziekolwiek sobie doczytał - bo to najbardziej podstawowe z podstawowych informacji - to byś zobaczył , że

    trzeba chyba poszczególne piny procka ustawić tak żeby były albo wejściem albo wyjściem ;)

    .... przecież żeby wysterować diodę LED musisz podać jakiś sygnał na wyjście prawda ? to chyba dla ciebie jasne?

    .... ale żeby sprawdzić stan np czy klawisz jest wciśnięty to trzeba sprawdzić na wejściu

    do tego służy właśnie DDR - ustawianie kierunku działania poszczególnych pinów protów procka

    jeśli ustawisz na 0 (tak jest domyślnie po włączeniu) to są one wejściami

    a jesli ustawisz DDRx na 1 to robisz z danego pinu(portu) wyjście
  • Pomocny post
    #3 6873928
    m.bartczak
    Poziom 16  
    Bardzo polecam dokumentację do AVR :)

    Ale ponieważ jest po angielsku, można też natknąć się w sieci na jej polskie tłumaczenie:

    Dokumentacja ATMega16 po polsku

    - Jak widać materiały z laborek czasami są przydatne :)

    --- snapshot z tej dokumentacji:

    Konfigurowanie cyfrowych portów I/O
    Bity DDxn w rejestrze DDRx określają kierunek pracy pinu. Wpisana tam wartość 1 powoduje pracę pinu Pxn jako wyjściowy, 0 jako wejściowy.

    Wpisanie 1 do PORTxn podczas, gdy pin skonfigurowany jest jako wejście, powoduje włączenie rezystora pull-up. Wartość 0 spowoduje jego wyłączenie. Skonfigurowanie pinu jako wyjście automatycznie odłączy rezystor pull-up.

    W czasie stanu resetu mikrokontrolera
    lub gdy nie pracuje zegar, piny są w trójstanowe.

    Wpisanie 1 do PORTxn, podczas gdy pin skonfigurowany jest jako wyjście, spowoduje ustawienie stanu wysokiego. Wpisanie 0 ustawi stan niski.

    Ustawienie bitu PUD w rejestrze SFIOR wyłącza rezystory pull-up we wszystkich portach, bez względu na ustawienie DDxn i PORTxn.

    Moderowany przez tmf:

    Poprawiłem nieaktywny link i dodałem dokumentację jako załącznik na przyszłość.

  • REKLAMA
  • #6 6874738
    20rafalo
    Poziom 19  
    Dla Ciebie może być pierdoła, ale dla mnie nie! Pisałem że to po prostu mi gdzieś umknęło podczas lektury.
    Freddie Chopin z praktyki pewnie wiesz że proste rzeczy czasem zaskakują i stają się trudne. Człowiek rozwiązując prosty problem często wybiera trudne drogi...
  • #7 6874993
    rpal
    Poziom 27  
    Oświadczam że ja czytam. I ostatnio ta lektura tak mnie zafrapowała że porównałem opis od dwóch takichsamych pamięci, jedna pochodziła od Atmela druga od Microchipa. Przyznam że Atmel zrobił to bardziej łopatologicznie. Może dobrze jest czytać między wierszami , tak jak to bywało za komuny :)
  • #8 6875893
    kamyczek
    Poziom 38  
    DDRX to rejestr kierunku porty który ustala czy port X jest wejściem czy wyjściem.
    PORTX w przypadku wyjścia ustawia stan na porcieX.
    PORTX w przypadku wejścia odpowiada za podciąganie wejścia do VCC
    PINX bada stan na wyprowadzeniu portuX
  • REKLAMA
  • #9 6941902
    manski
    Poziom 23  
    witam , żeby nie zakładać nowego wątku chciałem się zapytać o podobną sprawę choć trochę bardziej skomplikowaną , zachciało mi się zbudować do samochodu emulator oryginalnego radia mitsubishi na ATmega8 z kwarcem 16 mHz ( żeby zastąpić przycisk DISP z radia oraz wyświetlać na wyświetlaczu komputera swoje teksty ) , zrobiłem sprzęt do rozczajenia oryginalnej komunikacji RADIO-WYŚWIETLACZ , i juz wiem na czym polega owa komunikacja ( trzy piny MBUSY , SERIAL CLOCK , SERIAL DATA pracują jako dwukierunkowe - raz nadają raz odbierają w obu urządzeniach jest wyjście typu otwarty kolektor ) ale właśnie :czy za każdym razem w zależności od tego czy chcę nadawać czy odbierać muszę zmieniać wpisy w rejestrze DDR czy można pozostawić na stałe jako wyjście ?, 2. czy w bascomie można zmieniać stan dwóch pinów na raz ? ( bo można pojedynczo i można cały port 8 bitów , ale ja potrzebuję dwa ( serial data i serial clock ) bo dane "idą" synchronicznie z zegarem , a jak zmieniam pojedynczo to zawsze jeden impuls jest pierwszy .
  • #10 6942074
    H0miczek
    Poziom 20  
    Musisz zmieniac ;]
    Co do dwóch naraz (załóżmy ze to B2 i B3): DDRB&=~0xC (wejscie) lub DDRB|=0xC (wyjscie).
    Tylko nie wiem czy w bascomie da sie tak zapisac. Jak sie nie da to: DDRB=DDRB|0xC
  • #11 6942662
    janbernat
    Poziom 38  
    W Bascomie ( i w każdym innym języku) można napisać np tak:

    DDRB=&B01010101
    lub tak
    DDRB=&B11110000

    Jest to zapis dwójkowy ale może być szesnastkowy lub dziesiętny.

    Wpisanie 0 ustawia dany pin jako wejście a 1 jako wyjście.

    Oznacza to wpisanie JEDNOCZEŚNIE do rejestru sterującego portem jakim jest np. rejestr DDRB nowego stanu określającego który pin jest wejściem a który wyjściem.
  • #12 6942747
    H0miczek
    Poziom 20  
    Zgadza sie, ale jak wpiszesz np DDRB|=0xC (czy dla bascoma DDRB=DDRB|&HC ?) to modyfikujesz tylko 2 piny (ustawiasz w DDR jedynki czyli skonfigurujesz jako wyjscia) i nie obchodzi Cie czy reszta byla wyjsciami czy wejsciami. Chyba o to chodzilo, nie? ;]
  • #13 6942797
    manski
    Poziom 23  
    janbernat napisał:
    W Bascomie ( i w każdym innym języku) można napisać np tak:

    DDRB=&B01010101
    lub tak
    DDRB=&B11110000


    to oczywiste ale , DDRB=&B11110000 konfiguruje cały port na raz ( wszystkie piny ) ale jeśli ja chcę zmienić stany tylko dwóch , nie ruszając innych , poza tym czy muszę ustawiać koniecznie piny jako wyjściowe gdy chcę wysyłać dane może do wysyłania zmieniać stan pinu rozkazem PORTB= , a czytać poprzez pinb.x = ?
  • REKLAMA
  • #14 6942831
    H0miczek
    Poziom 20  
    Aaaa, czy ja piszę po chińsku?
    znaczek "|" (OR) ustawia jedynki w DDR we wskazanym miejscu (tylko tam gdzie w ORowanej wartosci wpiszesz jedynki) i nie rusza konfiga innych pinów. tym sposobem zmieniasz na wyjscia dokładnie te piny co chcesz zmienić.
    Jak chcesz mieć wejscia to zerujesz (ANDujesz) odpowiednie bity.
    I tak, musisz ustawiać jako wyjściowe..
  • #15 6943103
    janbernat
    Poziom 38  
    Poczytaj w helpie do Bascoma by ZbeeGin o maskowaniu, ustawianiu i zmianie na przeciwną wartość bitów.
    Albo w podręczniku do C.
    | w C to jest OR w Bascomie.
    AND XOR w Bascomie to nie pamiętam jak jest w C.
    Bierzesz stan DDRB jaki jest już ustawiony.
    Do zmienna1 wpisujesz co potrzebujesz.
    Piszesz:
    zmienna2=zmienna1 AND DDRB
    DDRB=zmienna2.
    I tak jak napisała HOmiczek - trzeba przy takiej transmisji zmieniać piny na we-wy.
    Odczytanie pinb.x gdy jest on ustawiony jako wyjście spowoduje że odczytasz stan w jakim go poprzednio ustawiłeś -1 lub 0- a nie stan odczytu wejścia.
  • #16 6969761
    manski
    Poziom 23  
    dzięki za pomoc , zrobiłem to tak :
     
    Slijbajt:
    Wartosc = Portc
    Kierunek = Ddrc
    For Razy = 7 To 0 Step -1
    Wartosc.5 = 0
    Kierunek.5 = 1
    Wartosc.4 = Bajt.razy
    Kierunek.4 = Not Bajt.razy
    Portc = Wartosc
    Ddrc = Kierunek
    Waitus 7                                                   
    Ddrc.5 = 0
    Portc.5 = 1
    Waitus 1                                                    
    Next Razy
    Waitus 6                                                   
    Ddrc.5 = 0 : Portc.5 = 1                                   
    Waitus 5
    Ddrc.4 = 0 : Portc.4 = 1                                    
    Return
    

    i w zasadzie działa prawidłowo ale , gdy zmieniam stan zegara z niskiego na wysoki mam wstawione waitus 1 i to też jest za dużo , obliczenia warunków pętli trwają tak długo że nawet bez tego opóźnienia jest za długo ( ponad 7 usek dla kwarcu 16 MHz ) , jak zmienić część kodu zawartą pomiędzy for i next na assembler , na procedurę wywoływaną z parametrami bajt , waitus a ( zamiast waitus 7 - do dopasowania do czasu trwania stanu niskiego na clock ) , waitus b ( zamiast waitus 1 - do dopasowania czasu trwania stanu wysokiego na clock ) , clock to linia portc.5 , reszta może być w bascomie , bo tylko ta część programu się nie wyrabia , jak zrezygnuję z pętli i wstawiam osiem jednakowych sekwencji po kolei to się wyrabia , ale strasznie zajmuje pamięć , sama w/w procedura bez pętli to ponad 10% w mega8
  • #17 6973109
    janbernat
    Poziom 38  
    Umieszczanie "wait" w bascomie, delay w C itd. W PRZERWANIU jest bardzo złym nawyczkiem.
    W pętli głównej też-ale czasem można to z bólem serca wytrzymać.
    Gdy program wchodzi w "wait"-czyli w pustą pętlę- to "głuchnie" na wszystkie sygnały.
    Nie tkwij w złych nawyczkach- i póki czas je zmień.
  • #18 6998672
    Limonit
    Poziom 13  
    manski napisał:
    ale właśnie :czy za każdym razem w zależności od tego czy chcę nadawać czy odbierać muszę zmieniać wpisy w rejestrze DDR czy można pozostawić na stałe jako wyjście ?

    Tego typu linią z OC należałoby sterować trochę inaczej. Linia taka jest podciągnięta rezystorem do zasilania. Nadaje się na niej zmieniając właśnie kierunek linii, a na wyjściu na stałe stan niski. Jedynka powstaje, kiedy linia (PORT) jest wejściem, a zero kiedy wyjściem. Słucha się takiej linii normalnie.
    Taki układ zabezpiecza przed konfliktem elektrycznym, kiedy to oba urządzenia zaczęłyby nadawać jednocześnie (wystawienie na linię różnych stanów nie spowoduje uszkodzeń). Przypominam tę sztuczkę - może się przydać.
REKLAMA