Forum: Compiler & IDEs AVR Xmega USART Interrupt Problem


von Stargate (Gast)


Angehängte Dateien:

Lesenswert?

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

von Gerhard G. (xmega)


Lesenswert?

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

von Frank L. (franklink)


Angehängte Dateien:

Lesenswert?

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

von Peter D. (peda)


Lesenswert?

Stargate schrieb:
>   .baudrate = 9200,

Wer macht denn sowas?


Peter

von Felix K. (stargate)


Lesenswert?

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

von Felix K. (stargate)


Lesenswert?

Peter Dannegger schrieb:
> Stargate schrieb:
>>   .baudrate = 9200,
>
> Wer macht denn sowas?
>
>
> Peter

Wo ist da das Problem?

von Stefan E. (sternst)


Lesenswert?

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.

von Felix K. (stargate)


Lesenswert?

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

von Frank L. (franklink)


Lesenswert?

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

von Felix K. (stargate)


Lesenswert?

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
Noch kein Account? Hier anmelden.