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: IRQ (PCint6)
|
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:
|
43 | */
|
44 |
|
45 | #ifndef F_CPU //Define F_CPU if not done
|
46 | #define F_CPU 8000000UL
|
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 | #include <util/delay.h>
|
63 | #include "wl_module.h"
|
64 | #include "nRF24L01.h"
|
65 | #include "spi.h"
|
66 |
|
67 |
|
68 |
|
69 | void atmega_init();
|
70 | void uart_init(void);
|
71 | int uart_putuint8_1(uint8_t c);
|
72 | void uart_putuint8_s(uint8_t *s);
|
73 | int uart_putc(char c);
|
74 | void uart_puts (char *s);
|
75 |
|
76 | uint8_t sendedaten[wl_module_PAYLOAD] = "Dies sind 32 Zeichen. Gesendet!!";
|
77 | uint8_t counter = 0;
|
78 | uint8_t status_funk = 71;
|
79 | volatile uint8_t PTX;
|
80 |
|
81 | int main(void)
|
82 | {
|
83 | uart_init();
|
84 | uart_puts("Beginne Initialisierungen...\n");
|
85 |
|
86 |
|
87 | atmega_init(); // Atmega initialisieren
|
88 | wl_module_init(); // Funkmodul initialisieren
|
89 | _delay_ms(50); // kurz warten
|
90 | sei();
|
91 | wl_module_tx_config(wl_module_TX_NR_0);
|
92 |
|
93 | wl_module_config_register(EN_AA,ENAA_P0); //Auto Acknowledgment bei P0
|
94 |
|
95 | // Status lesen
|
96 | uart_puts("Status: ");
|
97 | status_funk = wl_module_get_status();
|
98 | uart_putuint8_1(status_funk + '0');
|
99 | uart_puts(" \n");
|
100 |
|
101 | uart_puts("RX_payload: ");
|
102 | status_funk = wl_module_get_rx_pw(0);
|
103 | uart_putuint8_1(status_funk + '0');
|
104 | uart_puts(" \n");
|
105 |
|
106 |
|
107 | // ACHTUNG: Payload steht momentan auf 32
|
108 | while (1)
|
109 | {
|
110 | uart_puts("Sende: ...\n");
|
111 | sendedaten[wl_module_PAYLOAD-1] = counter+'0'; // Text ändern
|
112 | wl_module_send(sendedaten,wl_module_PAYLOAD); // senden
|
113 |
|
114 | //uart_putuint8_s(sendedaten);
|
115 |
|
116 | counter++;
|
117 | if (counter >=5)
|
118 | {
|
119 | counter = 0;
|
120 | }
|
121 | _delay_ms(1000);
|
122 | }
|
123 | }
|
124 |
|
125 |
|
126 | void atmega_init()
|
127 | {
|
128 | // Auf 8 MHz intern umstellen
|
129 | CLKPR = 0x80; // Aenderungen erlauben
|
130 | CLKPR = 0x00; // internen CLK nicht teilen = 8 MHz
|
131 |
|
132 | // Interrupt Funkmodul
|
133 | DDRB &= ~(1<<PINB6); // als Eingang definieren
|
134 | PCMSK0 = (1<<PCINT6); // PCint6 aktivieren (ACHTUNG: darf später nur auf fallende Flanke reagieren)
|
135 | PCICR = (1<<PCIE0);
|
136 | }
|
137 |
|
138 | ISR(PCINT0_vect)
|
139 | {
|
140 | uart_puts("ISR:...\n");
|
141 |
|
142 | if (!(PINB & (1<<PINB6))) // wenn interrupt aufgrund fallender Flanke
|
143 | {
|
144 | uint8_t status;
|
145 |
|
146 | uart_puts("ISR_IF...\n");
|
147 |
|
148 | // Read wl_module status
|
149 | wl_module_CSN_lo; // Pull down chip select
|
150 | status = spi_fast_shift(NOP); // Read status register
|
151 | wl_module_CSN_hi; // Pull up chip select
|
152 |
|
153 |
|
154 | if (status & (1<<TX_DS)) // IRQ: Package has been sent
|
155 | {
|
156 | uart_puts("ISR_package_send...\n");
|
157 | wl_module_config_register(STATUS, (1<<TX_DS)); //Clear Interrupt Bit
|
158 | PTX=0;
|
159 | }
|
160 |
|
161 | if (status & (1<<MAX_RT)) // IRQ: Package has not been sent, send again
|
162 | {
|
163 | uart_puts("ISR_package_not_send_send_again...\n");
|
164 | wl_module_config_register(STATUS, (1<<MAX_RT)); // Clear Interrupt Bit
|
165 | wl_module_CE_hi; // Start transmission
|
166 | _delay_us(10);
|
167 | wl_module_CE_lo;
|
168 | }
|
169 |
|
170 | if (status & (1<<TX_FULL)) //TX_FIFO Full <-- this is not an IRQ
|
171 | {
|
172 | uart_puts("ISR_FIFO_full...\n");
|
173 | wl_module_CSN_lo; // Pull down chip select
|
174 | spi_fast_shift(FLUSH_TX); // Flush TX-FIFO
|
175 | wl_module_CSN_hi; // Pull up chip select
|
176 | }
|
177 | }
|
178 | }
|
179 |
|
180 |
|
181 | void uart_init(void)
|
182 | {
|
183 | UBRR0H = UBRR_VAL >> 8;
|
184 | UBRR0L = UBRR_VAL & 0xFF;
|
185 |
|
186 | UCSR0B |= (1<<TXEN0); // UART TX einschalten
|
187 | UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); // Asynchron 8N1
|
188 | }
|
189 |
|
190 | int uart_putuint8_1(uint8_t c)
|
191 | {
|
192 | while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
|
193 | {
|
194 | }
|
195 |
|
196 | UDR0 = c; /* sende Zeichen */
|
197 | return 0;
|
198 | }
|
199 |
|
200 | void uart_putuint8_s(uint8_t *s)
|
201 | {
|
202 | while (*s)
|
203 | { /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
|
204 | uart_putuint8_1(*s);
|
205 | s++;
|
206 | }
|
207 | }
|
208 |
|
209 | int uart_putc(char c)
|
210 | {
|
211 | while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
|
212 | {
|
213 | }
|
214 |
|
215 | UDR0 = c; /* sende Zeichen */
|
216 | return 0;
|
217 | }
|
218 |
|
219 | void uart_puts(char *s)
|
220 | {
|
221 | while (*s)
|
222 | { /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
|
223 | uart_putc(*s);
|
224 | s++;
|
225 | }
|
226 | }
|