USART mit dem Attiny2313 / 4313 geht nicht

OP #2819233
Lesenswert?

Hallo!

Ich habe folgendes Problem mit dem Attiny2313 / 4313.

Ich habe den tiny über einen MAX232N an die Serielle Schnittstelle 
gepackt. An einem Port (PD6) hängt ne LED, die sich per Taster 
ein-/ausschalten lässt.

Die Ausgabe an den PC per uart_puts() funktioniert ohne Probleme.
1
void uart_puts (char *s)
2
{
3
    while (*s)
4
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
5
        uart_putc(*s);
6
        s++;
7
    }
8
}

Aber sobald ich am PC auch nur ein Zeichen eingebe, leuchtet plötzlich 
die zuvor ausgeschaltete LED auf und es geht gar nichts mehr. Den 
Empfang habe ich nach einem Tutorial per Interrupt gelöst:
1
ISR(USART_RXC_vect)
2
{
3
  uart_puts("test");
4
}

Initialisiert wird USART wie folgt:
1
void uart_init()
2
{
3
  UBRRH = UBRR_VAL >> 8;
4
  UBRRL = UBRR_VAL & 0xFF;
5
  UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);  // UART RX, TX und RX Interrupt einschalten
6
  /* Set frame format: 8data, 2stop bit */
7
  UCSRC = ( 1 << USBS ) | ( 3 << UCSZ0 );
8
}

Wieso leuchtet plötzlich die LED auf / hängt sich der tiny auf? Und 
warum mag er meine Eingaben nicht verarbeiten? :(  Ich hoffe ihr könnt 
mir helfen!


Danke schonmal!
#2819248
Lesenswert?

Michael Niewöhner schrieb:
> Ich habe folgendes Problem mit dem Attiny2313 / 4313.
1
ISR(USART_RXC_vect)

Und wo hast du diesen Namen her?
Merke: Den Vektornamen errät man nicht und man kopiert ihn auch nicht 
einfach von einem anderen Code der für einen anderen µC geschrieben 
wurde. Stattdessen informiert man sich, wie dieser Name für genau deinen 
µC lautet.

PS: Und außerdem ignoriert man die diesbezügliche Compiler-Warnung 
nicht.
OP #2819260
Lesenswert?

Dank für die flotte Antwort!

Naja, erraten hab ich den Namen sicher nicht... und der compiler spricht 
folgendes:
1
uart.h:23:1: warning: type defaults to 'int' in declaration of 'ISR'
2
uart.c:40:1: warning: type of 'UART0RX_vect' defaults to 'int'

Das Datenblatt hat gesprochen... "USART0_RXC" ist wohl richtig... Geht 
aber auch nicht, gleiches Problem :(
Gast #2819264
Lesenswert?

Hallo Michael,

was macht denn die Funktion uart_puts?!
Puffert sie die zu sendenden Zeichen oder blockiert sie? Im zweiten Fall 
wäre es sehr "gefährlich" sie aus einer InterruptServiceRoutine 
aufzurufen...

Gruß
KeyMusic
#2819269
Lesenswert?

Michael Niewöhner schrieb:
> und der compiler spricht
> folgendes:

Dann hast du außerdem auch noch ein
1
#include <avr/interrupt.h>
vergessen.

Michael Niewöhner schrieb:
> Das Datenblatt hat gesprochen... "USART0_RXC" ist wohl richtig...

Irgendwelche Namen in irgendwelchen Assembler-Beispiel-Codes sind 
irrelevant.

http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
OP #2819277
Lesenswert?

Danke für eure Hilfe!  Bitte nicht gleich schlagen :S indeckunggeh


main.c
1
#include <avr/io.h>
2
#include "functions.h"
3
#include <util/delay.h>
4
#include "uart.h"
5
#include <avr/interrupt.h> 
6

7
void init(void)
8
{  
9
  // Eingänge
10
  DDRB &= ~( (1<<DDB0) ); // Taster 1
11
  PORTB |= (1 << PB0); // Pull-Up ein
12
  
13
  //Ausgänge
14
  DDRD  |= (1<<DDD6); // LED
15

16
  //UART initialisieren
17
  uart_init();
18

19
  //LED EIN
20
  PORTD |= (1<<PD6);
21
  
22
  //Interrupts ein
23
  sei();
24
  uart_puts("INIT\n\r");
25
}
26

27
int main()
28
{
29
  init();
30
  uint16_t i;
31
  char s[10];
32
  while(1)
33
  {
34
    // Taster 1
35
    if (debounce(&PINB, PB0))
36
    {
37
      PORTD ^= (1<<PD6);
38
      uart_puts("TEST\n\r");
39
    }
40
  }
41
  
42
  return 0;
43
}

functions.c
1
#include <avr/io.h>
2
#include "functions.h"
3
#include <util/delay.h>
4
  
5
uint8_t debounce(volatile uint8_t *port, uint8_t pin)
6
{
7
    if  (!(*port & (1 << pin)))
8
    {
9
        _delay_ms(30);
10
        if (  (*port & (1 << pin)) )
11
    {
12
      _delay_ms(30);
13
      return 1;
14
    }
15
    }
16
    return 0; 
17
}

functions.h
1
#ifndef F_CPU
2
  #define F_CPU 8000000UL
3
#endif
4

5
uint8_t debounce(volatile uint8_t *port, uint8_t pin);

uart.c
1
#include <avr/io.h>
2
#include "uart.h"
3
#include <avr/interrupt.h>
4
 
5
volatile uint8_t uart_str_complete = 0;
6
volatile uint8_t uart_str_count = 0;
7
volatile char uart_string[UART_MAXSTRLEN + 1] = "";
8

9
void uart_init()
10
{
11
  UBRRH = UBRR_VAL >> 8;
12
  UBRRL = UBRR_VAL & 0xFF;
13
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);  // UART RX, TX und RX Interrupt einschalten
14
  UCSRC = ( 1 << USBS ) | ( 3 << UCSZ0 );
15
  //UCSRC = (1<<UCSZ1)|(1<<UCSZ0);
16
  
17
}
18

19
int uart_putc(unsigned char c)
20
{
21
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
22
    {
23
    }                             
24
 
25
    UDR = c;                      /* sende Zeichen */
26
    return 0;
27
}
28
 
29
void uart_puts (char *s)
30
{
31
    while (*s)
32
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
33
        uart_putc(*s);
34
        s++;
35
    }
36
}
37

38

39
ISR(USART_RX_vect)
40
{
41
  PORTD ^= (1<<PD6);
42
}

uart.h
1
#ifndef F_CPU
2
  #define F_CPU 8000000UL
3
#endif
4

5
#define BAUD 9600UL      // Baudrate
6
 
7
// Berechnungen
8
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
9
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
10
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
11
 
12
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
13
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
14
#endif
15

16
#define UART_MAXSTRLEN 10
17

18
int uart_putc(unsigned char c);
19
void uart_puts (char *s);
20
void uart_init();
21
unsigned char USART_Receive( void );
22

23
extern volatile uint8_t uart_str_complete;
24
extern volatile uint8_t uart_str_count;
25
extern volatile char uart_string[UART_MAXSTRLEN + 1];
OP #2819279
Lesenswert?

Compiler:
1
avr-gcc (GCC) 4.5.1
2
Copyright (C) 2010 Free Software Foundation, Inc.
3
This is free software; see the source for copying conditions.  There is NO
4
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5

6

7
Compiling: main.c
8
avr-gcc -c -mmcu=attiny4313 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.lst  -std=gnu99 -DF_OSC= -funsigned-char -funsigned-bitfields -MD -MP -MF .dep/main.o.d main.c -o main.o 
9
In file included from main.c:4:0:
10
uart.h:20:1: warning: function declaration isn't a prototype
11
main.c:27:5: warning: function declaration isn't a prototype
12
main.c: In function 'main':
13
main.c:50:4: warning: "/*" within comment
14
main.c:31:7: warning: unused variable 's'
15
main.c:30:11: warning: unused variable 'i'
16

17
Compiling: functions.c
18
avr-gcc -c -mmcu=attiny4313 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=functions.lst  -std=gnu99 -DF_OSC= -funsigned-char -funsigned-bitfields -MD -MP -MF .dep/functions.o.d functions.c -o functions.o 
19

20
Compiling: uart.c
21
avr-gcc -c -mmcu=attiny4313 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=uart.lst  -std=gnu99 -DF_OSC= -funsigned-char -funsigned-bitfields -MD -MP -MF .dep/uart.o.d uart.c -o uart.o 
22
In file included from uart.c:2:0:
23
uart.h:20:1: warning: function declaration isn't a prototype
24
uart.c:9:6: warning: function declaration isn't a prototype
25

26
Linking: main.elf
27
avr-gcc -mmcu=attiny4313 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.o  -std=gnu99 -DF_OSC= -funsigned-char -funsigned-bitfields -MD -MP -MF .dep/main.elf.d main.o functions.o uart.o   --output main.elf -Wl,-Map=main.map,--cref    -lm
28

29
Creating load file for Flash: main.hex
30
avr-objcopy -O ihex -R .eeprom main.elf main.hex
31

32
Creating load file for EEPROM: main.eep
33
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
34
  --change-section-lma .eeprom=0 -O ihex main.elf main.eep
35
avr-objcopy: --change-section-lma .eeprom=0x00000000 never used
36

37
Creating Extended Listing: main.lss
38
avr-objdump -h -S main.elf > main.lss
39

40
Creating Symbol Table: main.sym
41
avr-nm -n main.elf > main.sym
42

43
Size after:
44
AVR Memory Usage
45
----------------
46
Device: attiny4313
47

48
Program:     346 bytes (8.4% Full)
49
(.text + .data + .bootloader)
50

51
Data:         28 bytes (10.9% Full)
52
(.data + .bss + .noinit)
53

54

55

56
Errors: none
57
-------- end --------
#2819286
Lesenswert?

1
  PORTD ^= (1<<PD6);
Ändere das wieder in das ursprüngliche, und du wirst merken, dass der 
Interrupt vermutlich sehr wohl geht (nur nicht ganz so, wie von dir 
erwartet).

Als nächstes liest du dir dann im Datenblatt die Beschreibung des 
RXC-Flags nochmal durch, und überlegst, was wohl die Ursache dieses "nur 
nicht ganz so, wie von dir erwartet" ist.

Edit:
@MWS
Spielverderber ;-)

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