eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronika › atxmega32a4, przerwania USART i resetowanie uC...
Ilość wypowiedzi w tym wątku: 11

  • 1. Data: 2011-06-05 13:45:02
    Temat: atxmega32a4, przerwania USART i resetowanie uC...
    Od: Martin Lukasik <m...@m...pl>

    Witam wszystkich i proszę o pomoc :-)
    Pytałem na avrfreaks, ale nie dostałem żadnej odpowiedzi...

    Podłączyłem xmega32a4 do PCta i mogę wysyłać dane. Dodałem ISR do
    kodu, i przerwanie odpala się przy wysłaniu danych (TXC). To działa
    bez problemu.
    Teraz dodaję ISR dla RX i sprawdzam... i niestety, gdy wysyłam coś do
    uC to teoretycznie przerwanie się wykonuje... mówię teoretycznie, bo
    odebranie znaku resetuje się mikrokontroler!
    A gdy mikrokontroler się zresetuje i program wykonuje się od nowa, to
    wszystkie przerwania są wyłączone (i nawet TX już nie działa).

    Ktoś wie co robię źle? :-(

    Oto mój kod:


    #define UART_GPS USARTE0

    int main (void) {
    cli();
    sei(); /* enable interrupts */

    OSC.CTRL |= OSC_RC32MEN_bm;
    while(!(OSC_STATUS & OSC_RC32MRDY_bm));
    CCP = CCP_IOREG_gc;
    CLK.CTRL = CLK_SCLKSEL_RC32M_gc;

    UARTinit(&UART_GPS); // init serial port


    while(1) {
    UARTputs(&UART_GPS, "test string\r\n");
    _delay_ms(500);
    }

    }

    ISR(USARTE0_RXC_vect) { //UART receive interrupt
    PORTA.OUTTGL |= (1 <<PIN0); // PA0 is toggled
    }

    ISR(USARTE0_TXC_vect) { //UART receive interrupt
    PORTA.OUTTGL |= (1 <<PIN1); // PA1 is toggled
    }



    I moje funkcje:


    //not finished yet, need to handle PORTE via arg
    void UARTinit(USART_t *port) {
    int bsel = 3325;
    int bscale = -3;
    // 4800 @ 32MHz


    PORTE.OUTSET = PIN3_bm;
    PORTE.DIRSET = PIN3_bm; // PE3 (TXD0) as output
    PORTE.DIRCLR = PIN2_bm; // PE2 (RXD0) as input

    PORTE.INTCTRL = 0x01; // set interrupt0 low level
    PORTE.INT0MASK = 0x04; // set pins 3 and 2 for as a source for
    interrupt

    port->BAUDCTRLA = /*(uint8_t)*/ bsel;
    port->BAUDCTRLB = (bscale << 4) | (bsel >> 8);

    PMIC.CTRL = PMIC_LOLVLEN_bm;

    // Enable RX and TX low level interrupts
    port->CTRLA = USART_RXCINTLVL_LO_gc | USART_TXCINTLVL_LO_gc;

    // Enable both RX and TX.
    port->CTRLB = USART_RXEN_bm | USART_TXEN_bm;

    // Set USART to 8bit, no parity, 1 stop bit
    port->CTRLC = USART_CHSIZE_8BIT_gc | USART_PMODE_DISABLED_gc;

    }


    //send a string to UART
    uint8_t UARTputs(USART_t *port, const char *ptr) {

    while(*ptr) {
    while(!(port->STATUS & USART_DREIF_bm)) // wait for output
    buffer to clear / send complete / ready to send
    _delay_us(1);

    port->DATA = *ptr++; // send character
    }

    return 1;
    }


    Używam tego z MAX232 (wiem, że jest na 5V). Niestety nic innego na
    chwilę obecną pod ręką nie mam. TX z xmegi jest podłączony
    bezpośrednio, i to działa. RX jest podłączony przez dzielnik napięcia
    (Umax = 3V, zasilanie uC 3.3V).


  • 2. Data: 2011-06-05 14:55:48
    Temat: Re: atxmega32a4, przerwania USART i resetowanie uC...
    Od: bratsiostry <n...@i...pl>


    >
    > ISR(USARTE0_RXC_vect) { //UART receive interrupt
    > PORTA.OUTTGL |= (1 <<PIN0); // PA0 is toggled
    > }

    Najprawdopodobniej musisz odczytać dane, które przyszły żeby wyzerować
    flagę przerwania. Doczytaj w pdfie lub sprawdź.


  • 3. Data: 2011-06-05 18:31:57
    Temat: Re: atxmega32a4, przerwania USART i resetowanie uC...
    Od: Martin Lukasik <m...@m...pl>

    On Jun 5, 3:55 pm, bratsiostry <n...@i...pl> wrote:
    > > ISR(USARTE0_RXC_vect) { //UART receive interrupt
    > >    PORTA.OUTTGL |= (1 <<PIN0); // PA0 is toggled
    > > }
    >
    > Najprawdopodobniej musisz odczyta dane, kt re przysz y eby wyzerowa
    > flag przerwania. Doczytaj w pdfie lub sprawd .

    Miałem cichą nadzieję, że to to, ale jednak nie :/
    W ogóle chyba nie trzeba czytać tych danych tak na dobrą sprawę, bo
    bufor może się bezkarnie przepełnić, ma nawet flagę przepełnienia
    bufora. Tak czy owak sprobowałem czytać USARTE0.DATA w procedurze
    ISR(), ale dalej to samo.
    W PDFie, którego przeczytałem już kilka razy dalej nic nowego nie
    znalazłem :/

    Nie mam pojęcia o co chodzi :-(
    Jakieś pomysły?

    Chyba trzeba będzie w konću wydać kasę na sprzętowy debugger...

    m.


  • 4. Data: 2011-06-05 18:56:42
    Temat: Re: atxmega32a4, przerwania USART i resetowanie uC...
    Od: bratsiostry <n...@i...pl>

    Martin Lukasik pisze:
    > On Jun 5, 3:55 pm, bratsiostry <n...@i...pl> wrote:
    >>> ISR(USARTE0_RXC_vect) { //UART receive interrupt
    >>> PORTA.OUTTGL |= (1 <<PIN0); // PA0 is toggled
    >>> }
    >> Najprawdopodobniej musisz odczyta dane, kt re przysz y eby wyzerowa
    >> flag przerwania. Doczytaj w pdfie lub sprawd .
    >
    > Miałem cichą nadzieję, że to to, ale jednak nie :/
    > W ogóle chyba nie trzeba czytać tych danych tak na dobrą sprawę, bo
    > bufor może się bezkarnie przepełnić, ma nawet flagę przepełnienia
    > bufora. Tak czy owak sprobowałem czytać USARTE0.DATA w procedurze
    > ISR(), ale dalej to samo.
    > W PDFie, którego przeczytałem już kilka razy dalej nic nowego nie
    > znalazłem :/
    >
    > Nie mam pojęcia o co chodzi :-(
    > Jakieś pomysły?
    >
    > Chyba trzeba będzie w konću wydać kasę na sprzętowy debugger...
    >
    > m.

    W atmegach flaga RXC jest zerowana dopiero po odczycie danej. Nie mam
    pdfa od xmegi, ale może być tak samo. Sprawdź jeszcze w kodzie wynikowym
    jak skompilowany jest odczyt - może być sytuacja, że kompilator
    zoptymalizował kod jeśli przypisana wartość nie jest później wykorzystana.


  • 5. Data: 2011-06-05 19:28:16
    Temat: Re: atxmega32a4, przerwania USART i resetowanie uC...
    Od: Martin Lukasik <m...@m...pl>

    On Jun 5, 7:56 pm, bratsiostry <n...@i...pl> wrote:

    > W atmegach flaga RXC jest zerowana dopiero po odczycie danej. Nie mam
    > pdfa od xmegi, ale może być tak samo. Sprawdź jeszcze w kodzie wynikowym
    > jak skompilowany jest odczyt - może być sytuacja, że kompilator
    > zoptymalizował kod jeśli przypisana wartość nie jest później wykorzystana.

    AVR1307:

    "When a complete character is received in the shift register, it is
    copied to the buffer,
    and the shift register is ready to receive a second (or third)
    character. Note that, if
    three characters have been received, without reading the DATA
    register, a fourth
    character will cause loss of the character in the shift register, the
    third byte is lost. In
    this case the buffer overflow flag will be set (BUFOVF in
    USARTxn.STATUS)."

    więc to potwierdza co mówiłem odnośnie czytania bufora.

    A to odnośnie czytania z DATA:
    "The RXCIF flag is set when there are unread data in the receive
    buffer, and cleared
    when the receive buffer is empty. The RXCIF flag is cleared by reading
    the data, it is
    not required to clear the flag manually."

    Zajrzę jeszcze do kodu asm. Ponoć reset może się pojawić przy skoku
    (jmp, rjmp) do niezdefiniowanego adresu (ponoć dzieje się tak gdy
    włączysz przerwanie a nie ma nigdzie procedury do jego obsługi --
    wtedy wywołanie przerwania kończy się skokiem "niewiadomogdzie" i uC
    się resetuje). No nic, powalczę jeszcze...

    Dzięki.

    m.


  • 6. Data: 2011-06-05 19:36:14
    Temat: Re: atxmega32a4, przerwania USART i resetowanie uC...
    Od: Michoo <m...@v...pl>

    W dniu 05.06.2011 21:28, Martin Lukasik pisze:
    > Zajrzę jeszcze do kodu asm. Ponoć reset może się pojawić przy skoku
    > (jmp, rjmp) do niezdefiniowanego adresu (ponoć dzieje się tak gdy
    > włączysz przerwanie a nie ma nigdzie procedury do jego obsługi --
    > wtedy wywołanie przerwania kończy się skokiem "niewiadomogdzie" i uC
    > się resetuje).
    Nie, nie "niewiadomogdzie", ale właśnie pod reset (tam wskazują
    wszystkie niezdefiniowane przerwania) - możesz za pomocą jakiegoś
    objdump/gdb zobaczyć jak wygląda reset vector - czy jest jakaś funkcja
    przypisana.

    --
    Pozdrawiam
    Michoo


  • 7. Data: 2011-06-05 21:07:43
    Temat: Re: atxmega32a4, przerwania USART i resetowanie uC...
    Od: Martin Lukasik <m...@m...pl>

    On Jun 5, 8:36 pm, Michoo <m...@v...pl> wrote:

    > Nie, nie "niewiadomogdzie", ale właśnie pod reset (tam wskazują
    > wszystkie niezdefiniowane przerwania) - możesz za pomocą jakiegoś
    > objdump/gdb zobaczyć jak wygląda reset vector - czy jest jakaś funkcja
    > przypisana.

    Niestety nie ma nic pod tym wektorem. Rozumiem, że wektor resetu to 0.
    W asmie mam tylko wektory 58 i 60, co jest zgodne z założeniami i moim
    programem. Nie mam tam nigdzie skoku do wektora 0.

    w .lss mam:

    00000212 <__vector_58>:
    }




    ISR(USARTE0_RXC_vect) { //UART receive interrupt
    212: 1f 92 push r1
    214: 0f 92 push r0
    216: 0f b6 in r0, 0x3f ; 63
    218: 0f 92 push r0
    21a: 11 24 eor r1, r1
    21c: 8f 93 push r24
    21e: ef 93 push r30
    220: ff 93 push r31
    data = USARTE0.DATA;
    222: 80 91 a0 0a lds r24, 0x0AA0
    226: 80 93 00 20 sts 0x2000, r24
    PORTA.OUTTGL |= (1 <<PIN0); // PA0 is toggled
    22a: e0 e0 ldi r30, 0x00 ; 0
    22c: f6 e0 ldi r31, 0x06 ; 6
    22e: 87 81 ldd r24, Z+7 ; 0x07
    230: 81 60 ori r24, 0x01 ; 1
    232: 87 83 std Z+7, r24 ; 0x07

    /* lcd_puts("INT triggered");
    lcd_puts(UARTgetc(&USARTD0));
    show_display();
    */
    }
    234: ff 91 pop r31
    236: ef 91 pop r30
    238: 8f 91 pop r24
    23a: 0f 90 pop r0
    23c: 0f be out 0x3f, r0 ; 63
    23e: 0f 90 pop r0
    240: 1f 90 pop r1
    242: 18 95 reti

    00000244 <__vector_60>:

    ISR(USARTE0_TXC_vect) { //UART receive interrupt
    244: 1f 92 push r1
    246: 0f 92 push r0
    248: 0f b6 in r0, 0x3f ; 63
    24a: 0f 92 push r0
    24c: 11 24 eor r1, r1
    24e: 8f 93 push r24
    250: ef 93 push r30
    252: ff 93 push r31
    PORTA.OUTTGL |= (1 <<PIN1); // PA1 is toggled
    254: e0 e0 ldi r30, 0x00 ; 0
    256: f6 e0 ldi r31, 0x06 ; 6
    258: 87 81 ldd r24, Z+7 ; 0x07
    25a: 82 60 ori r24, 0x02 ; 2
    25c: 87 83 std Z+7, r24 ; 0x07
    }
    25e: ff 91 pop r31
    260: ef 91 pop r30
    262: 8f 91 pop r24
    264: 0f 90 pop r0
    266: 0f be out 0x3f, r0 ; 63
    268: 0f 90 pop r0
    26a: 1f 90 pop r1
    26c: 18 95 reti



    Wygląda ok... Przeoczyłem coś?

    Dzieje się magia...


    m.


  • 8. Data: 2011-06-05 21:17:46
    Temat: Re: atxmega32a4, przerwania USART i resetowanie uC...
    Od: "Marcin Wasilewski" <j...@a...pl>

    Użytkownik "Martin Lukasik" <m...@m...pl> napisał w wiadomości
    news:e0544b5a-6e33-479b-ae99-3eee040a322e@u26g2000vb
    y.googlegroups.com...

    > Niestety nie ma nic pod tym wektorem. Rozumiem, że wektor resetu to 0.
    > W asmie mam tylko wektory 58 i 60, co jest zgodne z założeniami i moim
    > programem. Nie mam tam nigdzie skoku do wektora 0.

    > Wygląda ok... Przeoczyłem coś?
    > Dzieje się magia...
    > m.

    A niezdefiniowane wektory gdzie mają skok? Zrób procedurę obsługi przerwania
    np. zapalającą diodę na nieużywanym porcie. I przekieruj na tą procedurę
    wszystkie wektory od nieużywanych przerwań. Jeśli stan diody się zmieni, to
    znaczy, że wywołujesz (masz niezamaskowane) jakieś przerwanie, którego
    obsługi nie przewidziałeś.
    Jak nie pomoże odepnij linie RX i TX od MAX232 i je połącz na krótko. To co
    nadasz znajdzie się w buforze, zobacz czy procek wtedy też się resetuje, bo
    może to nie przerwania, tylko coś z napięciami masz nie tak. Następnie podaj
    na MAX232 stały sygnał i zobacz jakie masz napięcie na wyjściu.


  • 9. Data: 2011-06-05 21:24:38
    Temat: Re: atxmega32a4, przerwania USART i resetowanie uC...
    Od: John Smith <d...@b...pl>

    W dniu 2011-06-05 15:45, Martin Lukasik pisze:
    > Witam wszystkich i proszę o pomoc :-)
    > Pytałem na avrfreaks, ale nie dostałem żadnej odpowiedzi...
    >
    > Podłączyłem xmega32a4 do PCta i mogę wysyłać dane. Dodałem ISR do
    > kodu, i przerwanie odpala się przy wysłaniu danych (TXC). To działa
    > bez problemu.
    > Teraz dodaję ISR dla RX i sprawdzam... i niestety, gdy wysyłam coś do
    > uC to teoretycznie przerwanie się wykonuje... mówię teoretycznie, bo
    > odebranie znaku resetuje się mikrokontroler!
    > A gdy mikrokontroler się zresetuje i program wykonuje się od nowa, to
    > wszystkie przerwania są wyłączone (i nawet TX już nie działa).
    >
    > Ktoś wie co robię źle? :-(
    [...]

    A stos prawidłowo zainicjowany?
    K.


  • 10. Data: 2011-06-06 00:09:11
    Temat: Re: atxmega32a4, przerwania USART i resetowanie uC...
    Od: Jacek Radzikowski <j...@s...die.die.die.piranet.org>

    On 06/05/2011 05:07 PM, Martin Lukasik wrote:
    > On Jun 5, 8:36 pm, Michoo<m...@v...pl> wrote:
    >
    >> Nie, nie "niewiadomogdzie", ale właśnie pod reset (tam wskazują
    >> wszystkie niezdefiniowane przerwania) - możesz za pomocą jakiegoś
    >> objdump/gdb zobaczyć jak wygląda reset vector - czy jest jakaś funkcja
    >> przypisana.
    > Niestety nie ma nic pod tym wektorem. Rozumiem, że wektor resetu to 0.
    > W asmie mam tylko wektory 58 i 60, co jest zgodne z założeniami i moim
    > programem. Nie mam tam nigdzie skoku do wektora 0.
    [...]
    > Wygląda ok... Przeoczyłem coś?
    >
    > Dzieje się magia...

    Z reguły kiedy z programem dzieje się magia, to winny jest temu stos.
    Przypatrz się dokładnie czy nie masz zbyt głębokich odwołań do funkcji,
    czy stos nie wchodzi na obszar danych albo nie wychodzi poza RAM, czy
    nie piszesz gdzieś poza obszarem zadeklarowanych zmiennych.
    Za każdym razem jak miałem do czynienia z "czarną magią" na uP,
    okazywało się że błąd był związany ze stosem.

    pzdr.
    j.

strony : [ 1 ] . 2


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: