Atmega2560 USART Interrupt

Gast #2946887
Lesenswert?

Hallo an alle,

Irgendwie verzweifel ich grad. Ich versuche für meinen ATMega2560 mit 
dem Entwicklungboard Arduino MEGAAdk mein USART1 mit einem Receive 
Interrupt zu konfigurieren.

Analog beim ATmega 8 klappt es...

Wäre schön, wenn ihr mir helfen könnten.

Hier mein Code:
1
#include "usart.h"
2

3

4
//The setup function is called once at startup of the sketch
5
void setup()
6
{
7
  USART_init_();
8
//  SetINT_init();
9
//  sei();
10

11
}
12

13
// The loop function is called in an endless loop
14
void loop()
15
{
16

17
}
18

19
ISR(USART1_RX_vect)          // USART1_RX_vect ?? funzt noch nicht!!!
20
{
21

22
  Sende_Char('n');
23

24
}
----------------------------------------------------------------

meine usart.c:
1
#include <stdint.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <stdlib.h>
5
#include <stdio.h>
6

7
/*Die UART-Schnittstellen werden Initialisiert
8
 * */
9
void USART_init_(void) {
10
  UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1) | (1 << TXCIE1); //Enable Receiver and Transmitter 1, RX Complete Interrupt Enable 1,  TX Complete Interrupt Enable 1
11
  UCSR2B = (1 << RXEN2) | (1 << TXEN2) | (1 << RXCIE2) | (1 << TXCIE2); //Enable Receiver and Transmitter 2, RX Complete Interrupt Enable 2,  TX Complete Interrupt Enable 2
12
  UCSR3B = (1 << RXEN3) | (1 << TXEN3) | (1 << RXCIE3) | (1 << TXCIE3); //Enable Receiver and Transmitter 3, RX Complete Interrupt Enable 3,  TX Complete Interrupt Enable 3
13

14
  UCSR1C = (1 << UCSZ11) | (1 << UCSZ10);                         //8 Databits
15
  UCSR2C = (1 << UCSZ21) | (1 << UCSZ20);                         //8 Databits
16
  UCSR3C = (1 << UCSZ31) | (1 << UCSZ30);                         //8 Databits
17

18
  UBRR1 = 25;                   //Einstellen der Baudrate 38400
19
  UBRR2 = 25;                   //Einstellen der Baudrate 38400
20
  UBRR3 = 25;                   //Einstellen der Baudrate 38400
21

22
}
23

24
/*Set Interrupts (global)
25
 * */
26
void SetINT_init(void) {
27
  sei();
28
}
29

30
/*Funktion zum �bertragen eines chars
31
 * */
32
void Sende_Char(char c) {
33
  /*Wert:   xxxx xxxx
34
   *Maske:  0001 0000  &
35
   *      ---------
36
   *Ergebnis:  000x 0000
37
   *Ergebnis:  !(true oder false)
38
   * */
39
  while (!(UCSR1A & (1 << UDRE1)))
40
    ;  //Warten bis USART zum schreiben bereit ist
41
  UDR1 = c;            
42
}
43

44
/*Funktion zum Empfangen eines chars
45
 * */
46
uint8_t Lese_Zeichen() {
47
  uint8_t z;
48
  if (UCSR1A & (1 << RXC1))  //Pr�fe, ob Datenbyte empfangen wurde
49
    z = UDR1;
50
  else
51
    z = 0xFF;// Der Wert 0xFF spielt bei Strings keine Bedeutung deshalb kann er als Leerzeichen interpretiert werden
52
  return z;
53
}
54

55
/*Funktion zur �bergabe der Zeichenkette
56
 *die �bertragen werden soll
57
 */
58
void Sende_String(char *s) {
59
  while (*s)            //bis string ausgelesen gelesen
60
  {
61
    Sende_Char(*s);        //Funktionsaufruf
62
    s++;            //speicherstelle erh�hen
63
  }
64
  s = 0;              //Speicherstelle zur�cksetzen
65
}



BITTE UM HILFE!!!
#2947023
Lesenswert?

simon schrieb:


> Irgendwie verzweifel ich grad. Ich versuche für meinen ATMega2560 mit
> dem Entwicklungboard Arduino MEGAAdk mein USART1 mit einem Receive
> Interrupt zu konfigurieren.

Hast du es denn ohne Interrupt schon mal probiert.
Und da am besten mal einfach nur Senden lassen, damit du am PC siehst ob 
und wenn ja was am PC ankommt (sprich ob die ganze Taktung inkl Baudrate 
stimmt)

> Analog beim ATmega 8 klappt es...

Gewöhn dich an die Vorstellung, dass man Code nicht einfach von einem µC 
auf einen anderen übernehmen kann. Man kann die Grundidee und Codeteile 
übernehmen, aber dann behandelt man den Code so, wie wenn man ihn neu 
schreiben müsste. D.h. ALLES wird mit dem Datenblatt kontrolliert.
Insofern ist es irrelevant, ob das mit dem Mega8 funktioniert hat oder 
nicht. Das ist ein neues Programm und das soll auf einem 2560 laufen. 
Und nur das zählt.


> void setup()
> {
>   USART_init_();
> //  SetINT_init();
> //  sei();
>
> }

OHne freigegbenen Interrupts wirds aber nichts mit dem Receive Interrupt

> void USART_init_(void) {
>   UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1) | (1 << TXCIE1);
> //Enable Receiver and Transmitter 1, RX Complete Interrupt Enable 1,  TX
> Complete Interrupt Enable 1
>   UCSR2B = (1 << RXEN2) | (1 << TXEN2) | (1 << RXCIE2) | (1 << TXCIE2);
> //Enable Receiver and Transmitter 2, RX Complete Interrupt Enable 2,  TX
> Complete Interrupt Enable 2
>   UCSR3B = (1 << RXEN3) | (1 << TXEN3) | (1 << RXCIE3) | (1 << TXCIE3);
> //Enable Receiver and Transmitter 3, RX Complete Interrupt Enable 3,  TX
> Complete Interrupt Enable 3

Es ist keine so gute Idee, alle Interrupts auf Verdacht freizugeben. Vor 
allen Dingen dann nicht, wenn man keine ISR dazu hat. Denn wenn der 
Interrupt auftritt, und es keine ISR dafür gibt, dann wird das mit einem 
Prozessor-Reset quittiert. Insofern hast du zwar den Transmit Complete 
Interrupt freigegeben, aber keine ISR dafür. Ergo ....
Gast #2947063
Lesenswert?

Hallo Karl Heinz Buchegger,

Vielen Dank für deine Antwort.

Das Senden vom Mikrocontroller aus funktioniert einwandfrei. ich habe 
dazu einfach in die loop() die Funktion Sende_Char('h'); geschrieben.



Meine Korrekturen:
1
void USART_init_(void) {
2
  UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1); // | (1 << TXCIE1); //Enable Receiver and Transmitter 1, RX Complete Interrupt Enable 1,  TX Complete Interrupt Enable 1
3
  UCSR1C = (1 << UCSZ11) | (1 << UCSZ10) | (1<<UMSEL10);          //8 Databits, Synchron
4
  UBRR1 = 25;                   //Einstellen der Baudrate 38400
5
  
6
}

und
1
ISR(USART_RX_vect)          // USART1_RX_vect ?? funzt noch nicht!!!
2
{
3

4
  Sende_Char('n');
5

6
}
7
ISR(USART_UDRE_vect)          // USART1_RX_vect ?? funzt noch nicht!!!
8
{
9

10
  Sende_Char('m');
11

12
}

leider funktioniert es immer noch nicht.

Hast du noch weitere Tipps?
#2947092
Lesenswert?

Die ISR kann nicht
1
ISR(USART_RX_vect)

USART_RX_vect heissen!
Du hast mehere UARTS und jede hat ihren eigenen Interrupt Vektor. Die 
Erwartung ist also, dass die Nummer der UART für die diese ISR zuständig 
ist, sich im Namen der ISR niederschlägt.

Du hast ja hier
1
   UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1);
auch überall die '1' für die UART mit der Nummer 1 drinnen.


Hast du keine Compiler Warnung bekommen?
#2947303
Lesenswert?

simon schrieb:

> das habe ich behoben, dennoch keine Änderung...  :(

Was hast du behoben?

Hast du auch die Interrupts mittels sei() freigegeben?


Tu dir selbst einen Gefallen und zeig IMMER deinen kompletten Code. Häng 
das File einfach als Attachment an, das ist schon ok.
Aber dadurch, dass du uns auf dieser Seite des Monitors Rätselraten 
lässt, was und wie du deinen Code verändert hast, wird die Sache nicht 
besser.
#2947323
Lesenswert?

sei() ist auskommentiert und kommt in setInt() nochmal vor, welche aber 
nicht aufgerufen wird. Was machst du da eigentlich fürn crap?
Was hat die "usart.c" mit deinen Interrupts und vorallem dem I-Bit zu 
tun? Das gehört da nicht rein. Kapsle deinen Code ordentlich. Jedes 
Modul hat ne bestimmte Aufgabe. Die Aufgabe der uart.c ist bestimmt 
NICHT die Interrupts global zu schalten.
Wäre so es so schwer in die main vor der Hauptschleife ein sei() zu 
machen? In deiner Arduino/Sketch Deppenumgebung wäre das dann wohl die 
setup(). Das sei() dort wieder entkommentieren.
Gast #2947725
Lesenswert?

Hallo, danke für eure Tipps.

Ich denke ich ahbe sie alle mit eingebunden.  Im Anhang findet ihr 
meinen Code.

Und hier die das Main-Programm

// Do not remove the include below
#include "rs232.h"
#include "usart.h"
1
ISR(USART0_RX_vect)          // USART1_RX_vect ?? funzt noch nicht!!!
2
{
3
  UDR0 = 'x';
4
}
5

6
//The setup function is called once at startup of the sketch
7
void setup()
8
{
9
  USART_init_();
10
  sei();
11

12

13
}
14

15
// The loop function is called in an endless loop
16
void loop()
17
{
18

19
}

AAUSGABE: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Nur zur Erklärung:
ich möchte mit einem Terminal-Programm ein Zeichen senden. dann soll die 
ISR() sich melden und ggf etwas senden.

Ich bin euch für die Hilfe sehr dankbar!


Viele Grüße,
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren