Forum: Mikrocontroller und Digitale Elektronik ATSAM3U4E - USART Interrupt


von Mark (Gast)


Lesenswert?

Hallo Leute,

ich arbeite gerade mit dem Eval-Kit SAM3U-EK von Atmel. Der darauf 
verbaute ARM ATSAM3U4E ärgert mich zur Zeit ein wenig.

Konkret geht es mir um die USART Schnittstelle. Ich bin bereits soweit 
das ich problemlos senden kann, nur das Empfangen(per Interrupt) 
funktioniert nicht richtig.

Aber hier erstmal der Init Code der USART1:
1
void USARTInit(void)
2
{
3
4
  /*1. init PIOA&USART1*/
5
    //enable necessary peripheral clocks
6
    PMC->PMC_PCER = (0x1 << ID_PIOA  )|      //enable PIOA clock
7
                       (0x1 << ID_USART1);          //enable USART1 clock  
8
9
  /*2. configure PIOA*/
10
    //disable pin charge interrupt for usart pins
11
      PIOA->PIO_IDR    =  (PIO_PA21A_RXD1 | PIO_PA20A_TXD1);
12
13
    //disable pullups for usart pins
14
    PIOA->PIO_PUDR   =  (PIO_PA21A_RXD1 | PIO_PA20A_TXD1);
15
16
    //disable pio controller for usart pins(enables peripheral control of the pin)
17
    PIOA->PIO_PDR    =  (PIO_PA21A_RXD1 | PIO_PA20A_TXD1);
18
19
    //select corresponding peripheral for usart1 
20
    PIOA->PIO_ABSR  &= ~(PIO_PA21A_RXD1 | PIO_PA20A_TXD1);
21
        
22
  /*3. configure USART1*/
23
    //reset receiver and transmitter
24
    USART1->US_CR    = US_CR_RSTRX   | US_CR_RSTTX;
25
        
26
    //disable all interrupts
27
    USART1->US_IDR   = 0xFFFFFFFF;
28
29
    //set needed interrupts
30
    USART1->US_IER  = (1<<3);
31
        
32
    //set baut rate factor
33
    USART1->US_BRGR  = BAUD(9600);
34
        
35
    //set usart mode
36
    USART1->US_MR =  (0x0 <<  0)|        //normal mode
37
                       (0x0 <<  4)|                 //use main clock
38
                       (0x3 <<  6)|                 //character length: 8 bits
39
                       (0x4 <<  9)|                 //no parity
40
                       (0x0 << 12)|                 //1 stop bit
41
                       (0x0 << 14);                 //normal mode: the USART channel operates as an RX/TX USART
42
    
43
    //disbale peripheral DMA controller for transmitter/receiver
44
    USART1->US_PTCR  = US_PTCR_RXTDIS | US_PTCR_TXTDIS;
45
46
    //enable receiver and transmitter
47
    USART1->US_CR    = US_CR_RXEN     | US_CR_TXEN;
48
49
  /*4. activate interrupts*/
50
    //set interrupt values
51
    NVIC_DisableIRQ(USART1_IRQn);
52
    NVIC_ClearPendingIRQ(USART1_IRQn);
53
    NVIC_SetPriority(USART1_IRQn,5);
54
    NVIC_EnableIRQ(USART1_IRQn);
55
56
};

hier der Interrupt Handler Code:
1
void USART1_IRQHandler(void)
2
{
3
  //init/vars
4
  unsigned int InterruptStatus;
5
6
   //read out interrupt stat
7
  InterruptStatus = USART1->US_CSR;
8
9
  //send back(test command)
10
  //SER_putChar(USART1->US_RHR);
11
12
  //reset status bits
13
  USART1->US_CR = US_CR_RSTSTA;
14
  
15
  //dummy action, to prevent compiler optimation
16
  InterruptStatus++;
17
};

und noch der Vollständigkeit halber:
1
void SER_putChar(char c)
2
{
3
  while (!(USART1->US_CSR & US_CSR_TXRDY)){};
4
   
5
  USART1->US_THR = c;
6
};

Problem ist, dass der sofort in den Interrupt springt wenn ich die USART 
aktiviere, und da nie wieder raus kommt.
(getestet mit dem 'SER_putChar' Kommando, er schickt mir in einer 
Endlosschleife das Zeichen zurück was zuletzt empfangen wurde)

Andere ISRs (zb Timer/RTC/...) funktionieren einwandfrei und werden 
"beendet" sobald ich das jeweilig zugehörige Status Register lese.

Wie komme ich aus der USART1 ISR wieder raus?

Gruß,
Mark

von Mark (Gast)


Lesenswert?

ok, hab die Lösung gefunden:

das "USART1->US_IER  = (1<<3);" muss durch "USART1->US_IER  = (1<<0);" 
ersetz werden, damit ich auch wirklich den Interrupt habe, den ich auch 
möchte.

...eine einfache Zahl kann ganz schön aufhalten...

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.