Hallo, habe eine Hardware - UART Schnittstelle und möchte nun die Empfangen Daten dieser Schnittstelle über die Software - UART Schnittstelle weiterleiten (sprich senden). Ich kann Daten empfangen und senden, aber alles nur getrennt. Wie muss ich vorgehen, damit ich die empfangenen Daten weiter senden kann?
Sabine F. schrieb: > Ich kann Daten empfangen und senden, aber alles nur getrennt. Was meinst du mit "getrennt"? > Wie muss > ich vorgehen, damit ich die empfangenen Daten weiter senden kann? Ich würde am ehesten: - eine Timer gesteuerte Senderoutine verwenden für die SW UART, die einfach Daten aus einem Sendepuffer rausschiebt - den "UART RX Complete Interrupt" (sofern vorhanden) nutzen, um Daten in den Sendepuffer zu übergeben Oder wenn's einfach werden soll: - eine andere MCU derselben Familie nehmen, die 2 Hardware UARTs besitzt :D
Tom M. schrieb: > Was meinst du mit "getrennt"? Ich kann sowohl Zeichen empfangen, welche ich über den Terminal an den Mikrocontroller sende, als wie auch Zeichen an den Terminal senden. Daten werden im Terminal eingegeben und werden an den µC gesendet, dieser sollte sie danach weiterschicken an einen anderen Terminal. Das Emfangen geschieht ohne Interrupts über die Hardware - UART, das Senden über die Software - UART mit Interrupt. Funktioniert die Kombination von mit und ohne Interrupt?
Hi Sabiner, das sollte eigentlich ohne Probleme gehen. Der Teufel wird wie immer im Detail stecken. Etwa unterschiedliche Baudraten ohne Puffer etc. Beschreibe mal ausführlich was Du geschrieben hast und poste den Quellcode.
Sabine F. schrieb: > Das Emfangen geschieht ohne Interrupts über die Hardware - UART, > das Senden über die Software - UART mit Interrupt. Klingt gut, sollte funzen. Wo hakt's noch?
1 | #include <avr/io.h> |
2 | #include "main.h" |
3 | #include "suart.h" |
4 | #include <avr/power.h> |
5 | |
6 | int i; |
7 | char satz[2000]; |
8 | |
9 | int main( void ) { |
10 | uart_init(); |
11 | uartRx(); |
12 | clock_prescale_set(clock_div_1); |
13 | suart_init(); |
14 | DDRB = 0x02; |
15 | PORTB = 0x02; |
16 | |
17 | sei(); |
18 | for(i=0; satz[i] != 0; i++) { |
19 | sputs(satz[i]); |
20 | }
|
21 | for (;;) { // main loop |
22 | sputchar( '-' ); |
23 | while (! kbhit()); // wait until byte received |
24 | sputchar (sgetchar () + 1); // sent byte + 1 |
25 | }
|
26 | }
|
27 | |
28 | void uart_init(void) { |
29 | UBRR0H = 0x00; |
30 | UBRR0L = 0x17; |
31 | |
32 | |
33 | UCSR0B = (1<<TXEN0) | (1<<RXEN0); // UART TX und RX einschalten |
34 | UCSR0C = (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00); // Asynchron 8N2 |
35 | }
|
36 | |
37 | void uartRx() { |
38 | satz[0] = 1; |
39 | for(i=0; satz[i] != 0; i++) { |
40 | while(!(UCSR0A & (1<<RXC0))) { |
41 | }
|
42 | satz[i] = UDR0; |
43 | }
|
44 | }
|
Hier wird die Software UART initalisiert.
1 | #include "main.h" |
2 | #include "suart.h" |
3 | |
4 | |
5 | |
6 | #define BIT_TIME (u8)((XTAL / BAUD) / PRESCALE)
|
7 | |
8 | |
9 | volatile u8 stx_count; |
10 | u8 stx_data; |
11 | |
12 | volatile u8 srx_done; |
13 | u8 srx_data; |
14 | u8 srx_mask; |
15 | u8 srx_tmp; |
16 | |
17 | |
18 | void suart_init( void ) |
19 | {
|
20 | SBIT(PORTD,STX) = 1; |
21 | // OCR0A = TCNT0 + 1; // force first compare
|
22 | // TCCR0A = 0; // Default: Normal port operation
|
23 | TCCR0B = 1 << CS01 | 1<<CS00; // clk/64 |
24 | // TIFR0 = 1<<ICF1; // clear pending interrupt
|
25 | TIMSK0 = 1 << OCIE0A; // enable output compare interrupt |
26 | |
27 | EICRA = 1 << ISC01; // falling edge |
28 | EIMSK = 1 << INT0; // enable edge interrupt |
29 | |
30 | stx_count = 0; // nothing to sent |
31 | srx_done = 0; // nothing received |
32 | STXDDR |= 1 << STX; // TX output |
33 | }
|
34 | |
35 | |
36 | u8 sgetchar (void) // get byte |
37 | {
|
38 | while (!srx_done); // wait until byte received |
39 | srx_done = 0; |
40 | return srx_data; |
41 | }
|
42 | |
43 | |
44 | ISR (INT0_vect) // rx start |
45 | {
|
46 | OCR0B = TCNT0 + (u8)((BIT_TIME * 3) / 2);// scan 1.5 bits after start |
47 | |
48 | srx_tmp = 0; // clear bit storage |
49 | srx_mask = 1; // bit mask |
50 | if( !(SRXPIN & 1<<SRX)) { // still low |
51 | EIMSK &= ~(1 << INT0); // disable edge interrupt |
52 | TIMSK0 = 1<<OCIE0A^1<<OCIE0B; // wait for first bit |
53 | }
|
54 | TIFR0 = 1<<OCF0B; // clear pending interrupt ? why does that output compare int occur? |
55 | EIFR |= (1 << INTF0); // clear any pending edge interrupt |
56 | }
|
57 | |
58 | |
59 | ISR (TIMER0_COMPB_vect) |
60 | {
|
61 | u8 in = SRXPIN; // scan rx line |
62 | // PORTB = 0x00;
|
63 | if (srx_mask) { |
64 | if (in & 1 << SRX) |
65 | srx_tmp |= srx_mask; |
66 | srx_mask <<= 1; |
67 | OCR0B += BIT_TIME; // next bit slice |
68 | } else { |
69 | srx_done = 1; // mark rx data valid |
70 | srx_data = srx_tmp; // store rx data |
71 | // TIFR0 = 1<<ICF1; // clear pending interrupt
|
72 | TIMSK0 = 1<<OCIE0A; // enable tx and wait for start |
73 | EIFR |= (1 << INTF0); // clear any pending edge interrupt: This hinders the in0-vect from beeing triggerd again just now which may occur by falling edges in the serial data bits |
74 | EIMSK = 1 << INT0; // reenable edge interrupt |
75 | }
|
76 | // PORTB = 0x02;
|
77 | }
|
78 | |
79 | |
80 | void sputchar (u8 val) // send byte |
81 | {
|
82 | while (stx_count); // until last byte finished |
83 | stx_data = ~val; // invert data for Stop bit generation |
84 | stx_count = 10; // 10 bits: Start + data + Stop |
85 | }
|
86 | |
87 | |
88 | void sputs (u8 *txt) // send string |
89 | {
|
90 | while (*txt) |
91 | sputchar (*txt++); |
92 | }
|
93 | |
94 | |
95 | ISR (TIMER0_COMPA_vect) // tx bit |
96 | {
|
97 | u8 dout; |
98 | u8 count; |
99 | |
100 | OCR0A += BIT_TIME; // next bit slice |
101 | count = stx_count; |
102 | |
103 | if (count) { |
104 | stx_count = --count; // count down |
105 | // ??? dout = 1<<COM0A1; // set low on next compare
|
106 | dout = 0; |
107 | if (count != 9) { // no start bit |
108 | if (!(stx_data & 1)) // test inverted data |
109 | //??? dout = 1<<COM0A1^1<<COM0A0; // set high on next compare
|
110 | dout = 1; |
111 | stx_data >>= 1; // shift zero in from left |
112 | }
|
113 | // TCCR0A = dout;
|
114 | // STX = (dout == 0) ? 1 : 0;
|
115 | SBIT(PORTD,STX) = dout; |
116 | }
|
117 | }
|
Am einfachsten ist es, wenn du das ganze Gedöns mit dem 'satz' wieder vergisst. Kommt ein Zeichen an der Hardware UART an, schickst du es gleich wieder auf der Software UART weiter. Dazu brauchst du dann eine Funktion, die auf 1 Zeichen an der Hardware UART wartet
1 | uint8_t uartRx() |
2 | {
|
3 | while(!(UCSR0A & (1<<RXC0))) |
4 | {
|
5 | }
|
6 | |
7 | return UDR0; |
8 | }
|
eine Funktion, die ein einzelnes Zeichen auf der Software UART rausschickt hast du ja schon. Und in der Hauptschleife in main() ist der verbindende 'Kitt'
1 | int main() |
2 | {
|
3 | ....
|
4 | |
5 | |
6 | for(;;) { // main loop |
7 | Zeichen = uartRxChar(); |
8 | sputchar( Zeichen ); |
9 | }
|
10 | }
|
dann überlegst du noch, was von dem Zeugs, das jetzt überflüssig ist, du nicht brauchst, schmeisst es raus und bist fertig.
Tom M. schrieb: > Klingt gut, sollte funzen. Wo hakt's noch? Bei der Übertragung wird nur ein -o- übertragen, anstatt des textes.
Sabine F. schrieb: > Bei der Übertragung wird nur ein -o- übertragen, anstatt des textes. Jo, was anderes tust du ja nicht in deiner main(): Sabine F. schrieb: > for(i=0; satz[i] != 0; i++) { > sputs(satz[i]); > } > for (;;) { // main loop > sputchar( '-' ); > while (! kbhit()); // wait until byte received > sputchar (sgetchar () + 1); // sent byte + 1 > }
Danke für eure bisherigen Antworten!! Kann noch immer keine Zeichenkette versenden :(, hat jemand eine Idee?
1 | #include "main.h" |
2 | #include "suart.h" |
3 | #include <avr/power.h> |
4 | |
5 | char satz[2000]; |
6 | int i = 0; |
7 | |
8 | int main( void ) { |
9 | clock_prescale_set(clock_div_1); |
10 | suart_init(); |
11 | |
12 | sei(); |
13 | while(1) { |
14 | uartRxChar(); |
15 | sputs(satz[i]); |
16 | }
|
17 | for (;;) { // main loop |
18 | sputchar( '-' ); |
19 | while (! kbhit()); // wait until byte received |
20 | sputchar (sgetchar () + 1); // sent byte + 1 |
21 | }
|
22 | }
|
23 | |
24 | void uartRxChar() { |
25 | satz[0] = 1; |
26 | for(i=0; satz[i] != 0; i++) { |
27 | while(!(UCSR0A & (1<<RXC0))) { |
28 | }
|
29 | return satz[i] = UDR0; |
30 | }
|
31 | }
|
Max1989 schrieb: > Danke für eure bisherigen Antworten!! > > Kann noch immer keine Zeichenkette versenden :(, hat jemand eine Idee? Die Programmiersprache lernen. Mit zusammenkopiertem unverstandenem Code hat noch keiner bei 0 beginnend programmieren gelernt.
Warum funktioniert es nicht, wenn ich das empfangene Zeichen in ein Char - Array an Stelle i speichere und dann die Stelle i wieder ausgib?
Sabine, Das wird so nichts. Programmiere Dir erst mal eine UART library (oder nimm die eine vom Netz), bei der die empfangenen bzw. die zu sendenden Daten mittels Interrupt in eine Queue gespeichert werden. Dann können die Daten aus der RxQueue bequem abgeholt, bearbeitet, und in die TxQueue geschoben werden. Die Vermischung von UART Funktionalität und Bearbeitung in der Main loop führt ins Chaos.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.