Forum: Mikrocontroller und Digitale Elektronik Attiny 4313 UART Probleme


von Jonas E. (jonas_e43)


Lesenswert?

Hallo,
ich bin gerade dabei meinen RFID Reader so umzubauen, dass er mit 
einem PC über UART kommunizieren kann.
Ich benutze den ISR(USART_RX_vect) Interrupt und möchte dann den String 
auslesen. Leider zeigt der Microcontroller dann nur Unsinn an oder hängt 
sich neuerdings auf...
Vielleicht hat ja von euch jemand eine Idee wo der Fehler liegt.
Würde mich über etwas Hilfe sehr freuen :)
Gruß Jonas

Hier der Code:
main.c
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#include <stdio.h>
5
6
#include "em4100.h"
7
#include "lcd.h"
8
#include "rs232.h"
9
10
#ifndef F_CPU
11
#define F_CPU 14745600UL
12
#endif
13
14
void long_delay(uint16_t ms)
15
{
16
  ms = ms*(F_CPU / 1000000);
17
  for(; ms>0; ms--)
18
  _delay_ms(1);
19
}
20
21
char* tagToString(uint8_t* tag)
22
{
23
  const uint8_t SIZE = sizeof(char) * 5 * 2 + ( sizeof(char) );
24
  char* retVal = malloc(SIZE);
25
  uint8_t index = 0;
26
  
27
  for (uint8_t j=0; j<5; j++)
28
  {
29
    uint8_t nibble = (tag[j] >> 4) & 0x0f;
30
    if (nibble > 9)
31
    nibble += 'A'-10;
32
    else
33
    nibble += '0';
34
    retVal[index++] = nibble;
35
    
36
    nibble = tag[j] & 0x0f;
37
    if (nibble > 9)
38
    nibble += 'A'-10;
39
    else
40
    nibble += '0';
41
    retVal[index++] = nibble;
42
  }
43
  
44
  return retVal;
45
}
46
int main(void)
47
{
48
  
49
  lcd_init();
50
  UART_init();
51
52
  lcd_clear();
53
  DDRB |= ( 1 << DDB6) | ( 1 << DDB7 );
54
55
  TCCR0B = 1<<CS01 | 1<<CS00; //Timer/Counter0 prescaler 64
56
  MCUCR |= 1<<ISC10; //Any logical change on INT1 generates an interrupt request
57
  GIMSK |= 1<<INT1; //External interrupt request 1 enable (demod_out from RFID chip)
58
59
  sei();
60
  
61
  lcd_clear();
62
  
63
  uint8_t tag[5];
64
  while ( 1 )
65
  {
66
    lcd_clear();
67
    lcd_string("Ready.");
68
    
69
    if ( em4095_read_tag(tag))
70
      {
71
      char* tagString = tagToString(tag);
72
      lcd_clear();
73
      lcd_stringCenter("Tag ID:", 1);
74
      lcd_stringCenter(tagString, 2);
75
      UART_puts(tagString);
76
      
77
      free(tag);
78
      free(tagString);
79
      long_delay(3000);
80
    }
81
    
82
  }    
83
84
}

rs232.c
1
#include "rs232.h"
2
3
void UART_init(void)
4
{
5
  UBRRH = UBRR_VAL >> 8;
6
  UBRRL = UBRR_VAL & 0xFF;
7
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); 
8
  UCSRC = (1<<UCSZ1)|(1<<UCSZ0);
9
}
10
11
uint8_t UART_peekchar(void)          // Auf Zeichen im UART Eingang prüfen
12
{
13
  return UCSRA & (1<<RXC);            // sofort zurückkehren und Zustand melden
14
}
15
  
16
uint8_t UART_getc(void)
17
{
18
  while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
19
  ;
20
  return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
21
}
22
23
char* UART_gets()
24
{
25
  int length = 1;
26
  char* line = malloc(sizeof(char) * length);
27
#if 0 == '\0'
28
  line[0] = -1;
29
#else
30
  line[0] = 0;
31
#endif
32
  
33
  while ( 1 )
34
  {
35
    line[length - 1] = UART_getc();
36
    if ( line[length - 1] == '\0' || line[length - 1] == '\n' )
37
      break;
38
    else
39
    {
40
      length++;
41
      
42
      char* newLine = realloc(line, sizeof(char) * length);
43
      if ( newLine != NULL )
44
        line = newLine;
45
      else
46
        break;
47
      
48
      line[length - 1] = 0;
49
    }
50
  }
51
  
52
  return line;
53
}  
54
55
void UART_putchar(char z)          // Zeichen in UART Ausgang geben
56
{
57
  while ( !(UCSRA & (1<<UDRE)) )        // Warte bis UART Ausgang frei
58
      ;
59
  UDR = z;
60
}
61
  
62
void UART_puts(char *s)            // Zeichenkette (String) in UART Ausgang geben
63
{
64
  while ( *s )
65
  {
66
    UART_putchar(*s);
67
    s++;
68
  }
69
  UART_putchar('\0');
70
}
71
  
72
  ISR(USART_RX_vect)
73
  {
74
    char* receivedString = UART_gets();
75
    lcd_clearLine(1);
76
    lcd_stringCenter(receivedString, 1);
77
    long_delay(2000);
78
  }

rs232.h
1
#ifndef RS232_H_
2
#define RS232_H_
3
4
5
#include <stdlib.h>
6
#include <avr/interrupt.h>
7
8
#include "lcd.h"
9
10
#ifndef F_CPU
11
#define F_CPU 14745600UL
12
#endif
13
14
#define BAUD 9600UL
15
16
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
17
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
18
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
19
20
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
21
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
22
#endif
23
24
25
void UART_init(void);
26
 
27
// Auf Zeichen im UART Eingang prüfen
28
uint8_t UART_peekchar(void);
29
 
30
// Auf Zeichen im UART Eingang warten
31
uint8_t UART_getc(void);
32
 
33
// Zeichen in UART Ausgang geben
34
void UART_putchar(char z);
35
 
36
// Zeichenkette (String) in UART Ausgang geben
37
void UART_puts(char *s);
38
39
char* UART_gets( void );
40
41
#endif /* RS232_H_ */

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.