Forum: Mikrocontroller und Digitale Elektronik AT90CAN128 uart RX Interrupt


von Franz S. (franz_0815)


Lesenswert?

Hallo
Beschäftige mich gerade mit dem Prozessor AT90CAN128

Beim Empfangen von Daten über RXD0 resetet mein System.

Das ende klappt.
Aber auch nur beim Empfangen von einen char tillt alles.

??
Gruss
1
//C Code Example (1)
2
#include "pins.h"
3
#include "uart.h"
4
#include <avr/interrupt.h>
5
6
unsigned int buffercounter = 0;
7
char usart_rx_buffer[BUFFER_SIZE],newdata;
8
char *rx_buffer_pointer_in  = &usart_rx_buffer[0];
9
char *rx_buffer_pointer_out  = &usart_rx_buffer[0];
10
unsigned char receive_char;  
11
12
13
void USART0_Init (unsigned long baudrate)
14
//void USART0_Init (unsigned long baudrate)
15
{
16
17
  unsigned long baud = (F_CPU/(16*baudrate))-1;
18
  SETBIT (DDRE,PE1);
19
  /* Set baud rate */
20
  UBRR0H = (unsigned char) (baud>>8);
21
  UBRR0L = (unsigned char) baud;
22
  /* Set frame format: 8data, no parity & 2 stop bits */
23
  UCSR0C = (0<<UMSEL0) | (0<<UPM0) | (1<<USBS0) | (3<<UCSZ0);
24
  /* Enable receiver and transmitter */
25
//  UCSR0B = (1<<RXEN0) | (1<<TXEN0);
26
    UCSR0A =0;
27
  UCSR0B =(1 << TXEN0 | 1 << RXEN0 | 1<< RXCIE0);
28
  //return baud;
29
}
30
//C Code Example (1)
31
void USART0_Transmit (unsigned char data)
32
{
33
  /* Wait for empty transmit buffer */
34
  while ( ! ( UCSR0A & (1<<UDRE0)));
35
  /* Put data into buffer, sends the data */
36
  UDR0 = data;
37
}
38
39
void SendRs232(char* string)//Nullterminiert
40
{
41
  unsigned char ende = 0;
42
  int i=0;
43
  while(!ende)
44
  {
45
    unsigned char data = string[i++];
46
    if(data == 0)
47
      ende = 1;
48
    else
49
      USART0_Transmit(data);
50
  }
51
}
52
53
ISR (USART_RX0)
54
{
55
56
57
      while (!(UCSR0A & (1<<RXC0)));
58
       receive_char=UDR0;
59
/*    receive_char=UDR0 &127;  // &127 damit auch 7 Datenbit funktioniert.
60
    usart_rx_buffer[buffercounter]=receive_char;
61
  buffercounter++;
62
63
    if((buffercounter > BUFFER_SIZE - 1)||(receive_char==13)) 
64
   {
65
     if((buffercounter < BUFFER_SIZE )&&(receive_char==13))
66
         usart_rx_buffer[buffercounter+1]=0; // f?r stringende !
67
     buffercounter=0;
68
   }
69
 */
70
71
72
}

von Tom (Gast)


Angehängte Dateien:

Lesenswert?

Im Anhang das ganze in lesbar. Jede IDE und jeder bessere Editor hat 
automatische Formatierung. Wie kann man in so einem Wust programmieren 
und hoffen, den Überblick zu behalten?

von Karl H. (kbuchegg)


Lesenswert?

Franz Suahnein schrieb:

> ISR (USART_RX0)

Bist du sicher, dass der Name des Interrupt-Vektors, USART_RX0, korrekt 
ist?
Da zb das entsprechende Bit im UCSR0A den Namen RXC0 trägt, hätte ich 
als Name jetzt mal eher USART_RXC0 angenommen. Aber ich gebe zu, dass 
Atmel da mit den Bezeichnungen nicht ganz einheitlich ist. Allerdings 
teilt dir der Compiler ja als Warnung mit, dass er mit dem Namen des 
INterrupts nichts anfangen kann.
Allerdings ist es auch so, dass das Symptom "Reset beim Auftreten eines 
Interrupt Ereignisses" ein deutliches Indiz für einen Schreibfehler im 
Interrupt Namen ist

>       while (!(UCSR0A & (1<<RXC0)));

das ist ziemlich sinnlos.
Die Interrupt Funktion ist aufgerufen worden, WEIL ein Zeichen an der 
UART vorliegt, das abgeholt werden will. Das brauchst du hier nicht mehr 
testen. An dieser Stelle steht einwandfrei und zweifellos fest, dass es 
ein Zeichen in UDR0 gibt.

von Franz S. (franz_0815)


Lesenswert?

Hallo
So mal geändert.
Aber der Prozessor resetet nicht sonder kommt garnicht mehr.

Bei dem AT90CAN128 ist das ISP System auch auf TX0 RX0,also 
zusammengeschaltet mit MISO und MOSI.

Auch die Routine ohne Interrupt bringt das programm zu stehen.
Mit dem Ozsi sieht alles gut auch.
Auch nach dem programmieren das den AVR-ISP entfernen bringt nichts.

?
Was kann es noch sein.

1
ISR(USART0_vec)
2
/
3
/ISR (USART0)
4
{
5
6
main_counter++;
7
//      while (!(UCSR0A & (1<<RXC0)));
8
     receive_char=UDR0;
9
/*    receive_char=UDR0 &127;  // &127 damit auch 7 Datenbit funktioniert.
10
    usart_rx_buffer[buffercounter]=receive_char;
11
  buffercounter++;
12
13
    if((buffercounter > BUFFER_SIZE - 1)||(receive_char==13)) 
14
   {
15
     if((buffercounter < BUFFER_SIZE )&&(receive_char==13))
16
         usart_rx_buffer[buffercounter+1]=0; // f?r stringende !
17
     buffercounter=0;
18
   }
19
 */
20
21
22
}
23
24
uint8_t USART0_Receive(void)  
25
{
26
  while ( !(UCSR0A & (1<<RXC0)) );
27
  main_counter++;
28
  return UDR0;
29
}

von Karl H. (kbuchegg)


Lesenswert?

Franz Suahnein schrieb:

> Auch die Routine ohne Interrupt bringt das programm zu stehen.

Hast du auch die Freigabe des Interrupts hier
1
  UCSR0B =(1 << TXEN0 | 1 << RXEN0 | 1<< RXCIE0);
rausgenommen?

Man kann es nicht oft genug betonen.
Wenn es eine ISR nicht gibt, du den entsprechenden Interrupt aber 
freigibt, dann kommt es beim Auftreten des Interrupts zu einem Reset.
Ob es die ISR nicht gibt, weil du sie nicht geschrieben hast, oder weil 
sie nicht als solche erkannt wurde, weil du dich im Namen vertan hast, 
ist dabei unerheblich. Nicht benutzbar ist nicht benutzbar und der dann 
benutzte Default-Handler macht nun mal einen Reset.

von Franz S. (franz_0815)


Lesenswert?

void USART0_Init (unsigned long baudrate)
//void USART0_Init (unsigned long baudrate)
{

  unsigned long baud = (F_CPU/(16*baudrate))-1;
  /* Set baud rate */
  UBRR0H = (unsigned char) (baud>>8);
  UBRR0L = (unsigned char) baud;
  /* Set frame format: 8data, no parity & 2 stop bits */
  UCSR0C = (0<<UMSEL0) | (0<<UPM0) | (1<<USBS0) | (3<<UCSZ0);
  /* Enable receiver and transmitter */
//  UCSR0B = (1<<RXEN0) | (1<<TXEN0);
  UCSR0B =(1 << TXEN0 | 1 << RXEN0 | 0<< RXCIE0);
}


Will hoffen das mit dem "0<<RXCIE0" richtig ist.

ISR(USART0_vec)

sollte doch auch richtig sein.

?

von Franz S. (franz_0815)


Lesenswert?

hallo
Menschen der Elektronik, Gemeinschaft der Elektroniker !!

ISR(USART0_RX_vect)

http://www.atmel.com/webdoc/avrlibcreferencemanual/group__avr__interrupts.html

""Man kann es nicht oft genug betonen.""

Danke Karl Heinz.

von Peter D. (peda)


Lesenswert?

Es sollte eigentlich ne Warnung geben:
1
main.c:8: warning: 'BLA_BLUB_Vect' appears to be a misspelled signal handler

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.