Co jest trochę wali

26

Jestem nowy w programowaniu mikrokontrolerów. Używam kontrolera ATmega32-A i kompilatora CodeVisionAVR. Używam generatora fal (AD9833) do generowania sygnału fali sinusoidalnej za pomocą komunikacji SPI. Jestem w stanie wygenerować falę sinusoidalną z powodzeniem. Teraz przekazuję ten sygnał do czujnika. Wyjście czujnika jest wybierane przez multiplekser i wysyłane do ADC. Teraz chcę odczytać wartości ADC za pomocą komunikacji SPI. Dużo próbowałem skonfigurować rejestry ADC. Nadal nie działa. Aby zobaczyć kod komunikacji SPI, zobacz mój poprzedni post Konfiguracja rejestrów ADC za pomocą komunikacji SPI . Korzystam z komunikacji USART (RS232) do drukowania wartości na PC (PuTTY).

Ktoś poradził mi, żebym używał bit bitu. Jestem nowy w tej koncepcji. Czy ktoś może mi podać przykładowy kod bitowy komunikacji SPI. Jak rozpocząć tę procedurę? Czy ktoś może mi zapewnić dobry sprzęt. Czy potrzebuję zewnętrznego sprzętu?

Napisałem to, w tym połączenia pinowe:

#define ADC_CS PORTB.3
#define MOSI PORTB.5
#define MISO PINB.6
#define SCK PORTB.7

void send_8bit_serial_data(unsigned char data)
{
    int i;  
    ADC_CS=0;
    for (i = 0; i < 8; i++)
    {
        // consider leftmost bit
        // set line high if bit is 1, low if bit is 0
        if (data & 0x80)
            output_high(PORTB.5);
        else
            output_low(PORTB.5);

        // pulse clock to indicate that bit value should be read
        output_low(PORTB.7);
        output_high(PORTB.7);

        // shift byte left so next bit will be leftmost
        data <<= 1;
    }

    // deselect device
    ADC_CS=1;
}
verendra
źródło
Twój kod wygląda dobrze poza dolnym wyjściem zegara powinno być przed ustawieniem bitu i opóźnieniem. Potrzebujesz kilku opóźnień, aby naprawić taktowanie (więc zegar niski / wysoki to mniej więcej ten sam okres) Ponownie spójrz na kod Stevena. Jeśli chcesz również przeczytać, musisz również dodać kod do tego.
Oli Glaser,
@OliGlaser Czy mogę użyć bezpośrednio tego kodu zamiast normalnego kodu SPI, aby skonfigurować rejestry.
verendra
@verendra - nie jestem pewien, co rozumiesz przez „normalny kod SPI”. Jeśli masz na myśli zamiast sprzętowego SPI, to ADC nie dba o to, jak generowane są impulsy, o ile zgadzają się z protokołem i czasem.
Oli Glaser,

Odpowiedzi:

25

Bit banging tworzy w oprogramowaniu całą serię impulsów, zamiast polegać na sprzęcie wewnątrz mikrokontrolera.

Wiele mikrokontrolerów ma sprzętowy interfejs SPI, a następnie wystarczy wpisać bajt do rejestru wyjściowego, a kontroler SPI przeniesie dane, a jednocześnie odbierze dane z urządzenia podrzędnego. Możesz otrzymać przerwanie po zakończeniu przesyłania, a następnie odczytać odebrane dane.

Ale niektóre mikrokontrolery nie mają na pokładzie sprzętu SPI, a następnie trzeba go zasymulować, wykonując wszystko ręcznie. SPI ma wiele różnych trybów, użyję tego schematu pulsu jako przykładu:

wprowadź opis zdjęcia tutaj

Tak więc podczas gdy dedykowany kontroler SPI dba o wszystkie impulsy, przesuwanie danych i synchronizację, podczas bit-bitu musisz sam podjąć każdą akcję:

Make Slave Select low  
Short delay
Do 8 times
  Make the SCK (Serial Clock) pin low 
  Make the MOSI (Master-Out-Slave-In) pin high or low depending on bit 7 of the data  
  Add brief delay  
  Make the SCK output high
  Read MISO (Master-In-Slave-Out) pin
  Shift received data left, and shift the bit just read in as bit 0   
  Add brief delay  
  Shift the data byte 1 bit left
Make Slave Select high again  

Interfejs SPI do bitów jest stosunkowo prosty, na przykład kod I2C do bitów będzie bardziej złożony, a jeśli chcesz przeskoczyć protokół UART, potrzebujesz jakiegoś timera.

stevenvh
źródło
2
Czy możesz podać przykładowy kod c.
verendra
1
@verendra - dodałem przykład pseudokodu, który powinieneś być w stanie łatwo przetłumaczyć na C.
stevenvh 15.10
Z powodzeniem generuję Wavefrom za pomocą komunikacji SPI. Mam problem z odczytaniem wartości ADC tylko przy użyciu SPI. Muszę użyć bit banging dla obu lub tylko po to, by odczytać wartości ADC. Czy możesz rzucić okiem na mój kod do wysłania 8 bitów, czy to pisz? ale mylę jak go używać. Czy mogę umieścić ten kod bezpośrednio zamiast mojego kodu SPI, aby zarejestrować rejestr.
verendra
@Steven - schemat, który pokazujesz, to MSB jako pierwszy, więc musisz wyjść w lewo z 7 i w lewo z 0. Wiem, że nie ma standardu, więc może to być LSB, ale myślę, że większość urządzeń peryferyjnych SPI robi to w ten sposób .
Oli Glaser,
2
@Oli - dobra uwaga, że ​​mi tego brakowało. Naprawię to, dzięki za opinie. Powodem, dla którego nie ma standardu, jest to, że nie ma znaczenia, o ile liczba przesłanych bitów jest równa długości rejestru przesuwnego. Ostatnio niektóre mikrokontrolery (jak NXP Cortec-M3) mają rejestr przesuwny o zmiennej długości, a wtedy kierunek może mieć znaczenie. IIRC w AVR możesz wybrać najpierw MSB lub LSB jako pierwszy.
stevenvh
6

Bit-biting odnosi się do koncepcji generowania / próbkowania sygnałów wychodzących lub wchodzących do urządzenia przez oprogramowanie, a nie sprzęt. Oczywiście wymagany jest sprzęt, ale w przypadku korzystania z bit-bangingu jedynym sprzętem dla każdego wyjścia jest zatrzask, który można jawnie ustawić lub wyczyścić za pomocą oprogramowania, a jedynym sprzętem dla każdego wejścia jest interfejs umożliwiający oprogramowaniu sprawdzenie, czy jest high lub low (i zazwyczaj wykonują gałąź warunkową dla jednego stanu, ale nie dla drugiego).

Maksymalna prędkość, którą można osiągnąć dzięki bitbangowaniu, będzie na ogół ułamkiem tego, co można osiągnąć za pomocą specjalnie zbudowanego sprzętu, ale poza ograniczeniami wynikającymi z szybkości procesora, bitbanging jest znacznie bardziej wszechstronny i może być stosowany w okolicznościach gdzie sprzęt ogólnego przeznaczenia nie jest całkiem odpowiedni, a sprzęt specjalnego przeznaczenia nie byłby opłacalny.

Na przykład wiele kontrolerów ma port „w stylu SPI”, który zachowuje się zasadniczo w następujący sposób: gdy bajt jest zapisywany w pewnym rejestrze, sprzęt generuje pewną liczbę impulsów zegarowych (zwykle osiem), odliczając bit danych na zbocze narastające każdego impulsu zegarowego i próbkowanie przychodzącego bitu danych na zboczu opadającym. Zasadniczo porty w stylu SPI kontrolerów umożliwiają konfigurację różnych funkcji, ale w niektórych przypadkach może być konieczne połączenie procesora z urządzeniem, które robi coś niezwykłego. Urządzenie może wymagać przetwarzania bitów danych w wielokrotnościach innych niż osiem, może też wymagać, aby dane były zarówno wyjściowe, jak i próbkowane na tym samym zboczu zegara, lub może mieć inne nietypowe wymagania. Jeśli konkretny sprzęt kontrolera, którego używasz, może spełnić twoje dokładne wymagania, świetny (niektóre zapewniają konfigurowalną liczbę bitów, osobno konfigurowalne taktowanie nadawania i odbierania itp.) Jeśli nie, pomocne może być wybijanie bitów. W zależności od kontrolera, bit-bifting interfejsu SPI często zajmuje 2-10 razy tyle, ile pozwala sprzętowi na jego obsługę, ale jeśli wymagania nie pasują do posiadanego sprzętu, wolniejsza wymiana danych może być lepsza niż w ogóle nie mogąc tego zrobić.

Jedną ważną rzeczą, na którą należy zwrócić uwagę w przypadku projektów bitowych, jest to, że są one najprostsze i najbardziej niezawodne w okolicznościach, w których albo komunikowane urządzenia czekają na kontrolerze bitów, aby wygenerować cały czas, lub gdy kontroler będzie mógł zaczekaj, bez rozproszenia, na nadejście zdarzenia i na miejsce, w którym będzie mógł zrobić wszystko, co musi zrobić z tym wydarzeniem, zanim nadejdzie inne wydarzenie, na które musi zareagować. Są znacznie mniej wytrzymałe w okolicznościach, w których urządzenie będzie musiało być w stanie reagować na bodźce zewnętrzne w stosunkowo krótkim czasie, ale nie może wykorzystać 100% swojej energii na obserwowanie takich bodźców.

Załóżmy na przykład, że ktoś chce, aby procesor przesyłał szeregowo dane w stylu UART z szybkością, która jest bardzo wysoka w stosunku do jego szybkości zegara (np. PIC, który wykonuje 8 192 instrukcji na sekundę, chce wysyłać dane z szybkością 1200 bps). Jeśli nie są włączone żadne przerwania, taka transmisja nie jest trudna (zegar jeden bit na siedem cykli instrukcji). Gdyby PIC robił tylko czekanie na przychodzący bajt danych 1200bps, mógłby wykonać pętlę 3-cyklową, czekając na bit startowy, a następnie kontynuować taktowanie danych w siedmiocyklowych odstępach. Rzeczywiście, jeśli PIC miałby bajt danych gotowy do wysłania, gdy nadszedł przychodzący bajt danych, siedem cykli na bit wystarczyłoby, aby PIC wysłał swój bajt danych jednocześnie z odczytaniem przychodzącego bajtu. Również,jeżeli taka odpowiedź miałaby ustalony czas w stosunku do pierwotnej transmisji . Z drugiej strony, PIC nie miałby możliwości obsługi komunikacji bit-bang w taki sposób, aby każde urządzenie mogło transmitować w dowolnym momencie, w którym uznało to za stosowne (w przeciwieństwie do posiadania jednego urządzenia, które mogłoby transmitować, gdy zobaczyło dopasuj się i rób, co chcesz, gdy nie transmitujesz, i jedno urządzenie, które musiałoby spędzać większość czasu, robiąc tylko czekając na transmisje z pierwszego urządzenia).

supercat
źródło