-
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.