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,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
}