Forum: Mikrocontroller und Digitale Elektronik AT90CAN128 - UART Interupt Problem


von Andreas P. (Gast)


Lesenswert?

Hi @ all,

ich habe folgendes Problem. Ich habe das Atmel DVK90CAN1 
Entwicklungsboard mit dem AT90CAN128 µC und mein USART1 Empfängt nichts.
Der Kontroller besitzt zwei USART aber um LIN Botschaften zu 
senden/empfangen muss der 2 USART (USART1) angesteuert werden, da dieser 
an dem LIN Transceiver angeschlossen ist (RxLIN-->PD2, TxLIN-->PD3, 
NotSleep-->PD7).
Ich kann soweit auch wunderbar Nachrichten vom Board aus LIN Nachrichten 
versenden (USART1 funktioniert in diese Richtung) aber ich kann nichts 
empfangen.
Empfangen werden die Nachrichten über einen Interupt ISR(USART1_RX_vect) 
aber hier kommt nichts an... warum ??

Stimmen meine Einstellungen und wofür genau ist SREG, habe ich noch 
nicht ganz kapiert!

Meine Port-Einstellungen sehen wie folgt aus:
1
DDRE = 0x0B;  // Pins für Taster auf Port E als Eingang=0 definiert
2
  PORTE |= (1<<PE7); //Pullup für Taster aktivieren
3
  
4
  // Port A (0101 0101)
5
  DDRA = 0xFF;  // Alle Pins auf Port A (LEDs) als Ausgang definiert
6
  PORTA |= (1<<PA0)|(1<<PA2)|(1<<PA4)|(1<<PA6); // Einzelne LEDs anschalten
7
8
  uart_init(); //Schnittstelle inistiallisiern
9
10
// Port D0 als Ausgang für ????  <-- WOFÜR ????????
11
  // Port D3 als Ausgang für LIN TX
12
  // Port D7 als Ausgang für NOTSleepLIN <-- LIN Aktivieren
13
DDRD |= (1<<DDD0) | (1<<DDD3) | (1<<DDD7); // DDR = Data Direction Register
14
  
15
  // Port D2 als Eingang für LIN RX
16
  DDRD &= ~(1<<DDD2);
17
18
19
  // Ports auf HIGH   Pullup
20
  //      ????      RxLIN    TxLIN     NOTSleepLIN
21
  PORTD |= (1<<PD0) | (1<<PD2) | (1<<PD3) | (1<<PD7);
22
      
23
  SREG |= 0xE0;  // Das "Status Register" aktiviert die externen ISR 
24
          // für RX,TX,UDR (siehe Seite 197)
25
26
sei();  // Globales Interrrupt Flag setzten


Hier noch die UART Init:
1
void uart_init()
2
{
3
  /* set baud rate */
4
  UBRRH = UBRRVAL >> 8;
5
  UBRRL = UBRRVAL & 0xff;
6
  /* set frame format: 8 bit, no parity, 1 bit */
7
  UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0);
8
  
9
  // Receiver und Transmitter einschalten UND (Transmitt) und Receive Interrupts einschalten
10
//  UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); // | (1 << TXCIE);
11
  
12
  /* enable serial receiver and transmitter */
13
  #if !USE_SLEEP
14
    UCSRB = (1 << RXEN) | (1 << TXEN);
15
  #else
16
    UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
17
  #endif
18
}

von Karl H. (kbuchegg)


Lesenswert?

Andreas P. schrieb:

> Stimmen meine Einstellungen und wofür genau ist SREG, habe ich noch
> nicht ganz kapiert!

Das SREG Register geht dich nichts an. Das lässt du in Ruhe!

Wenn du die INterrupts global aktivieren willst, dann rufst du
1
    sei();
auf, und wenn du die Interrupts global deaktivieren willst, dann rufst 
du
1
    cli();
auf.


>   SREG |= 0xE0;  // Das "Status Register" aktiviert die externen ISR
>           // für RX,TX,UDR (siehe Seite 197)

Lass das SREG in Ruhe!

1
  #if !USE_SLEEP
2
    UCSRB = (1 << RXEN) | (1 << TXEN);
3
  #else
4
    UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
5
  #endif
Hast du ein #define für USE_SLEEP?

von Andreas P. (Gast)


Lesenswert?

Hallo Kalr,

danke für die Antwort!

Ich habe das SREG jetzt auskommentiert aber es hat sich noch immer 
nichts verändert.
Ein DEFINE für USE_SLEEP habe ich (#define USE_SLEEP 1).
ich benutze die UART Lib von Roland Riegel.

Gruß Andreas

von Andreas P. (Gast)


Lesenswert?

Hier noch meine komplette UART.c
Ganz am Ende ist das UART1_Interrupt deklariert aber es wird nicht 
ausgeführt bei Empfang auf dem LIN oder beim Senden mit HTerm
1
/*
2
 * Copyright (c) 2006-2009 by Roland Riegel <feedback@roland-riegel.de>
3
 *
4
 * This file is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License version 2 as
6
 * published by the Free Software Foundation.
7
 */
8
9
#include <stdio.h>
10
#include <avr/interrupt.h>
11
#include <avr/io.h>
12
#include <avr/pgmspace.h>
13
#include <avr/sfr_defs.h>
14
#include <avr/sleep.h>
15
16
#include "uart.h"
17
#include "globals.h"
18
19
/* some mcus have multiple uarts */
20
#ifdef UDR1
21
#define UBRRH UBRR1H
22
#define UBRRL UBRR1L
23
#define UDR UDR1
24
25
#define UCSRA UCSR1A
26
//#define UDRE UDRE1
27
28
29
#define UCSRB UCSR1B
30
31
#define UCSRC UCSR1C
32
#define URSEL
33
34
#define UCSRC_SELECT 0
35
#else
36
#define UCSRC_SELECT (1 << URSEL)
37
#endif
38
39
#ifndef USART_RXC_vect
40
41
#if defined(UART1_RX_vect)
42
#define USART_RXC_vect UART1_RX_vect
43
44
#elif defined(UART_RX_vect)
45
#define USART_RXC_vect UART1_RX_vect
46
47
#elif defined(USART1_RX_vect)
48
#define USART_RXC_vect USART1_RX_vect
49
50
#elif defined(USART_RX_vect)
51
#define USART_RXC_vect USART1_RX_vect
52
53
#elif defined(USART1_RXC_vect)
54
#define USART_RXC_vect USART1_RXC_vect
55
56
#elif defined(USART_RXC_vect)
57
#define USART_RXC_vect USART1_RXC_vect
58
#else
59
#error "Uart receive complete interrupt not defined!"
60
#endif
61
#endif
62
63
#define BAUD 19200UL  // Default 57600UL
64
#define UBRRVAL (F_CPU/(BAUD*16)-1)
65
#define USE_SLEEP 1
66
67
void uart_init()
68
{
69
  // Setze Baudrate
70
  UBRRH = UBRRVAL >> 8;
71
  UBRRL = UBRRVAL & 0xFF;
72
    
73
  // set frame format: 8 bit, no parity, 1 bit
74
  UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0);
75
76
  // Receiver und Transmitter einschalten UND (Transmitt) und Receive Interrupts einschalten
77
//  UCSRB = (1 << RXEN) | (1 << TXEN);// | (1 << RXCIE); // | (1 << TXCIE);
78
  
79
  // enable serial receiver and transmitter
80
  #if !USE_SLEEP
81
    UCSRB = (1 << RXEN) | (1 << TXEN);
82
  #else
83
    UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
84
  #endif
85
86
}
87
88
89
void uart_deak()
90
{
91
  //UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0);
92
  UCSRA=0x00;
93
  UCSRB=0x00;
94
  UCSRC=0x00;
95
}
96
97
void uart_putc(uint8_t c)
98
{
99
  if (c == '\n')
100
    uart_putc('\r');
101
102
  /* wait until transmit buffer is empty */
103
  while (!(UCSR1A & (1 << UDRE1)))
104
    ;
105
106
  /* send next byte */
107
  UDR = c;
108
}
109
110
void uart_putc_hex(uint8_t b)
111
{
112
  /* upper nibble */
113
  if ((b >> 4) < 0x0a)
114
    uart_putc((b >> 4) + '0');
115
  else
116
    uart_putc((b >> 4) - 0x0a + 'a');
117
118
  /* lower nibble */
119
  if ((b & 0x0f) < 0x0a)
120
    uart_putc((b & 0x0f) + '0');
121
  else
122
    uart_putc((b & 0x0f) - 0x0a + 'a');
123
}
124
125
void uart_putw_hex(uint16_t w)
126
{
127
  uart_putc_hex((uint8_t) (w >> 8));
128
  uart_putc_hex((uint8_t) (w & 0xff));
129
}
130
131
void uart_putdw_hex(uint32_t dw)
132
{
133
  uart_putw_hex((uint16_t) (dw >> 16));
134
  uart_putw_hex((uint16_t) (dw & 0xffff));
135
}
136
137
void uart_putw_dec(uint16_t w)
138
{
139
  uint16_t num = 10000;
140
  uint8_t started = 0;
141
142
  while (num > 0)
143
  {
144
    uint8_t b = w / num;
145
    if (b > 0 || started || num == 1)
146
    {
147
      uart_putc('0' + b);
148
      started = 1;
149
    }
150
    w -= b * num;
151
152
    num /= 10;
153
  }
154
}
155
156
void uart_putdw_dec(uint32_t dw)
157
{
158
  uint32_t num = 1000000000;
159
  uint8_t started = 0;
160
161
  while (num > 0)
162
  {
163
    uint8_t b = dw / num;
164
    if (b > 0 || started || num == 1)
165
    {
166
      uart_putc('0' + b);
167
      started = 1;
168
    }
169
    dw -= b * num;
170
171
    num /= 10;
172
  }
173
}
174
175
void uart_puts(const char* str)
176
{
177
  while (*str)
178
    uart_putc(*str++);
179
}
180
181
void uart_puts_p(PGM_P str)
182
{
183
  while (1)
184
  {
185
    uint8_t b = pgm_read_byte_near(str++);
186
    if (!b)
187
      break;
188
189
    uart_putc(b);
190
  }
191
}
192
193
uint8_t uart_getc()
194
{
195
  /* wait until receive buffer is full */
196
#if USE_SLEEP
197
  uint8_t sreg = SREG;
198
  sei();
199
200
  while (!(UCSRA & (1 << RXC)))
201
  //  sleep_mode();
202
203
  SREG = sreg;
204
#else
205
  while(!(UCSRA & (1 << RXC)));
206
#endif
207
208
  uint8_t b = UDR;
209
  if (b == '\r')
210
    b = '\n';
211
212
  return b;
213
}
214
215
void uart_gets(char* Buffer, uint8_t MaxLen)
216
{
217
  uint8_t NextChar;
218
  uint8_t StringLen = 0;
219
220
  NextChar = uart_getc(); // Warte auf und empfange das nächste Zeichen
221
222
  // Sammle solange Zeichen, bis:
223
  // * entweder das String Ende Zeichen kam
224
  // * oder das aufnehmende Array voll ist
225
  while (NextChar != '\n' && StringLen < MaxLen - 1)
226
  {
227
    *Buffer++ = NextChar;
228
    StringLen++;
229
    NextChar = uart_getc();
230
  }
231
232
  // Noch ein '\0' anhängen um einen Standard
233
  // C-String daraus zu machen
234
  *Buffer = '\0';
235
}
236
237
//EMPTY_INTERRUPT(USART_RXC_vect)
238
239
ISR (USART1_RXC_vect)   // UART1
240
{
241
   PORTA = ~PORTA;
242
//   sync_flag=1;
243
//   UCSRA &= ~(1 << RXC);
244
   
245
   //U8 u = UDR;
246
}

von Karl H. (kbuchegg)


Lesenswert?

Das hier
1
#if USE_SLEEP
2
  uint8_t sreg = SREG;
3
  sei();
4
5
  while (!(UCSRA & (1 << RXC)))
6
  //  sleep_mode();
7
8
  SREG = sreg;

ergibt keinen Sinn. Hast du den Aufruf von sleep_mode() auskommentiert 
und damit die Logik verändert?

von Andreas P. (Gast)


Lesenswert?

Hallo Karl,
ich habe den Fehler gefunden.... und zwar waren die Jumper auf dem Board 
falsch gesteckt.
Ich dachte ich kann gleichzeitig über den UART empfagnen und per SUB-D 
und HTerm schauen was dort ankommt, geht aber nicht... habe ich Jumper 
umgesetzt und siehe da... ich kann jetzt auch empfangen!!

Danke für die Hilfe!!!!!!!!!

Gruß Andi

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.