Sieh dir deine Funktion getche() an. Du hast eine Funktion getch() und
du hast eine Funktion putch(). Es ist ein leichtes, aus diesen beiden
Funktionen die Funktion getche() zusammenzusetzen. Was du aber nicht tun
solltest: In der Funktion getche() die Funktionalität wieder
auszuprogrammieren. Trachte danach Funktionen wiederzuverwenden! Du
möchtest die hardwareabhängigen Dinge nach Möglichkeit nicht über viele
Funktionen verstreut haben, sondern wenn irgendwie geht, in nur 1
Funktion beisammen haben.
So könnte zb eine sinnvolle Aufteilung in Funktionalitäten aussehen:
File: test_uart.c
*****************
1 | #include <avr/io.h>
|
2 | #include "uart.h"
|
3 |
|
4 | //#define TAKT 3686400UL
|
5 | //#define BAUD 9600UL
|
6 |
|
7 | int main(void)
|
8 | {
|
9 | initusart();
|
10 | putch('>');
|
11 |
|
12 | while(1) {
|
13 | getch();
|
14 | }
|
15 | }
|
File: uart.c
************
1 | #include <avr/io.h>
|
2 | #include "uart.h"
|
3 |
|
4 | void initusart( void )
|
5 | {
|
6 | unsigned char x;
|
7 |
|
8 | //UBRRL = (TAKT /16UL*BAUD)-1;
|
9 | UBRRL = 23;
|
10 | UCSRB |= (1<< TXEN) | (1<<RXEN);
|
11 | UCSRC |= (1<< URSEL) | (1<<UCSZ1);
|
12 | x = UDR;
|
13 | }
|
14 |
|
15 | void putch( unsigned char x )
|
16 | {
|
17 | loop_until_bit_is_set( UCSRA, UDRE );
|
18 | UDR = x;
|
19 | }
|
20 |
|
21 | unsigned char getch( void )
|
22 | {
|
23 | loop_until_bit_is_set( UCSRA, RXC );
|
24 | return UDR;
|
25 | }
|
26 |
|
27 | unsigned char getche( void )
|
28 | {
|
29 | unsigned char x = getch();
|
30 | putch( x );
|
31 | return x;
|
32 | }
|
33 |
|
34 | unsigned char kbhit( void )
|
35 | {
|
36 | if( bit_is_set( UCSRA, RXC ) )
|
37 | return UDR;
|
38 | else
|
39 | return 0;
|
40 | }
|
File: uart.h
************
1 | void initusart( void );
|
2 | void putch( unsigned char x );
|
3 | unsigned char getch( void );
|
4 | unsigned char getche( void );
|
5 | unsigned char kbhit( void );
|
In uart.c sind alle Funktionen beisammen, die man benötigt wenn man mit
der UART arbeiten will. Ein Programm, welches das tun will, includiert
das File "uart.h". Dadurch bekommt es die Funktionsprotoypen aller
verfügbaren Funktionen und kann sie benutzen. Der Inhalt von uart.c
interessiert das Testprogramm nicht weiter. Alles was es wissen muss,
findet es in uart.h
Ins Projekt (AVR-Studio) bzw. Makefile, werden das Testprogramm bzw
uart.c als Source File eingetragen. uart.h kommt im Makefile in die
Anhängigkeiten bzw. im AVR STudio unter die Header Files.
Und dann hast du dein Projekt sauber aufgesetzt und es gibt auch keine
multiple Definitions mehr.
Alle C Files werden einzeln compiliert und zum EXE zusammengelinkt
An der Konstanten 23 in initusart solltest du noch arbeiten, die gehört
da in dieser Form nicht hin
Und arbeite an deiner Formatierung. Da hat Rufus völlig recht.