1 | #define F_CPU 14745460 // Quarz 14.74546 MHz
|
2 |
|
3 | #include <avr/io.h>
|
4 | #include <avr/interrupt.h>
|
5 | #include <util/delay.h>
|
6 | #include <string.h>
|
7 | #include <stdbool.h>
|
8 |
|
9 | #define UBUFSIZE 64 // Ringpuffergröße
|
10 | #define UART1_RXOFF UCSR1B = (1<<TXEN1); // wird benötigt, da der TH3122 die Daten bounced
|
11 | #define UART1_RXON UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1); // dito
|
12 |
|
13 | unsigned char uart0_buf[UBUFSIZE]; // UART0 Ringpuffer
|
14 | unsigned char iptr0 = 0; // Eingangszeiger
|
15 | unsigned char optr0 = 0; // Ausgangszeiger
|
16 |
|
17 | unsigned char uart1_buf[UBUFSIZE]; // UART1 Ringpuffer
|
18 | unsigned char iptr1 = 0; // Eingangszeiger
|
19 | unsigned char optr1 = 0; // Ausgangszeiger
|
20 |
|
21 | ISR(USART0_RXC_vect) // ISR UART0
|
22 | {
|
23 | uart0_buf[iptr0] = UDR0; // schiebe die empfangenen Daten in den Buffer
|
24 | iptr0++;
|
25 | if (iptr0 == UBUFSIZE) { iptr0 = 0; } // den Bereich nicht verlassen
|
26 | }
|
27 |
|
28 | ISR(USART1_RXC_vect) // ISR UART1
|
29 | {
|
30 | uart1_buf[iptr1] = UDR1; // schiebe die empfangenen Daten in den Buffer
|
31 | iptr1++;
|
32 | if (iptr1 == UBUFSIZE) { iptr1 = 0; } // den Bereich nicht verlassen
|
33 | }
|
34 |
|
35 |
|
36 | void uart0_putchar(char Data)
|
37 | {
|
38 | while (!((UCSR0A) & (1<<UDRE0))) { } // warte auf UART0 Sender
|
39 | UDR0 = Data; // sende die Daten
|
40 | }
|
41 |
|
42 | void uart1_putchar(char Data)
|
43 | {
|
44 | while (!((UCSR1A) & (1<<UDRE1))) { } // warte auf UART1 Sender
|
45 | UDR1 = Data; // sende die Daten
|
46 | }
|
47 |
|
48 | unsigned char uart0_getchar()
|
49 | {
|
50 | unsigned char c = uart0_buf[optr0]; // hole Daten und erhöhe den Zeiger
|
51 | optr0++;
|
52 | if (optr0 == UBUFSIZE) { optr0 = 0; } // den Bereich nicht verlassen
|
53 | return c; // gebe Daten zurück
|
54 | }
|
55 |
|
56 | unsigned char uart1_getchar()
|
57 | {
|
58 | unsigned char c = uart1_buf[optr1]; // hole Daten und erhöhe den Zeiger
|
59 | optr1++;
|
60 | if (optr1 == UBUFSIZE) { optr1 = 0; } // den Bereich nicht verlassen
|
61 | return c; // gebe Daten zurück
|
62 | }
|
63 |
|
64 | bool uart0_haschar() // Gebe 'true' zurück wenn Daten im Puffer sind
|
65 | {
|
66 | return (iptr0 - optr0);
|
67 |
|
68 | }
|
69 |
|
70 | bool uart1_haschar() // Gebe 'true' zurück wenn Daten im Puffer sind
|
71 | {
|
72 |
|
73 | return (iptr1 - optr1);
|
74 |
|
75 | }
|
76 |
|
77 | void uart0_init(int BaudRate)
|
78 | {
|
79 | int ubrr0 = (F_CPU / 16 / BaudRate - 1); // Baudrate UART0 einstellen
|
80 | UBRR0H = (unsigned char)(ubrr0>>8);
|
81 | UBRR0L = (unsigned char)ubrr0;
|
82 |
|
83 | UCSR0C = (1<<URSEL0)|(3<<UCSZ00); // UART0 Frame Format einstellen: 8data, 1 Stop-bit, keine Parity
|
84 | UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1 << RXCIE0); // UART0 Receiver und Transmitter einschalten
|
85 | }
|
86 |
|
87 | void uart1_init(int BaudRate)
|
88 | {
|
89 | int ubrr1 = (F_CPU / 16 / BaudRate - 1); // Baudrate UART1 einstellen
|
90 | UBRR1H = (unsigned char)(ubrr1>>8);
|
91 | UBRR1L = (unsigned char)ubrr1;
|
92 |
|
93 | UCSR1C = (1<<URSEL1)|(3<<UCSZ10)|(1<<UPM11); // UART1 Frame Format einstellen: 8data, 1 Stop-Bit, even Parity
|
94 | UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1); // UART1 Receiver und Transmitter einschalten
|
95 | }
|
96 |
|
97 | bool uart1_ibusclear() // Prüfen ob I-Bus im Leerlauf
|
98 | {
|
99 | long long i;
|
100 | for (i=0;i<25000;i++) // i-Wert abhängig von F_CPU
|
101 | {
|
102 |
|
103 | if ( (PINB & (1<<PINB1)) ) // für ca.1,5ms lang prüfen, ob SEN/STA Pin des TH3122 low ist
|
104 | {
|
105 | return 0;
|
106 | }
|
107 | }
|
108 | return 1; // wenn ja, dann: I-Bus ist im Leerlauf
|
109 | }
|
110 |
|
111 | void uart1_sendibus(char *msg) // sende I-Bus-Nachricht
|
112 | {
|
113 |
|
114 |
|
115 | for (;;) // Schleife bis alles gesendet wurde
|
116 | {
|
117 | if (uart1_ibusclear()) // wenn I-Bus im Leerlauf
|
118 | {
|
119 | UART1_RXOFF // schalte UART1 Empfang aus
|
120 | while (*msg != '\0')
|
121 | {
|
122 | char tmp = *msg++; // hole ein Byte aus dem RAM
|
123 | uart1_putchar(tmp); // und sende es
|
124 | }
|
125 | UART1_RXON // schalte UART Empfang ein
|
126 | return;
|
127 | }
|
128 | }
|
129 | }
|
130 |
|
131 | int main() // Hauptprogramm
|
132 |
|
133 | {
|
134 | // Port-Pins einstellen, abhängig von der Schaltung
|
135 | PORTA =0xFF;
|
136 | DDRA = 0x00;
|
137 |
|
138 | PORTE =0xFF;
|
139 | DDRE = 0x00;
|
140 |
|
141 | PORTC = 0xFF;
|
142 | DDRC = 0x00;
|
143 |
|
144 | PORTB =0b11111111;
|
145 | DDRB = 0b00001001;
|
146 |
|
147 | PORTD =0b11111010;
|
148 | DDRD = 0b00000110; //------------
|
149 |
|
150 | sei(); // Interrupts einschalten
|
151 |
|
152 | uart1_init(9600); // USART's initialisieren (Baudrate auf 9600 )
|
153 | uart0_init(9600);
|
154 |
|
155 | while (1) // Daten von USART0 nach USART1 und zurück
|
156 | {
|
157 | if (uart0_haschar())
|
158 | {
|
159 | char tmp[2];
|
160 | tmp[0] = uart0_getchar();
|
161 | tmp[1] = '\0';
|
162 | uart1_sendibus(tmp);
|
163 | }
|
164 |
|
165 | if (uart1_haschar())
|
166 | {
|
167 | uart0_putchar(uart1_getchar());
|
168 | }
|
169 | }
|
170 |
|
171 | cli();
|
172 | return 0;
|
173 | }
|