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

[AVR][ATmega][C]Dwa UARTY w "łańcuch"

kazimi 23 Lip 2008 19:09 1991 1
REKLAMA
  • #1 5370999
    kazimi
    Poziom 12  
    Witam. Chciałem napisać następujący program:
    Dane przesyłane są z komputera przez UART1, a następnie te dane chciałbym przesłać dalej, za pomocą UART0. Na razie połączyłem sobie, w UART0 RxD z TxD za pomocą rezystora 200Ohm (taki loopback do testów). Czyli jak na razie chciałem uzyskać następujący przepływ : komputer -> UART1 -> UART0 -> UART0 -> UART1 -> komputer. Program skonstruowałem tak, że zanim prześle cokolwiek dalej, to czekam na odbiór całego stringu (aż nadejdzie NULL), i dopiero odsyłam dalej. Oto mój program, który niestety nie działa...

    Cytat:

    // enable use of extended keywords
    #pragma language=extended

    #include <stdio.h>
    #include <inavr.h>
    #include <pgmspace.h>

    #ifndef ENABLE_BIT_DEFINITIONS
    #define ENABLE_BIT_DEFINITIONS
    // Enable the bit definitions in the iom128.h file
    #endif

    #include <iom128.h>

    #define F_CPU 11059200
    //do komunikacji przez UART0
    #define USART0_BAUDRATE 9600
    #define BAUD0_PRESCALE (((F_CPU / (USART0_BAUDRATE * 16UL))) - 1 )

    //do komunikacji z komputerem
    #define USART1_BAUDRATE 9600
    #define BAUD1_PRESCALE (((F_CPU / (USART1_BAUDRATE * 16UL))) - 1 )

    volatile unsigned char fodbznak0 = 0; //flaga, fodbznak0 = 1 oznacza odebrany znak
    volatile unsigned char daneOdebrane0; //zawiera odebrane dane (z rejestru UDR0)
    volatile unsigned char *daneDoWyslania0;

    volatile unsigned char fodbznak1 = 0; //flaga, fodbznak1 = 1 oznacza odebrany znak
    volatile unsigned char daneOdebrane1; //zawiera odebrane dane (z rejestru UDR1)
    volatile unsigned char *daneDoWyslania1;

    volatile unsigned long int opoznienie;

    //------------------------------------------------------------------------------
    // ------------------------functions--------------------------------------------
    //------------------------------------------------------------------------------
    void InitTimer0(void) {
    DDRD = 0xff;
    //konfiguracja timera:
    TCCR0 = 1<<CS02 | 1<<CS01 | 1<<CS00; // czyli clk/1024
    TIMSK = 1<<TOIE0; //zezwolenie na przerwanie od timer0
    }
    //------------------------------------------------------------------------------
    void InitUart0(void)
    {
    __disable_interrupt();

    //set the baudrate to 9600 bps
    UBRR0H = (unsigned char)(BAUD0_PRESCALE>>8);
    UBRR0L = (unsigned char)BAUD0_PRESCALE;

    //Set frame format: 8 data 1stop no parity
    UCSR0C = (1<<UCSZ00)|(1<<UCSZ01);

    //Enable interrupts
    UCSR0B |= (1<<RXCIE0)|(1<<TXCIE0);

    //Enable UART receiver and transmitter
    //UCSR1B |= ( 1 << TXEN1 ) | ( 1 << RXEN1 );
    UCSR0B |= ( 1 << RXEN0 );
    __enable_interrupt();
    }
    //------------------------------------------------------------------------------
    void InitUart1(void)
    {
    __disable_interrupt();

    //set the baudrate to 9600 bps using a 11.059 MHz crystal */
    UBRR1H = (unsigned char)(BAUD1_PRESCALE>>8);
    UBRR1L = (unsigned char)BAUD1_PRESCALE;

    //Set frame format: 8 data 2stop no parity
    UCSR1C = (1<<USBS1)|(1<<UCSZ10)|(1<<UCSZ11);

    //Enable interrupts
    UCSR1B |= (1<<RXCIE1)|(1<<TXCIE1);

    //Enable UART receiver and transmitter
    //UCSR1B |= ( 1 << TXEN1 ) | ( 1 << RXEN1 );
    UCSR1B |= ( 1 << RXEN1 );
    __enable_interrupt();
    }
    //------------------------------------------------------------------------------
    void UART0_put_str(unsigned char *text) {

    daneDoWyslania0 = text;

    UCSR0B |= ( 1 << TXEN0 ); //wlacz nadajnik
    UDR0 = *daneDoWyslania0++;

    }
    //------------------------------------------------------------------------------
    void UART1_put_str(unsigned char *text) {

    daneDoWyslania1 = text;

    UCSR1B |= ( 1 << TXEN1 ); //wlacz nadajnik
    UDR1 = *daneDoWyslania1++;

    }
    //------------------------------------------------------------------------------
    // ------------------------IRQ handlers-----------------------------------------
    //------------------------------------------------------------------------------
    #pragma vector=TIMER0_OVF_vect
    __interrupt void timIntHandler(void) {

    if ( opoznienie > 0 ) {
    opoznienie--;
    }

    }
    //------------------------------------------------------------------------------
    #pragma vector=USART0_TXC_vect
    __interrupt void irqHandlerUSART0_TXC() {

    unsigned char znak;

    znak = *daneDoWyslania0++;

    if(znak!=0) {
    UDR0 = znak;
    }
    else {
    UCSR0B &= (~( 1 << TXEN0 )); //wylacz nadajnik
    }

    }
    //------------------------------------------------------------------------------
    #pragma vector=USART1_TXC_vect
    __interrupt void irqHandlerUSART1_TXC() {

    unsigned char znak;

    znak = *daneDoWyslania1++;

    if(znak!=0) {
    UDR1 = znak;
    }
    else {
    UCSR1B &= (~( 1 << TXEN1 )); //wylacz nadajnik
    }

    }
    //------------------------------------------------------------------------------
    #pragma vector=USART0_RXC_vect
    __interrupt void irqHandlerUSART0_RXC(void)
    {
    fodbznak0 = 1; //informujemy program główny o odebraniu znaku
    daneOdebrane0 = UDR0;
    }


    //------------------------------------------------------------------------------
    #pragma vector=USART1_RXC_vect
    __interrupt void irqHandlerUSART1_RXC(void)
    {
    fodbznak1 = 1; //informujemy program główny o odebraniu znaku
    daneOdebrane1 = UDR1;
    }
    //------------------------------------------------------------------------------
    // ------------------------------main()-----------------------------------------
    //------------------------------------------------------------------------------
    int main( void )
    {
    InitTimer0();
    InitUart0(); //uwaga!! ta funkcja odblokowuje przerwania !!
    InitUart1(); //uwaga!! ta funkcja odblokowuje przerwania !!


    unsigned char odebranaKomenda0[20];
    unsigned char i0 = 0; //do poruszania się po tablicy odebranaKomenda0[20]

    unsigned char odebranaKomenda1[20];
    unsigned char i1 = 0; //do poruszania się po tablicy odebranaKomenda1[20]
    while (1)
    {
    // //do testowania:
    // UART1_put_str("ECHO ");
    //odbieramy dane wysyłane przez UART0
    if(fodbznak0) {
    fodbznak0 = 0;
    if (daneOdebrane0 != NULL) {
    odebranaKomenda0[i0] = daneOdebrane0;
    i0++;
    }
    else {
    odebranaKomenda0[i0] = daneOdebrane0;
    i0 = 0;
    //po odebraniu całego stringu wysyłamy go dalej, na port COM komputera
    UART1_put_str(odebranaKomenda0);
    }

    }

    //odbieramy dane wysyłane przez komputer
    if(fodbznak1) {
    fodbznak1 = 0;
    if (daneOdebrane1 != NULL) {
    odebranaKomenda1[i1] = daneOdebrane1;
    i1++;
    }
    else {
    odebranaKomenda1[i1] = daneOdebrane1;
    i1 = 0;
    //po odebraniu całego stringu wysyłamy go dalej, na UART0
    UART0_put_str(odebranaKomenda1);
    }

    }

    }//koniec pętli while(1)
    }


    Jeżeli natomiast wewnątrz funkcji main() (a dokładniej wewnątrz tego while(1) ) włożę tylko to co poniżej, to mam programowy loopback, który działa.
    Cytat:

    //odbieramy dane wysyłane przez komputer
    if(fodbznak1) {
    fodbznak1 = 0;
    if (daneOdebrane1 != NULL) {
    odebranaKomenda1[i1] = daneOdebrane1;
    i1++;
    }
    else {
    odebranaKomenda1[i1] = daneOdebrane1;
    i1 = 0;
    //po odebraniu całego stringu wysyłamy go z powrotem do komputera
    UART1_put_str(odebranaKomenda1);
    }

    }


    Jeżeli ktoś robił coś podobnego, to też mógłby wrzucić, chętnie bym podpatrzył ;]
  • REKLAMA
  • #2 5371582
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    Gwoli wstępu - sformatuj porządnie kod (znacznik [code]), bo nikomu innemu nie będzie się chciało go czytać...

    Kod masz symetryczny, więc powinno działać. Jest jeden błąd - w UARTx_put_str kopiujesz wskaźnik na char, a nie same znaki. Prawidłowo powinieneś kopiować zawartość łańcucha do osobnego bufora nadawczego. W Twoim programie prawdopodobnie nie ma to znaczenia, bo wysyłasz łańcuchy przechowywane w zmiennych lokalnych funkcji main, z której program nigdy nie "wraca". Niemniej dane mogą zostać przypadkowo nadpisane, zwłaszcza, gdyby UARTy różniły się prędkościami.

    Pozdrawiam,
    Dr.Vee
REKLAMA