Hallo, ich habe eine Frage zu dem mitgelieferten Beispiel für das Board AT32UC3C-EK von Atmel. Das Beispiel ist folgendermassen aufgebaut: 1. Rx Interrupt wird eingerichtet(aktiviert, ISR ahandler angemeldet) 2. Wenn ein Zeichen empfangen wird, wird die entsprechende ISR aufgerufen in der dann dieser Zeichen als Echo zurückgeschickt wird. Das Ganze funktioniert ohne irgendwelche Änderungen und anpassungen: Compilieren aufs Board laden, fertig. Das ganze funktioniert aber, wenn ich Zeichen für Zeichen in Terminal schicke (hterm). Sobald ich mehrere Zeichen reintippe und aufs "Absenden" drücke, wird das erste Zeichen des Strings oder manchmal auch irgendein Müll empfangen. Meine Fehlersuche ergab bis jetzt: Wenn das erste Zeichen geschickt wurde, ist der uC ja in ISR und versucht in dieser ISR das Zeichen zurück zu schicken, dann trudelt schon das 2. Zeichen an, und ab da springt der uC immer wieder in die ISR und versendet meistens Müll. Der Interrupt request wird also nicht zurück gesetzt. Meine Frage ist also, wie mache ich das manuele Zurücksetzen des Requests bei diesem uC? Und was noch wichtiger, wieso scheitert hier das automatische Rücksetzen des Requests, wo es doch beim "Zeichen für Zeichen" ohne das manuele Eingreifen funktionier? Vielen Dank. Später hänge ich noch entspr. Code
Hallo Franzis, die Beispiele sind immer nur funktional und häufig nur auf ein Thema zugeschnitten. Besser Du suchst Dir eine Demoapplikation, in der ein datenstreaming umgesetzt worden ist. Wenn Du eine Zeichenkette empfangen möchtest, dann solltest Du einen Puffer definieren und zwei Zeiger (Anfang und Ende). Dann kann der Empfang ereignisunabhängig vom Senden durchgeführt werden. Man nennt das auch FIFO. First in First out. Ist allerdings nicht ganz mühelos.
cskulkw schrieb: > die Beispiele sind immer nur funktional und häufig nur auf ein Thema > zugeschnitten. Besser Du suchst Dir eine Demoapplikation, in der ein > datenstreaming umgesetzt worden ist. > > Wenn Du eine Zeichenkette empfangen möchtest, dann solltest Du einen > Puffer definieren und zwei Zeiger (Anfang und Ende). Dann kann der > Empfang ereignisunabhängig vom Senden durchgeführt werden. > > Man nennt das auch FIFO. First in First out. @cskulkw: Vielen Dank für die hilfreihe Antwort. Ich dachte schon deren Beispiel ist schlecht/ mit Fehlern programmiert worden. Ich werde mich nach solch einem Beispiel suchen. @all: Kann jemand was generel zu den Interrupts bei diesem AVR32 sagen, Tips geben? Oder gar zu den USART Interrupts. Hier ist der Code worum es hier geht:
1 | static void usart_int_handler(void) |
2 | {
|
3 | int c; |
4 | // The USART Rx interrupt flag is cleared by side effect when reading the
|
5 | // received character.
|
6 | // Waiting until the interrupt has actually been cleared is here useless as
|
7 | // the call to usart_write_char will take enough time for this before the
|
8 | // interrupt handler is leaved and the interrupt priority level is unmasked by
|
9 | // the CPU.
|
10 | usart_read_char(EXAMPLE_USART, &c); |
11 | |
12 | // Print the received character to USART.
|
13 | // It is a simple echo
|
14 | usart_write_char(EXAMPLE_USART, c); |
15 | }
|
16 | |
17 | int main(void) |
18 | {
|
19 | static const gpio_map_t USART_GPIO_MAP = |
20 | {
|
21 | {EXAMPLE_USART_RX_PIN, EXAMPLE_USART_RX_FUNCTION}, |
22 | {EXAMPLE_USART_TX_PIN, EXAMPLE_USART_TX_FUNCTION} |
23 | };
|
24 | |
25 | // USART options.
|
26 | static const usart_options_t USART_OPTIONS = |
27 | {
|
28 | .baudrate = EXAMPLE_USART_BAUDRATE, |
29 | .charlength = 8, |
30 | .paritytype = USART_NO_PARITY, |
31 | .stopbits = USART_1_STOPBIT, |
32 | .channelmode = USART_NORMAL_CHMODE |
33 | };
|
34 | |
35 | |
36 | // Configure Osc0 in crystal mode (i.e. use of an external crystal source, with
|
37 | // frequency FOSC0) with an appropriate startup time then switch the main clock
|
38 | // source to Osc0.
|
39 | pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP); |
40 | |
41 | // Assign GPIO to USART.
|
42 | gpio_enable_module(USART_GPIO_MAP, |
43 | sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0])); |
44 | |
45 | // Initialize USART in RS232 mode.
|
46 | usart_init_rs232(EXAMPLE_USART, &USART_OPTIONS, EXAMPLE_TARGET_PBACLK_FREQ_HZ); |
47 | print(EXAMPLE_USART, ".: Using interrupts with the USART :.\r\n\r\n"); |
48 | |
49 | // Disable all interrupts.
|
50 | Disable_global_interrupt(); |
51 | |
52 | // Initialize interrupt vectors.
|
53 | INTC_init_interrupts(); |
54 | |
55 | // Register the USART interrupt handler to the interrupt controller.
|
56 | // usart_int_handler is the interrupt handler to register.
|
57 | // EXAMPLE_USART_IRQ is the IRQ of the interrupt handler to register.
|
58 | // AVR32_INTC_INT0 is the interrupt priority level to assign to the group of
|
59 | // this IRQ.
|
60 | // void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_level);
|
61 | INTC_register_interrupt(&usart_int_handler, EXAMPLE_USART_IRQ, AVR32_INTC_INT0); |
62 | |
63 | // Enable USART Rx interrupt.
|
64 | EXAMPLE_USART->ier = AVR32_USART_IER_RXRDY_MASK; |
65 | print(EXAMPLE_USART, "Type a character to use the interrupt handler.\r\n" |
66 | "It will show up on your screen.\r\n\r\n"); |
67 | |
68 | // Enable all interrupts.
|
69 | Enable_global_interrupt(); |
70 | |
71 | |
72 | // When the USART interrupt occurs, this will wake the CPU up which will then
|
73 | // execute the interrupt handler code then come back to the while(1) loop below
|
74 | // to execute the sleep instruction again.
|
75 | |
76 | while(1) |
77 | {
|
78 | // If there is a chance that any PB write operations are incomplete, the CPU
|
79 | // should perform a read operation from any register on the PB bus before
|
80 | // executing the sleep instruction.
|
81 | AVR32_INTC.ipr[0]; // Dummy read |
82 | |
83 | // Go to FROZEN sleep mode.
|
84 | SLEEP(AVR32_PM_SMODE_FROZEN); |
85 | // When the device wakes up due to an interrupt, once the interrupt is serviced,
|
86 | // go back into FROZEN sleep mode.
|
87 | }
|
Un dieser "cleared by side effect" scheint wohl nicht immer zu funktionieren und deswegen springt der uC immer wieder in diese ISR.
Keiner, der irgendwas zu den Interrupts bei AVR32 generel oder noch genauer zu den UART Interrupts was sagen?
Hallo Franzis, Ich habe gerade das gleiche Problem und bin über deinen Eintrag gestolpert... Konntest du inzwischen das Problem beheben mit dem clearen des Interruptflags? Würde mir sehr weiterhelfen...
Hallo zusammen, ich habe das gleiche Problem. Hat jemand von euch eine Lösung gefunden? Beste Grüße Locutus
Nachtrag: Bei mir funktioniert der Code solange ich eine Baudrate <3 Mega-Baud verwende. Gehe ich höher, passiert das gleiche wie oben Beschrieben Beste Grüße Locutus
Hallo, ich habe ein sehr sehr ähnliches Problem. Wenn ich ein Zeichen sende, klappt dies wunderbar. Wenn ich aber mehrere direkt hintereinander mit hterm versende, bekomme ich non stop das erste zurückgesendet. Auftreten tut dies auf einem AT32UC3A3256 mit 57600 Baud. Wenn ich die Baudrate auf 9600 senke, dann funktioniert alles. Hat jemand eine Lösung? Gruß Philipp
Hab' auch das Problem. Hat schon jemand eine Lösung!?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.