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_ */
|