AT90CAN128 uart RX Interrupt

#3926521
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
}
#3926605
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.
#3926665
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
}
#3926705
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.
#3926716
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.

?

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