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

UART(RS-232) -> SPI, połączenie, konwersja interfejsów

regrom 11 Paź 2010 21:26 5731 15
  • #1 8608908
    regrom
    Poziom 16  
    Witam.

    Myślę nad zrobieniem programatora dla układu ISD150102 , jest to wielokomunikatowy układ dźwiękowy do bezpośredniego zapisu / odtwarzania sygnałów głosowych lub audio ,komunikatów.

    W związku z tym, że układ ewaluacyjny dla tej kostki jest drogi, myślę nad własnym programatorem.

    Wpadłem na pewien pomysł. Układ może być sterowany poprzez interfejs SPI(typ 3), przez ten interfejs można też do niego przesłać dane w formie PCM czyli np. plik *.wav.
    Docelowo napiszę program na PC(C#) wysyłający dane przez port COM, następnie chce wykorzystać mikroprocesor jako bufor i dalej przesyłać dane poprzez SPI do ISD, układ sterujemy za pomocą odpowiednich komend opisanych w nocie katalogowej.

    Mam pytanie dla ludzi doświadczonych czy takie połączenie wypali, czy da się te interfejsy z synchronizować, tzn. trzeba monitorować dane zwrotne(tzw. status byte) z układu ISD, także transmisja będzie dwukierunkowa:
    PC>>>(RS-232)>>>µC>>>(SPI)>>>ISD

    Jako mikrokontroler chce wykorzystać jakąś ATmegę posiadająca UART i SPI, newet pospolita ATmega8, czy 88 by starczyła, po to żeby wykorzystać sprzętowe interfejsy, a program w uC miałby wysyłać dane z Rx na MOSI, a z MISO na Tx.

    Także strony sprzętowej: układ MAX232, wspomniana wyżej ATmega, i będzie potrzebny konwerter SPI z 5V na 3,3V gdyż z takiego napięcia roboczego korzysta ISD.

    RS-232 to transmisja asynchroniczna, z kolei SPI synchroniczna.
    Także mam pytanie czy ma to sens i czy jest to możliwe? Mile widziane sugestie i porady.
  • Pomocny post
    #2 8609025
    tadzik85
    Poziom 38  
    Sens jest. Skoro twój układzik działa na 3.3V zasil i programator takim napięciem Max3232 działa na takim napięciu zasilającym.

    Zaimplementuj bufory typu fifo w obu kierunkach i sterowanie przepływem przy RS jeśli będzie konieczne.
  • #3 8609147
    tmf
    VIP Zasłużony dla elektroda
    Pytanie tylko cy RS232 jest wystarczająco szybki do przesłania twoich próbek. Dla 44kHz, 16-bit sample, mono potrzebujesz UART popędzać na 880000 bps. ATMega da spokojnie radę, ale MAX i PC?
  • #4 8609151
    regrom
    Poziom 16  
    Rozumiem, czyli problem zasilania mam załatwiony, wszystko przecież pójdzie na 3.3 V bez problemu.

    Mówisz o buforach fifo, hmm tylko, że po każdym wysłanym bajcie będę musiał sprawdzić odpowiedź układu ISD:
    UART(RS-232) -> SPI, połączenie, konwersja interfejsów

    wiec jakiego rozmiaru mogły by być te bufory? Chciałbym aby wymiana danych była na bieżąco,czyli po drugim wysłanym bajcie na MOSI odbieramy "status byte" odowiedzi na pierwszy bajt po MISO itd z kolejnymi bajtami, czy to z kolei jest dobra droga?

    Piszesz o sterowaniu przepływem RS, mógłbyś rozwinąć to zagadnienie?

    Swoją drogą jak działa np, avrprog?,tam też np. jest że dane są wysyłane po comie i dalej po SPI do programowanego układu.

    Dodano po 3 [minuty]:

    tmf napisał:
    Pytanie tylko cy RS232 jest wystarczająco szybki do przesłania twoich próbek. Dla 44kHz, 16-bit sample, mono potrzebujesz UART popędzać na 880000 bps. ATMega da spokojnie radę, ale MAX i PC?


    Tmf, chce skorzystać z tej dobroci jaką dysponuje tak kostka:

    UART(RS-232) -> SPI, połączenie, konwersja interfejsów

    Załączam szczegółową notę:
  • Pomocny post
    #5 8609265
    tadzik85
    Poziom 38  
    tmf, nie powiedział o czasie rzeczywistym. Ja rozumiem, że wdzięk chce wgrać i już.
    Sterowanie przepływem cóż myślę, że w tej kwestii pomoże ci znacznie lepiej wujek google, chodzi i czasowe chwilowe zawieszenie wysyłania danych przez RS, aby dane zostały przetworzone.

    Ale w uproszczonej wersji możesz zrobić tak, że wysyłasz paczkę danych do procka on wgrywa ja do twojej kostki z odpowiednim algorytmem. Po wgraniu odsyłasz do kompa "ślij dalej". I tak to wgrania całego dźwięku. Jeśli potrzeba ci innych rzeczy wysyłasz z kompa pewną komendę programator twój zrobi co trzeba i odeśle odpowiedź. Myślę, że do testów powinno wystarczyć, no chyba że potrzebujesz jakiś wielkich osiągów.
  • #6 8611329
    regrom
    Poziom 16  
    Właśnie myślę nad takim rozwiązaniem, osiągami zajmę się później jak wszystko zacznie działać, nic tylko zostaje mi przystąpić do testów:

    Na początek, jedna atmega jako slave(SPI) + LCD, druga jako master(SPI) podlaczona po comie do PC't napisze proste softy do przesyłania i zobaczę co z tego wyjdzie czy transmisja będzie stabilna, także biorę się za kompletowanie elementów.dzięki za odpowiedź.
  • #7 8676986
    regrom
    Poziom 16  
    Witam po przerwie,

    No więc tak, zrobiłem jak pisałem wyżej, po zabawie z każdym interfejsem z osobna połączyłem procki, Master komunikuje się PC po RS, a Slave ma podłączony LCD.

    Generalnie jest goła transmisja z wykorzystaniem dwóch przerwań od zakończenia transmisji, funkcje sterujące oparte o notę katalogową.

    Master:


    volatile unsigned char odebranyZnakRS = 0;
    volatile unsigned char odebranyZnakSPI = 0;
    .
    .
    void SPI_MasterInit(void)
    {
    /* Set MOSI and SCK output, all others input */
    sbi(DDRB,3);
    sbi(DDRB,5);
    
    /* Enable SPI, Master, set clock rate  */
    
    SPCR = (1<<SPE)|(1<<CPOL)|(1<<CPHA)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1)|(1<<DORD);
    }
    .
    .
    unsigned char SPI_MasterTransmit(char cData)
    {
    /* Start transmission */
    SPDR = cData;
    /* Wait for transmission complete */
    while(!(SPSR & (1<<SPIF)));
    
    return SPDR;
    }
    .
    .
    USART_Init(USART_BAUDRATE);
    SPI_MasterInit();
    sei(); 
    
    while(1)
    {}
    .
    .
    ISR(USART_RXC_vect)
    {
    odebranyZnakRS = UDR;
    
    odebranyZnakSPI = SPI_MasterTransmit(odebranyZnakRS);
    
    USART_Transmit(odebranyZnakSPI);
    
    } 


    SLAVE:

    volatile unsigned char odebranyZnak = 0;
    .
    .
    .
    void SPI_SlaveInit(void)
    {
    /* Set MISO output, all others input */
    sbi(DDRB,4);
    /* Enable SPI */
    SPCR = (1<<SPE)|(1<<CPOL)|(1<<CPHA)|(1<<SPIE)|(1<<DORD);
    }
    .
    .
    LCD_Initalize();
    SPI_SlaveInit();
    sei(); 
    .
    .
    while(1)
    {}
    ,
    .
    ISR(SPI_STC_vect)
    {
    odebranyZnak = SPDR;
    
    LCD_WriteData(odebranyZnak); //UDR
    
    SPDR = odebranyZnak;
    
    }



    Czyli jak widać, po odebraniu bajtu od komputera po UART w przerwaniu USART_RXC_vect (USART, Rx Complete ) , ten bajt przesyłam po SPI do układu slave, jednocześnie oczywiście odbieram bajt z SPI i przesyłam spowrotem do komputera.

    W układzie Slave, w przerwaniu SPI_STC_vect (Serial Transfer Complete ), wrzucam odebrany znak na LCD i wpisuje go ponownie do rejestru SPDR, czyli zwracam go do master, oczywiście odebrany zostaje przy kolejnej transmisji sterowanej przez mastera.

    W ten sposób mam transmisję w kółko,działa stabilnie,nie gubi znaków, to co wysyłam odbieram z powrotem na PC, co prawda z przesunięciem o jeden bajt ze względu na charakter transmisji SPI, wiec trzeba będzie pomyśleć nad jakimś bajtem buforującym.


    Poproszę o porady i sugestie jakie problemy może powodować takie przesyłanie, jak wy byście to zrobili?
  • Pomocny post
    #8 8677052
    tmf
    VIP Zasłużony dla elektroda
    Zrobilibyśmy chyba tak samo :) No może ponieważ RS jest na wymarciu w PC, to zrobiłbym to na AVRrze wyposażonym w USB. Ponieważ obsługę USB załatwiają sterowniki z Atmela lub LUFA, więc nie jest to bardziej skomplikowane niż RS :) Ale jak ci wszystko działa to jest git, nie ma co kombinować.
  • #9 8769512
    regrom
    Poziom 16  
    Po krótkiej przerwie czas zabrać się do roboty, zdobyłem dosyć ładne i tanie płytki PCB z QFP48(raster 0,5 mm) na 2,54 mm, tylko teraz to polutować ;)

    UART(RS-232) -> SPI, połączenie, konwersja interfejsów

    Jak ktoś by szukał: Link
    dostępne też w cyfronice lub Link

    RS na wymarciu, ale wciąż jeszcze żywy ;) , nad USB pomyślę w przyszłości, na razie układ chce uruchomić i poprawnie się z nim skomunikować, udało mi się poprawnie skonfigurować RS i SPI na AT także na razie zostanie przy tym.

    Teraz mam pytanko jak odseparować połączona atmege z tym układem po SPI od programowania ISP. W celach testowych oczywiście zworki(dip switche), ale na finalnej płytce w moim projekcie chciałbym się ich pozbyć.

    Drugie pytanie, oba układy zasilanie będę 3,3 V, czy przy takim napięciu ATmega będzie poprawnie zaprogramowana przez ISP KANDA(STK 200 itp).?Chodzi tu o poziomy tych napięć, programator zasilany mam z 5V czy to się nie będzie "gryzło"?

    Liczę na cenne porady doświadczonych kolegów :)
  • #10 8769568
    tmf
    VIP Zasłużony dla elektroda
    Pytanie czy musisz separować SPI od ISP?
    Normalnie ukłądy SPI nie będą reagować podczas programowania, gdyż ich piny SS będą w stanie wysokim - ponieważ w czasie aktywnego RESET piny IO procesora są w stanie HiZ, więc dla pewności na liniach SS powinien być rezystor podciągający. Z drugiej strony możesz układy programować przed wlutowaniem, a potem w razie konieczności skorzystać z bootloadera. Możesz też wybrać AVRy, któych SPI jest na innych pinach niż ISP.
    Co do programatora - będzie się gryzło - piny procesora nie są 5V tolerant, napięcie się zbije poprzez diody zabezpieczające scalaka, co jeśli nie ma rezystorów szeregowych na liniach ISP uwali mikrokontroler. Lepiej użyj programatora, który ma bufor wyjściowy zasilany z programowanego układu, albo obniż napięcie zasilające programator.
  • #11 8771653
    regrom
    Poziom 16  
    Dzięki tmf za rady, jak sam piszesz rozwiązań jest wiele, czy muszę separować, właśnie też tego się chciałem dowiedzieć ;), przy testach będą dip switche miedzy procesorem a układem ISD, samo gniazdo ISP może zostać sobie podłączone do procka, wystarczy, że kabelek z gniazda się wyciągnie, tylko potem będę musiał się zdecydować na "ładniejsze" rozwiązanie.

    Co do tych napięć, można by też jakiś konwerter na jednym tranzystorze ale to przekombinowanie, po prostu zasilę 74HC244 w moim stk200 takim samym napięciem jak programowany procesor i po sprawie myślę.

    W tym tygodniu będę miał wszystko ładnie polutowane i dam znać jak będzie działał mój programator do tego układu ISD. Pozdrawiam
  • #12 8797274
    regrom
    Poziom 16  
    No to po pierwszych próbach mam problem:

    Wszystko polutowane, połączyłem układy na płytkach stykowych, Atmega, MAX 3232(3,3V) oraz ISD15102.

    Pierwsze próby komunikacji z kostką wyglądają tak, wysyłam komendę PWR_UP 0x10 (Power up) do kostki, otrzymuje cały czas 0x90 czyli, że układ jest wyłączony(bit PD=1)czyli power down.

    Przy próbie wysłanie kolejnego bajtu,Atmega się wiesza.., nie ważne czy wysyłam to własnoręcznie napisanym programem czy terminalem efekt ten sam, drugi wysłany bajt - zawieszenie.

    Zauważyłem że na pinie SCK(zegar) jest około 1V, a w trybie 3 SPI powinno VCC czyli 3,3V.., mam tak na dwóch Atmegach 8L i zwykłej.

    Na ten pierwszy bajt kosta ISD odpowiada zawsze, potem sie wiesza procek. Co tu jest nie tak? Kod nie różni się od tego co jest wyżej poza tym że ustawiłem żeby pierwszy był MSB i zwolniłem procka do 1Mhz, oraz while(1) dalem mrugająca diodę żeby widzieć czy procek nie wisi..

    Jakieś sugestie? Pomysły?
  • #13 8797428
    tmf
    VIP Zasłużony dla elektroda
    Pokaż kod. Procesor nie może się zawiesić ot tak sobie, po prostu kod który wykorzystujesz na coś czeka w pętli i to coś nigdy nie zachodzi - wniosek taki, że kod jest OKDR.
  • #14 8797449
    regrom
    Poziom 16  
    Dzięki za zainteresowanie:

    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    
    volatile unsigned char odebranyZnakRS = 0;
    volatile unsigned char odebranyZnakSPI = 0;
    
    void SPI_MasterInit(void)
    {
    /* Set MOSI and SCK output, all others input */
    sbi(DDRB,3);
    sbi(DDRB,5);
    //sbi(DDRB,2);
    
    /* Enable SPI, Master, set clock rate fck/16 */
    
    SPCR = (1<<SPE)|(1<<CPOL)|(1<<CPHA)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); /*|(1<<DORD);*/
    }
    
    unsigned char SPI_MasterTransmit(unsigned char cData)
    {
    /* Start transmission */
    SPDR = cData;
    /* Wait for transmission complete */
    while(!(SPSR & (1<<SPIF)));
    
    return SPDR;
    }
    
    
    
    int main (void)
    
    {
    sbi(DDRC,5); // dioda
    cbi(PORTC,5); //OFF
    
    USART_Init(USART_BAUDRATE);
    SPI_MasterInit();
    
    sei(); 
    
    
    
    
    while(1)
    {
    
    
    _delay_ms(250);
    
    cbi(PORTC,5); //OFF
    _delay_ms(250);
    
    sbi(PORTC,5); //ON
    }
    
    }
    
    ISR(USART_RXC_vect)
    {
    
    odebranyZnakRS = UDR;
    
    odebranyZnakSPI = SPI_MasterTransmit(odebranyZnakRS);
    
    USART_Transmit(odebranyZnakSPI);
    
    } 
    


    No jedyna pętla w tym przerwaniu to będzie: while(!(SPSR & (1<<SPIF)));

    Dodano po 38 [minuty]:

    Coś tu jest nie tak :/ czy układ ISD jest podłączony do SPI czy nie, atmega się wiesza, a ta odpowiedz która dostaje to widocznie jakies smieci, trzeba bedzie chyba pokombinowac zasilic ta atmega z 5V, tylko dlaczego na tym pinie SCK jest ledwo 1V skoro powinno byc VCC??
  • #15 8800230
    regrom
    Poziom 16  
    Może ktoś rzucić chociaż okiem na ten konwerter z 3.3V na 5V i na odwrót:

    UART(RS-232) -> SPI, połączenie, konwersja interfejsów
  • #16 8805338
    regrom
    Poziom 16  
    Szkoda że nikt się nie wypowiedział.

    Na razie obyło się bez konwertera, znalazłem przyczynę zawieszania się Atmegi. Nóżka SS nie była skonfigurowana jako wyjście, więc należy ją podpiąć do VCC, o czym wcześniej zapomniałem.

    Jednak nadal nie mogę wskrzesić ISD do działania, z początku nóżkę SS ISD podłączyłem do GND, aby układ reagował na komendy SPI, jednak cały czas otrzymywałem 0x00. Dlatego skonfigurowałem pin SS jak wyjście, i podłączyłem wszystkie piny SPI ze sobą.

    Teraz przed wysłanie bajtu przez MOSI, zmieniam stan nóżki SS na niski a po zakończeniu transmisji na wysoki. Tym razem cały czas dostaje od ISD 0x80 czyli nadal nie powodzenie :|. Wszystkie napięcia na nogach ISD są, zwarć nie ma, co tu może być nie tak? Zegar SPI zwolniłem do 15 kHz.
REKLAMA