Hallo Leute! Dies ist mein erster Eintrag hier. Ich hoffe die Community kann mir bei meinem Problem weiterhelfen. Ich verwende ein STK 600 mit XMEGA 128 A1 und dem AVR Studio 5 mit ASF (Atmel Software Framework). Angehängt findet ihr die wichtigsten Programmfiles. Alle witeren Files findet man im ASF. Mein Problem ist nun das Triggern der ISR. Der Controller nimmt einfach kein Zeichen an, also die Routine wird nicht getriggert. Aktiviert habe ich die allgemeinen Interrupts, den PMIC, habe das Level für die ISR eingestellt (denke ich) und weiß nicht mehr weiter wieso es nicht funktioniert. Es wäre schön wenn mir jemand helfen könnte, der sich schon mit den Namendefinitionen des ASF vertraut gemacht hat, denn das Arbeiten mit den einzelnen Registern ist für mich noch zu kryptisch und nicht so einfach zu lernen. Mit freundlichen Grüßen Felix
Hallo, mit Atmel Studio 4 war es eine Kleinigkeit, jemand auf die Sprünge zu helfen. Heute wird das mit ASF schon schwieriger. Ein Tipp, baue das Programm mal so um, dass du eine serielle Schnittstelle über USART realisieren kannst. Ausgabe Terminal! Sollte das dann funktionieren, betreibst du den USART per Interrupt. Sollte das dann auch funktionieren, kannst du versuchen dein Programm Stück für Stück dem jetzigen Stand anzupassen. Wenn du im Studio 4 fit warst, gibt es auch eine andere Möglichkeit. In Studio 5 ein neues Projekt “C Executable Projekt “ anzulegen und deinen Code nach ART „ AVR Studio 4“ anzulegen. Hier ist der Fehler etwas leichter zu finden. Gruß Xmega
Hallo Stargat, ich hatte auch angefangen mit dem ASF zu arbeiten, hab aber ziemlich schnell aufgegeben, da ich nicht klar kam. Jetzt arbeite ich erstmal mit den Beispielen, die zum XMEGA explained Board auf der ATMEL hinterlegt sind, die funktionieren... Ich habe Dir mal das Beispiel für UART Interrupt angehangen. Vielleicht hilft es Dir. Gruß Frank
Hallo Gerhard, Frank! Ja, mit dem Studio 4 bin ich eben nicht gut klargekommen, weil das Programm einem nicht gut unter die Arme gegriffen hat (IMHO) wie das Studio 5. Außerdem habe ich nicht viel mit Studio 4 gemacht, da ich nach dem Programmieren mit BASCOM beim Wiedereinstieg auf das neuste Studio umsteigen wollte, damit ich gleich auf dem Laufenden bin. Ich wusste auch, dass er Support zum Anfang dann etwas weniger sein wird, aber man darf als Ingenieur auch Pionier sein. Zu deinem Tipp: Wenn du mal in das Programm reinschaust, dann findest du eine Ausgabezeile vor der Schleife, in der ich eine LED so lange blinken lasse, bis der Interrupt getriggert wird. Die Ausgabe funktioniert auch. Ich habe das Programm bereist aus dem Stadium herausgehievt, in dem ich den USART haltend (Progamm wartet auf Eingabe) steuern konnte. Zu Franks Anhang Vielen Dank dafür, ich werde mal schauen, was ich daaus verwerten kann. Ich werde es mal mit meinem Code vergleichen. Grüße Felix
Peter Dannegger schrieb: > Stargate schrieb: >> .baudrate = 9200, > > Wer macht denn sowas? > > > Peter Wo ist da das Problem?
Felix K. schrieb: > Peter Dannegger schrieb: >> Stargate schrieb: >>> .baudrate = 9200, >> >> Wer macht denn sowas? >> >> >> Peter > > Wo ist da das Problem? Das (mögliche) Problem ist, dass das eine SEHR ungewöhnliche Baudrate ist. Vermutlich wollte er eigentlich entweder 9600 oder 19200 haben.
So blind kann man sein ..... Vielen Dank! Das ist mir gar nicht aufgefallen. Leider hat mein Terminalprogramm (hTerm) das auch so decodiert. Leider ändert sich nichts am Verhalten der ISR. Sie springt einfach nicht an. Grüße Felix
Hallo, kann es sein, das Du das PMIC-Register nicht korrekt gesetzt hast?
1 | sysclk_enable_module(SYSCLK_PORT,PR_USART0_bm); |
2 | |
3 | usart_init_rs232(UART,&UART_OPTIONS); |
4 | usart_set_rx_interrupt_level(UART, USART_RXCINTLVL_LO_gc); |
5 | usart_set_tx_interrupt_level(UART, USART_TXCINTLVL_LO_gc); |
6 | PMIC.CTRL |= PMIC_LOLVLEX_bm | PMIC_HILVLEN_bm; |
Kommt von hier: Beitrag "xmega usart rxc interrupt" und hier: http://ottawarobotics.org/subversion/Members/andrzej/AVR/Xmega/shell01/main.c Gruß Frank
Hallo Frank! edit: Fehler entdeckt, siehe unten! Das hatte ich mir auch überlegt, aber mit dem Einfügen (und Modifizieren auf den benötigten USART) der Zeilen ist es leider nicht getan. Es ändert sich nichts. Beim Definieren (also dem Aufruf der Aktivierung des USART)
1 | #define CONF_BOARD_ENABLE_USARTC0
|
wird im ASF
1 | #ifdef CONF_BOARD_ENABLE_USARTC0
|
2 | ioport_configure_pin(IOPORT_CREATE_PIN(PORTC, 3), IOPORT_DIR_OUTPUT |
3 | | IOPORT_INIT_HIGH); |
4 | ioport_configure_pin(IOPORT_CREATE_PIN(PORTC, 2), IOPORT_DIR_INPUT); |
5 | #endif
|
definiert. Mit dem Aufruf von usart_init() in main() wird im Programmteil usart_diff_modes.c die Funktion usart_init_rs232 aufgerufen und alle Parameter übergeben. In der usart.c wird nun folgendes ausgeführt:
1 | void usart_init_rs232(USART_t *usart, const usart_rs232_options_t *opt) |
2 | {
|
3 | usart_enable_module_clock(usart); |
4 | usart_set_mode(usart, USART_CMODE_ASYNCHRONOUS_gc); |
5 | usart_format_set(usart, opt->charlength, opt->paritytype, |
6 | opt->stopbits); |
7 | usart_set_baudrate(usart, opt->baudrate, sysclk_get_per_hz()); |
8 | usart_tx_enable(usart); |
9 | usart_rx_enable(usart); |
10 | }
|
Die erste Anweisung führt nun folgendes aus:
1 | static inline void usart_enable_module_clock(USART_t *usart) |
2 | {
|
3 | #ifdef USARTC0
|
4 | if ((uintptr_t)usart == (uintptr_t)&USARTC0) { |
5 | sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); |
6 | }
|
7 | #endif
|
8 | ...
|
was der oben genannten Zeile:
1 | sysclk_enable_module(SYSCLK_PORT,PR_USART0_bm); |
entsprechen sollte?! Nun initialisiere ich den PMIC mit:
1 | pmic_init(); |
2 | |
3 | siehe ASF Code: |
4 | |
5 | //Enables all interrupt levels
|
6 | static inline void pmic_init(void) |
7 | {
|
8 | PMIC.CTRL = PMIC_LVL_LOW | PMIC_LVL_MEDIUM | |
9 | PMIC_LVL_HIGH; |
10 | }
|
was dem unten Stehenden doch entsprechen sollte, obwohl ich die Kombination aus Low Level Execution BitMask und Hi Level Enable BitMask nicht wirklich verstehe:
1 | PMIC.CTRL |= PMIC_LOLVLEX_bm | PMIC_HILVLEN_bm; |
Um das Interruptlevel im Code für den USART zu setzen habe ich in der usart_init() folgenden Code stehen:
1 | // Set the Level of PMIC to the initialized USART
|
2 | usart_set_rx_interrupt_level(&USARTC0,PMIC_LVL_LOW); |
Jetzt sehe ich grade, dass der zweite Parameter recht unterschiedlich ist.
1 | usart_set_rx_interrupt_level(UART, USART_RXCINTLVL_LO_gc); |
2 | usart_set_tx_interrupt_level(UART, USART_TXCINTLVL_LO_gc); |
Das war auch schon der Fehler: PMIC_LVL_LOW ist anscheinend nicht dafür gedacht, ein Level zu setzen, sondern nur um das entsprechende Level ein oder auszuschalten. Das macht mich aber sehr stutzig, denn die Funktion usart_set_rx_interrupt_level() erwartet folgendes:
1 | static inline void usart_set_tx_interrupt_level(USART_t *usart, |
2 | enum pmic_level level) |
und das enum ist definiert zu:
1 | enum pmic_level { |
2 | PMIC_LVL_LOW = PMIC_LOLVLEN_bm, //!< Low-level interrupts |
3 | PMIC_LVL_MEDIUM = PMIC_MEDLVLEN_bm, //!< Medium-level interrupts |
4 | PMIC_LVL_HIGH = PMIC_HILVLEN_bm, //!< High-level interrupts |
5 | /**
|
6 | * \brief Non-maskable interrupts
|
7 | * \note These cannot be enabled nor disabled.
|
8 | */
|
9 | PMIC_LVL_NMI = PMIC_NMIEX_bp, |
10 | };
|
Somit dachte ich dass ich eben das Level mit PMIC_LVL_L/M/H festlegen muss. Vielleicht kann mir das jemand nochmal erklären, ebenso was die _gc Maske für das Register denn nun macht, bzw wofür _gc steht. Vielen Dank für all die Vorschläge. Ich hoffe ja, dass sich bald noch mehr Leute mit dem Software Framework beschäftigen :-) Gruß Felix
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.