main_sender.c


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,EN_AA_ENAA_ALL);    //Auto Acknowledgment bei allen
94
  
95
  //wl_module_config_register(EN_RXADDR,EN_RXADDR_ERX_ALL);  // RX pipe alle aktivieren
96
  
97
  // Status lesen
98
  uart_puts("Status: ");
99
  status_funk = wl_module_get_status();
100
  uart_putuint8_1(status_funk + '0');
101
  uart_puts(" \n");
102
  
103
  uart_puts("RX_payload: ");
104
  status_funk = wl_module_get_rx_pw(0);
105
  uart_putuint8_1(status_funk + '0');
106
  uart_puts(" \n");
107
  
108
  
109
  // ACHTUNG: Payload steht momentan auf 32
110
    while (1) 
111
    {
112
    uart_puts("Sende: ...\n");
113
    sendedaten[wl_module_PAYLOAD-1] = counter+'0';    // Text ändern
114
    wl_module_send(sendedaten,wl_module_PAYLOAD);    // senden
115
    
116
    while (PTX)
117
    {
118
      uart_puts("Package lost: ");
119
      status_funk = wl_module_get_plos_cnt();
120
      uart_putuint8_1(status_funk + '0');
121
      uart_puts(" \n");
122
      
123
      uart_puts("Retransmitted Count: ");
124
      status_funk = wl_module_get_arc_cnt();
125
      uart_putuint8_1(status_funk + '0');
126
      uart_puts(" \n");
127
      _delay_ms(1500);
128
    }
129
    
130
    //uart_putuint8_s(sendedaten);
131
132
    counter++;
133
    if (counter >=5)
134
    {
135
      counter = 0;
136
    }
137
    _delay_ms(1000);
138
    }
139
}
140
141
142
void atmega_init()
143
{
144
  // Auf 8 MHz intern umstellen
145
  CLKPR = 0x80;            // Aenderungen erlauben
146
  CLKPR = 0x00;            // internen CLK nicht teilen = 8 MHz
147
    
148
  // Interrupt Funkmodul
149
  DDRB &= ~(1<<PINB6);      // als Eingang definieren
150
  PCMSK0 = (1<<PCINT6);      // PCint6 aktivieren (ACHTUNG: darf später nur auf fallende Flanke reagieren)
151
  PCICR = (1<<PCIE0);
152
}
153
154
ISR(PCINT0_vect)
155
{
156
  uart_puts("ISR:...\n");
157
  
158
  if (!(PINB & (1<<PINB6)))  // wenn interrupt aufgrund fallender Flanke
159
  {
160
    uint8_t status;
161
    
162
    uart_puts("ISR_IF...\n");
163
    
164
    // Read wl_module status
165
    wl_module_CSN_lo;                               // Pull down chip select
166
    status = spi_fast_shift(NOP);          // Read status register
167
    wl_module_CSN_hi;                               // Pull up chip select
168
    
169
    
170
    if (status & (1<<TX_DS))              // IRQ: Package has been sent
171
    {
172
      uart_puts("ISR_package_send...\n");
173
      wl_module_config_register(STATUS, (1<<TX_DS));  //Clear Interrupt Bit
174
      PTX=0;
175
    }
176
    
177
    if (status & (1<<MAX_RT))              // IRQ: Package has not been sent, send again
178
    {
179
      uart_puts("ISR_package_not_send_send_again...\n");
180
      wl_module_config_register(STATUS, (1<<MAX_RT));  // Clear Interrupt Bit
181
      wl_module_CE_hi;                // Start transmission
182
      _delay_us(10);
183
      wl_module_CE_lo;
184
    }
185
    
186
    if (status & (1<<TX_FULL))              //TX_FIFO Full <-- this is not an IRQ
187
    {
188
      uart_puts("ISR_FIFO_full...\n");
189
      wl_module_CSN_lo;                               // Pull down chip select
190
      spi_fast_shift(FLUSH_TX);            // Flush TX-FIFO
191
      wl_module_CSN_hi;                               // Pull up chip select
192
    }
193
  }
194
}
195
196
197
void uart_init(void)
198
{
199
  UBRR0H = UBRR_VAL >> 8;
200
  UBRR0L = UBRR_VAL & 0xFF;
201
  
202
  UCSR0B |= (1<<TXEN0);  // UART TX einschalten
203
  UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);  // Asynchron 8N1
204
}
205
206
int uart_putuint8_1(uint8_t c)
207
{
208
  while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
209
  {
210
  }
211
  
212
  UDR0 = c;                      /* sende Zeichen */
213
  return 0;
214
}
215
216
void uart_putuint8_s(uint8_t *s)
217
{
218
  while (*s)
219
  {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
220
    uart_putuint8_1(*s);
221
    s++;
222
  }
223
}
224
225
int uart_putc(char c)
226
{
227
  while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
228
  {
229
  }
230
  
231
  UDR0 = c;                      /* sende Zeichen */
232
  return 0;
233
}
234
235
void uart_puts(char *s)
236
{
237
  while (*s)
238
  {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
239
    uart_putc(*s);
240
    s++;
241
  }
242
}