1 | /*
|
2 | * Ampel_Code.c
|
3 | *
|
4 | * Created: 18.05.2016 11:23:34
|
5 | * Author : Marvin
|
6 | */
|
7 |
|
8 | /* Dies ist der Code zur Ampelsteuerung des FC Pfeil Broistedt.
|
9 | Geschrieben von Marvin Wenzel im Frühjahr 2016.
|
10 |
|
11 | Dieser Codeteil ist für die AMPELN-Fernbedinung, d.h. den Sender.
|
12 |
|
13 | Verwendet wird ein Atmega328PU sowie ein NRF24L01+ Funkmodul.
|
14 | Betrieben wird beides mit 3,3V. Getaktet wird mit den internen 8 MHz.
|
15 |
|
16 | Im folgenden sind die Pinbelegungen aufgeführt:
|
17 |
|
18 | PB0: CE
|
19 | PB1: CSN
|
20 | PB2: SSnot
|
21 | PB3: MOSI
|
22 | PB4: MISO
|
23 | PB5: SCK
|
24 | PB6:
|
25 | PB7:
|
26 |
|
27 | PC0:
|
28 | PC1:
|
29 | PC2:
|
30 | PC3:
|
31 | PC4:
|
32 | PC5:
|
33 | RESETnot: 3,3V
|
34 |
|
35 | PD0:
|
36 | PD1:
|
37 | PD2:
|
38 | PD3:
|
39 | PD4:
|
40 | PD5:
|
41 | PD6:
|
42 | PD7: IRQ (PCint23)
|
43 | */
|
44 |
|
45 | #ifndef F_CPU //Define F_CPU if not done
|
46 | #define F_CPU 16000000UL
|
47 | #endif
|
48 |
|
49 | #define BAUD 9600UL // Baudrate
|
50 |
|
51 | // Berechnungen
|
52 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
|
53 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
|
54 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
|
55 |
|
56 | #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
|
57 | #error Systematischer Fehler der Baudrate groesser 1% und damit zu hoch!
|
58 | #endif
|
59 |
|
60 | #include <avr/io.h>
|
61 | #include <avr/interrupt.h>
|
62 | #define F_CPU 16000000UL
|
63 | #include <util/delay.h>
|
64 | #include <stdlib.h>
|
65 | #include "wl_module.h"
|
66 | #include "nRF24L01.h"
|
67 | #include "SPI.h"
|
68 |
|
69 |
|
70 |
|
71 | void atmega_init();
|
72 | void uart_init(void);
|
73 | int uart_putuint8_1(uint8_t c);
|
74 | void uart_putuint8_s(uint8_t *s);
|
75 | int uart_putc(char c);
|
76 | void uart_puts (char *s);
|
77 |
|
78 | uint8_t sendedaten[wl_module_PAYLOAD] = "Dies sind 32 Zeichen. Gesendet!!";
|
79 | uint8_t counter = 0;
|
80 | uint8_t status_funk = 71;
|
81 | volatile uint8_t PTX;
|
82 | char stringbuffer [20];
|
83 | uint8_t status;
|
84 | uint8_t addr[5];
|
85 |
|
86 | int main(void)
|
87 | {
|
88 | uint8_t i;
|
89 | uart_init();
|
90 | uart_puts("Beginne Initialisierungen...\r\n");
|
91 |
|
92 |
|
93 | atmega_init(); // Atmega initialisieren
|
94 | wl_module_init(); // Funkmodul initialisieren
|
95 | _delay_ms(50); // kurz warten
|
96 | sei();
|
97 | wl_module_tx_config(wl_module_TX_NR_0);
|
98 |
|
99 | wl_module_config_register(EN_AA,EN_AA_ENAA_ALL); //Auto Acknowledgment bei allen
|
100 |
|
101 | //wl_module_config_register(EN_RXADDR,EN_RXADDR_ERX_ALL); // RX pipe alle aktivieren
|
102 | wl_module_config_register(STATUS, (1<<MAX_RT));
|
103 | // Status lesen
|
104 | uart_puts("Status: ");
|
105 | status_funk = wl_module_get_status();
|
106 | itoa(status_funk,stringbuffer,2);
|
107 | uart_puts(stringbuffer);//(status_funk + '0');
|
108 | uart_puts(" \r\n");
|
109 | _delay_ms(1000);
|
110 |
|
111 | uart_puts("RX_payload: ");
|
112 | status_funk = wl_module_get_rx_pw(0);
|
113 | itoa(status_funk,stringbuffer,10);
|
114 | uart_puts(stringbuffer);//(status_funk + '0');
|
115 | uart_puts(" \r\n");
|
116 |
|
117 | uart_puts("rf_setup: ");
|
118 | status_funk = wl_module_get_rf_setup();
|
119 | itoa(status_funk,stringbuffer,2);
|
120 | uart_puts(stringbuffer);//(status_funk + '0');
|
121 | uart_puts(" \r\n");
|
122 |
|
123 | uart_puts("rf_ch: ");
|
124 | status_funk = wl_module_get_rf_ch();
|
125 | itoa(status_funk,stringbuffer,10);
|
126 | uart_puts(stringbuffer);
|
127 | uart_puts(" \r\n");
|
128 |
|
129 | uart_puts("tx_addr: ");
|
130 | wl_module_get_tx_addr(addr,0,5);
|
131 | for (i=5; i>0; i--)
|
132 | {
|
133 | status_funk = addr[i-1];
|
134 | itoa(status_funk,stringbuffer,16);
|
135 | uart_puts(stringbuffer);
|
136 | uart_puts(", ");
|
137 | }
|
138 | uart_puts(" \r\n");
|
139 |
|
140 | _delay_ms(1500);
|
141 |
|
142 | // ACHTUNG: Payload steht momentan auf 32
|
143 | while (1)
|
144 | {
|
145 | uart_puts("Sende: ...\r\n");
|
146 | sendedaten[wl_module_PAYLOAD-1] = counter+'0'; // Text ändern
|
147 | wl_module_send(sendedaten,wl_module_PAYLOAD); // senden
|
148 |
|
149 | while (PTX)
|
150 | {
|
151 | uart_puts("Package lost: ");
|
152 | status_funk = wl_module_get_plos_cnt();
|
153 | itoa(status_funk,stringbuffer,10);
|
154 | uart_puts(stringbuffer);
|
155 | uart_puts(" \r\n");
|
156 |
|
157 | //wl_module_config_register(STATUS, (1<<MAX_RT));
|
158 |
|
159 | uart_puts("Status: ");
|
160 | status_funk = wl_module_get_status();
|
161 | itoa(status_funk,stringbuffer,2);
|
162 | uart_puts(stringbuffer);//(status_funk + '0');
|
163 | uart_puts(" \r\n");
|
164 |
|
165 | uart_puts("Retransmitted Count: ");
|
166 | status_funk = wl_module_get_arc_cnt();
|
167 | itoa(status_funk,stringbuffer,10);
|
168 | uart_puts(stringbuffer);
|
169 | uart_puts(" \r\n");
|
170 | _delay_ms(1500);
|
171 | }
|
172 |
|
173 | //uart_putuint8_s(sendedaten);
|
174 |
|
175 | counter++;
|
176 | if (counter >=5)
|
177 | {
|
178 | counter = 0;
|
179 | }
|
180 | _delay_ms(1000);
|
181 | }
|
182 | }
|
183 |
|
184 |
|
185 | void atmega_init()
|
186 | {
|
187 | // Auf 8 MHz intern umstellen
|
188 | //CLKPR = 0x80; // Aenderungen erlauben
|
189 | //CLKPR = 0x00; // internen CLK nicht teilen = 8 MHz
|
190 |
|
191 | // Interrupt Funkmodul
|
192 | DDRD &= ~(1<<PIND7); // als Eingang definieren
|
193 | PCMSK2 = (1<<PCINT23); // PCint23 aktivieren (ACHTUNG: darf später nur auf fallende Flanke reagieren)
|
194 | PCICR = (1<<PCIE2);
|
195 | }
|
196 |
|
197 | ISR(PCINT2_vect)
|
198 | {
|
199 | uart_puts("ISR:...\r\n");
|
200 |
|
201 | if (!(PIND & (1<<PIND7))) // wenn interrupt aufgrund fallender Flanke
|
202 | {
|
203 | uint8_t status;
|
204 |
|
205 | uart_puts("ISR_IF...\r\n");
|
206 |
|
207 | // Read wl_module status
|
208 | wl_module_CSN_lo; // Pull down chip select
|
209 | status = spi_fast_shift(NOP); // Read status register
|
210 | wl_module_CSN_hi; // Pull up chip select
|
211 |
|
212 |
|
213 | if (status & (1<<TX_DS)) // IRQ: Package has been sent
|
214 | {
|
215 | uart_puts("ISR_package_send...\r\n");
|
216 | wl_module_config_register(STATUS, (1<<TX_DS)); //Clear Interrupt Bit
|
217 | PTX=0;
|
218 | }
|
219 |
|
220 | if (status & (1<<MAX_RT)) // IRQ: Package has not been sent, send again
|
221 | {
|
222 | uart_puts("ISR_package_not_send_send_again...\r\n");
|
223 | wl_module_config_register(STATUS, (1<<MAX_RT)); // Clear Interrupt Bit
|
224 | wl_module_CE_hi; // Start transmission
|
225 | _delay_us(10);
|
226 | wl_module_CE_lo;
|
227 | }
|
228 |
|
229 | if (status & (1<<TX_FULL)) //TX_FIFO Full <-- this is not an IRQ
|
230 | {
|
231 | uart_puts("ISR_FIFO_full...\r\n");
|
232 | wl_module_CSN_lo; // Pull down chip select
|
233 | spi_fast_shift(FLUSH_TX); // Flush TX-FIFO
|
234 | wl_module_CSN_hi; // Pull up chip select
|
235 | }
|
236 | }
|
237 | }
|
238 |
|
239 |
|
240 | void uart_init(void)
|
241 | {
|
242 | UBRR0H = UBRR_VAL >> 8;
|
243 | UBRR0L = UBRR_VAL & 0xFF;
|
244 |
|
245 | UCSR0B |= (1<<TXEN0); // UART TX einschalten
|
246 | UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); // Asynchron 8N1
|
247 | }
|
248 |
|
249 | int uart_putuint8_1(uint8_t c)
|
250 | {
|
251 | while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
|
252 | {
|
253 | }
|
254 |
|
255 | UDR0 = c; /* sende Zeichen */
|
256 | return 0;
|
257 | }
|
258 |
|
259 | void uart_putuint8_s(uint8_t *s)
|
260 | {
|
261 | while (*s)
|
262 | { /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
|
263 | uart_putuint8_1(*s);
|
264 | s++;
|
265 | }
|
266 | }
|
267 |
|
268 | int uart_putc(char c)
|
269 | {
|
270 | while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
|
271 | {
|
272 | }
|
273 |
|
274 | UDR0 = c; /* sende Zeichen */
|
275 | return 0;
|
276 | }
|
277 |
|
278 | void uart_puts(char *s)
|
279 | {
|
280 | while (*s)
|
281 | { /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
|
282 | uart_putc(*s);
|
283 | s++;
|
284 | }
|
285 | }
|