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

[C] [AVR] Obsługa rejestru '595

lord_dagoth 20 Lis 2008 15:16 2461 7
REKLAMA
  • #1 5761946
    lord_dagoth
    Poziom 25  
    Mam pytanie odnośnie obsługi rejestrów 74HC595. Mam trzy takie połączone w jeden dłuższy, którymi steruje ATMega32. Tutaj jest fragment schematu, na którym jest przedstawione tylko i wyłącznie podłączenie rejestrów i uC, pominąłem całą resztę (zasilanie, itp):

    [C] [AVR] Obsługa rejestru '595

    No i teraz nie wiem, czy poprawnie napisałem kod. Czy aby osiągnąć zbocze narastające, musze najpierw ustawić pin (wyjście) na 0, potem na jeden? I gdy znowu będę chciał podać zbocze narastające, to znowu zero i jeden? Czy mój kod jest poprawny? Póki co, jedyne co on ma robić to wysyłać do rejestru w nieskończoność ciąg 20 bitów, 01010101010101010101.

    #include <avr\io.h>
    
    int main (void)
    {
    	DDRB = 0xFF; //ustawienie portu B jako wyjścia
    	
    	PORTB =(1>>PINB1);//Ustawienie pinu PB1 na 0 (enable dla rejestru, active low)
            PORTB  = (1>>PINB3); //ustawienie zera dla pinu, które będzie taktowało przesuwanie rejestru
    	for(;;)
    	{
    		PORTB  = (1<<PINB0); //podanie jedynki na wejście szeregowe rejestru
    		PORTB  = (1<<PINB3); //przesunięcie jedynki (zboczem narastającym)
    		PORTB  = (1>>PINB3); //ustawienie zera 
    		
    		PORTB  = (1>>PINB0); //podanie zera na wejście szeregowe rejestru
    		PORTB  = (1<<PINB3); //przesunięcie zera (zboczem narastającym)
    		PORTB  = (1>>PINB3); //ustawienie zera
    		
    		// itd, aż wszystkie 20 bitów będzie przesuniętych
    		
    		PORTB  = (1<<PINB2); //przepisanie danych równoległych na wyjścia '595
    		PORTB  = (1>>PINB2); //ustawienie zera
    	}
    }


    Aha, tylko nie chodzi mi o rozwiązania dotyczące konstrukcji języka C czy coś w ten deseń (jak "wstaw to w pętle" :P ), bo w C dość dobrze umiem programować i z tym to rade sobie dam. Chodzi mi tylko o przepisanie tych bitów do rejestru :D
  • REKLAMA
  • Pomocny post
    #2 5764460
    wrealcon
    Poziom 11  
    Na początku SH (CLK) = 0. Wystawiasz bit na SER, SH leci na 1. Czekasz chwilke i spuszczasz SH na 0.
    Jak juz wrzucisz wszystkie bity, robisz jeden takt na linii ST (G) (0 -> 1; ...... ; 1 -> 0).

    Co do kodu, wez pod uwage, ze przypis do PORTB kasuje jego poprzednia zawartosc... Uzyj PORTB |= ...... do ustawienia, lub PORTB &= ~(....) do skasowania, np.:
    PORTB |= 2; - ustawia PB1. (wpisuje 1)
    PORTB &= ~2; kasuje PB1. (wpisuje 0)
    ten ostatni jest odpowiednikiem PORTB &= 253.
  • REKLAMA
  • Pomocny post
    #3 5764524
    Dr.Vee
    VIP Zasłużony dla elektroda
    lord_dagoth napisał:
    		PORTB  = (1<<PINB0); //podanie jedynki na wejście szeregowe rejestru
    		PORTB  = (1<<PINB3); //przesunięcie jedynki (zboczem narastającym)
    		PORTB  = (1>>PINB3); //ustawienie zera 
    		
    		PORTB  = (1>>PINB0); //podanie zera na wejście szeregowe rejestru
    		PORTB  = (1<<PINB3); //przesunięcie zera (zboczem narastającym)
    		PORTB  = (1>>PINB3); //ustawienie zera
    		
    		// itd, aż wszystkie 20 bitów będzie przesuniętych
    		
    		PORTB  = (1<<PINB2); //przepisanie danych równoległych na wyjścia '595
    		PORTB  = (1>>PINB2); //ustawienie zera

    Ciekawe podejście... ;)

    PINx to makra, zdefiniowane jako:
    #define PINB0 0
    #define PINB1 1
    #define PINB2 2
    /* itd */
    Jak widać operacja (1 >> PINx) nie ma sensu, bo dla wszystkich pinów oprócz PIN0 da wartość zero... Za to (1 << PINx) zwraca maskę bitów z pojedyńczym bitem ustawionym na pozycji odpowiadjącej danemu pinowi. Tej maski używasz do ustawienia/wyzerowania konkretnego bitu. Ponadto avr-libc definiuje makro _BV(x) - bit value - które robi dokładnie to samo.

    Pozdrawiam,
    Dr.Vee
  • REKLAMA
  • #4 5764605
    lord_dagoth
    Poziom 25  
    Swój kod oparłem na tym ze strony: http://www.windmeadow.com/node/20

    Ale poprawie wg. waszej sugestii, dzięki za pomoc ;)

    EDIT: Dobra, poczytałem trochę o tych operacjach logicznych w sąsiednim topic'u, i wyczarowałem coś takiego:
    #include <avr\io.h>
    
    int main (void)
    {
    	DDRB = 0xFF; //ustawienie portu B jako wyjścia
    	
    	PORTB &=~_BV(1);;//Ustawienie pinu PB1 na 0 (enable dla rejestru, active low)
    	PORTB &=~_BV(3);//ustawienie 0 dla zegara
    	PORTB &=~_BV(2);//ustawienie zera dla pinu odpowiedzialnego za przepisywanie
    
    	for(;;)
    	{
    		PORTB |=_BV(0); //podanie jedynki na wejście szeregowe rejestru
    		PORTB |=_BV(3); //przesunięcie jedynki (zboczem narastającym)
    		PORTB &=~_BV(3); //ustawienie zera 
    		
    		PORTB &=~_BV(0); //podanie zera na wejście szeregowe rejestru
    		PORTB |=_BV(3); //przesunięcie zera (zboczem narastającym)
    		PORTB &=~_BV(3); //ustawienie zera
    		
    		// itd, aż wszystkie 20 bitów będzie przesuniętych
    		
    		PORTB |=_BV(2); //przepisanie danych równoległych na wyjścia '595
    		PORTB &=~_BV(2); //ustawienie zera
    	}
    	return 0;
    }


    Teraz mniej więcej będzie ok? I Czy podczas taktowania rejestrów i zwalniania zatrzasku musze odczekiwać chwilke po ustawieniu odpowiedzialnego za to pinu z 0 na 1? Bo nie wiem czy dobrze rozumuję, ale jeżeli to jest taktowane zboczem narastającym, to nie muszę odczekiwać :P
  • REKLAMA
  • Pomocny post
    #5 5764753
    zumek
    Poziom 39  
    lord_dagoth napisał:
    .. Czy podczas taktowania rejestrów i zwalniania zatrzasku musze odczekiwać chwilke po ustawieniu odpowiedzialnego za to pinu z 0 na 1? Bo nie wiem czy dobrze rozumuję, ale jeżeli to jest taktowane zboczem narastającym, to nie muszę odczekiwać :P

    Odpowiedzi poszukaj w dokumentacji swojego rejestru.Np. w SN74LS595, Shift clock frequency = 0 do 20MHz.Poza tym, do transferu danych z uC do 595, idealnie nadaje się interfejs SPI.
  • #6 5765010
    lord_dagoth
    Poziom 25  
    http://www.nxp.com/acrobat_download/datasheets/74HC_HCT595_4.pdf

    Znalazłem na stronie drugiej maximum clock frequency SH_CP and ST_CP 100 MHz (bo mam układ 74HC595). uC mam taktowany zegarem 4mhz. Oznacza to że aby uzyskać zbocze narastające mogę spokojnie podać najpierw zero, potem jeden i znowu zero, bez odczekiwania jakiegoś czasu pomiędzy tymi trzema operacjami?
  • #7 5765503
    zumek
    Poziom 39  
    lord_dagoth napisał:
    ..Oznacza to że aby uzyskać zbocze narastające mogę spokojnie podać najpierw zero, potem jeden i znowu zero, bez odczekiwania jakiegoś czasu pomiędzy tymi trzema operacjami?

    Usuń z cytatu znak zapytania, przeczytaj cytat, a będziesz znał odpowiedź :-P
  • #8 5766525
    lord_dagoth
    Poziom 25  
    hehe :D Dzięki za pomoc :D Pewnie będę miał jeszcze jakieś pytania jak dojedzie do mnie programator i fizycznie wgram program na procka :P
REKLAMA