ATMEGA 128RFA1 - Bit übertragen

OP (Firma: Ostfalia WF) #3362121
Lesenswert?

Hallo,

im Rahmen einer Studienarbeit soll ich zum Thema HF-Technik eine Antenne 
für den 128RFA1 entwickeln.
Dabei stelle ich zwei Platinen mit Planar-Antennen her, an die jeweils 
ein 128RFA1 angeschlossen wird.

Um die korrekte Funktion zu demonstrieren, soll irgendwas übertragen 
werden. Da habe ich mir überlegt, dass es das einfachste ist 1 Bit zu 
übertragen. Bedeutet: Wenn ich bei dem einen Controler eine Taste 
drücke, so soll auf der anderen Platine eine LED leuchten.

Leider habe ich bisher nicht herausfinden können, wie ich den RF-Kanal 
nutzen kann, und konnte bisher auch keine genauen Informationen im 
Internet finden.

Vieleicht kann mir jemand zeigen, wie ich dieses Problem am einfachsten 
lösen kann.


Vielen Dank schon einmal im Voraus.

Florian
OP (Firma: Ostfalia WF) #3365278
Lesenswert?

Ja das Bit habe ich jetzt vergessen und versuche nun ein Byte zu 
übertragen. Der Inhalt ist ja zunächst auch egal.

Folgendes Programm habe ich jetzt am laufen:

main.c
1
#include <asf.h>
2
#include <avr/io.h>
3
#include "RadioFunctions.h"
4

5

6
int main (void)
7
{
8
  board_init();
9
  
10
  DDRE  = 0b11111111;
11
  //DDRE |= (1 << DDE5);
12
  
13
  DDRE  &= ~(1<<PE5);  /* Pin PC7 als Eingang */
14
  PORTE |= (1<<PE5);    /* internen Pull-Up an PC7 aktivieren */
15
  rfBegin(11);  // Initialize ATmega128RFA1 radio on channel 11 (can be 11-26)
16
  
17
  
18
  while(1)
19
  {
20
    PORTE = 0xFF;
21

22
    if (  PINE & (1<<PINE5)  )   //Taste senden  
23
    {
24
      
25
      //PORTE |= (1<<PE4);
26

27
    } else
28
    {
29
       rfWrite(0xFF); // ...send it out the radio.
30
      //
31
      
32
    }
33
  
34
    if (rfAvailable()) // If data receievd on radio...
35
    {
36
             //ggf. LED ansteuern
37
    }
38
  }
39

40
}


RadioFunctions.h
1
uint8_t rssiRaw; // Global variable shared between RX ISRs
2
#include <asf.h>
3
#include <string.h>
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <util/delay.h>
7
#define F_CPU 20000000
8

9
const int RF_BUFFER_SIZE = 127;
10
struct ringBuffer
11
{
12
  unsigned char buffer[127];
13
  volatile unsigned int head;
14
  volatile unsigned int tail;
15
} radioRXBuffer;
16

17

18
// Initialize the RFA1's low-power 2.4GHz transciever.
19
// Sets up the state machine, and gets the radio into
20
// the RX_ON state. Interrupts are enabled for RX
21
// begin and end, as well as TX end.
22
uint8_t rfBegin(uint8_t channel)
23
{
24
  for (int i=0; i<128; i++)
25
  {
26
    radioRXBuffer.buffer[i] = 0;
27
  }
28
  radioRXBuffer.tail = 0;
29
  radioRXBuffer.head = 0;
30

31
  // Transceiver Pin Register -- TRXPR.
32
  // This register can be used to reset the transceiver, without
33
  // resetting the MCU.
34
  TRXPR |= (1<<TRXRST); // TRXRST = 1 (Reset state, resets all registers)
35

36
  // Transceiver Interrupt Enable Mask - IRQ_MASK
37
  // This register disables/enables individual radio interrupts.
38
  // First, we'll disable IRQ and clear any pending IRQ's
39
  IRQ_MASK = 0; // Disable all IRQs
40
  
41
  // Transceiver State Control Register -- TRX_STATE
42
  // This regiseter controls the states of the radio.
43
  // First, we'll set it to the TRX_OFF state.
44
  TRX_STATE = (TRX_STATE & 0xE0) | TRX_OFF; // Set to TRX_OFF state
45
  
46

47
  PORTE &= ~(1<<PE2); 
48
  _delay_ms(1000);
49
  PORTE |= (1<<PE2);
50

51
  // Transceiver Status Register -- TRX_STATUS
52
  // This read-only register contains the present state of the radio transceiver.
53
  // After telling it to go to the TRX_OFF state, we'll make sure it's actually
54
  // there.
55

56
  if ((TRX_STATUS & 0x1F) != TRX_OFF) // Check to make sure state is correct
57
  return 0;        // Error, TRX isn't off
58

59
  // Transceiver Control Register 1 - TRX_CTRL_1
60
  // We'll use this register to turn on automatic CRC calculations.
61
  TRX_CTRL_1 |= (1<<TX_AUTO_CRC_ON); // Enable automatic CRC calc.
62
  
63
  // Enable RX start/end and TX end interrupts
64
  IRQ_MASK = (1<<RX_START_EN) | (1<<RX_END_EN) | (1<<TX_END_EN);
65
  
66
  // Transceiver Clear Channel Assessment (CCA) -- PHY_CC_CCA
67
  // This register is used to set the channel. CCA_MODE should default
68
  // to Energy Above Threshold Mode.
69
  // Channel should be between 11 and 26 (2405 MHz to 2480 MHz)
70
  if ((channel < 11) || (channel > 26)) channel = 11;
71
  PHY_CC_CCA = (PHY_CC_CCA & 0xE0) | 11; // Set the channel to 11
72
  
73
  // Finally, we'll enter into the RX_ON state. Now waiting for radio RX's, unless
74
  // we go into a transmitting state.
75
  TRX_STATE = (TRX_STATE & 0xE0) | RX_ON; // Default to receiver
76

77
  return 1;
78
}
79

80

81
// This function will transmit a single byte out of the radio.
82
void rfWrite(uint8_t b)
83
{
84
  uint8_t length = 3;
85

86
  // Transceiver State Control Register -- TRX_STATE
87
  // This regiseter controls the states of the radio.
88
  // Set to the PLL_ON state - this state begins the TX.
89
  TRX_STATE = (TRX_STATE & 0xE0) | PLL_ON; // Set to TX start state
90
  while(!(TRX_STATUS & PLL_ON))
91
  ; // Wait for PLL to lock
92

93
  //digitalWrite(TX_LED, HIGH); // Turn on TX LED
94
  
95
  PORTE &= ~(1<<PE3); 
96

97
  // Start of frame buffer - TRXFBST
98
  // This is the first byte of the 128 byte frame. It should contain
99
  // the length of the transmission.
100
  TRXFBST = length;
101
  // Now copy the byte-to-send into the address directly after TRXFBST.
102
  memcpy((void *)(&TRXFBST+1), &b, 1);
103

104
  // Transceiver Pin Register -- TRXPR.
105
  // From the PLL_ON state, setting SLPTR high will initiate the TX.
106
  TRXPR |= (1<<SLPTR); // SLPTR = 1
107
  TRXPR &= ~(1<<SLPTR); // SLPTR = 0 // Then bring it back low
108

109
  // After sending the byte, set the radio back into the RX waiting state.
110
  TRX_STATE = (TRX_STATE & 0xE0) | RX_ON;
111
}
112

113
// Returns how many unread bytes remain in the radio RX buffer.
114
// 0 means the buffer is empty. Maxes out at RF_BUFFER_SIZE.
115
unsigned int rfAvailable()
116
{
117
  return (unsigned int)(RF_BUFFER_SIZE + radioRXBuffer.head - radioRXBuffer.tail) % RF_BUFFER_SIZE;
118
}
119

120
// This function reads the oldest data in the radio RX buffer.
121
// If the buffer is emtpy, it'll return a 255.
122
char rfRead()
123
{
124
  if (radioRXBuffer.head == radioRXBuffer.tail)
125
  {
126
    return -1;
127
  }
128
  else
129
  {
130
    // Read from the buffer tail, and update the tail pointer.
131
    char c = radioRXBuffer.buffer[radioRXBuffer.tail];
132
    radioRXBuffer.tail = (unsigned int)(radioRXBuffer.tail + 1) % RF_BUFFER_SIZE;
133
    return c;
134
  }
135
}
136

137
// This interrupt is called when radio TX is complete. We'll just
138
// use it to turn off our TX LED.
139
ISR(TRX24_TX_END_vect)
140
{  
141
  PORTE |= (1<<PE3); 
142
}
143

144
// This interrupt is called the moment data is received by the radio.
145
// We'll use it to gather information about RSSI -- signal strength --
146
// and we'll turn on the RX LED.
147
ISR(TRX24_RX_START_vect)
148
{
149

150
  rssiRaw = PHY_RSSI; // Read in the received signal strength
151
  PORTE &= ~(1<<PE4);
152
}
153

154
// This interrupt is called at the end of data receipt. Here we'll gather
155
// up the data received. And store it into a global variable. We'll
156
// also turn off the RX LED.
157
ISR(TRX24_RX_END_vect)
158
{
159
  uint8_t length;
160
  // Maximum transmission is 128 bytes
161
  uint8_t tempFrame[RF_BUFFER_SIZE];
162

163
  // The received signal must be above a certain threshold.
164
  if (rssiRaw & RX_CRC_VALID)
165
  {
166
    // The length of the message will be the first byte received.
167
    length = TST_RX_LENGTH;
168
    // The remaining bytes will be our received data.
169
    memcpy(&tempFrame[0], (void*)&TRXFBST, length);
170
    
171
    // Now we need to collect the frame into our receive buffer.
172
    // k will be used to make sure we don't go above the length
173
    // i will make sure we don't overflow our buffer.
174
    unsigned int k = 0;
175
    unsigned int i = (radioRXBuffer.head + 1) % RF_BUFFER_SIZE; // Read buffer head pos and increment;
176
    while ((i != radioRXBuffer.tail) && (k < length-2))
177
    {
178
      // First, we update the buffer with the first byte in the frame
179
      radioRXBuffer.buffer[radioRXBuffer.head] = tempFrame[k++];
180
      radioRXBuffer.head = i; // Update the head
181
      i = (i + 1) % RF_BUFFER_SIZE; // Increment i % BUFFER_SIZE
182
    }
183
  }
184

185
  // Turn receive LED off, and we're out
186
  PORTE |= (1<<PE4);
187
}

Das Senden sollte meiner Meinung nach funktionieren, habe dies mittels 
Spektrumanalysater getestet (Beim Drücken der Sendetaste ist die 
Frequenz 2,405 GHz im Spektrum vorhanden). Wird die Taste gedrück, geht 
auch brav die TX-LED an.
Allerdings tut sich  beim zweiten uC nichts. Eigentlich sollte dort dann 
die RX Lampe agehen, gesteuert von der ISR. Auf beiden uC läuft das 
selbe Programm.

Mehr zu diesem Problem habe ich im Internet noch nicht herausfinden 
können.
Moderator Persönliche Seite #3365329
Lesenswert?

Karl Heinz Buchegger schrieb:
> Die Leib und Mageneinheit eines µC ist 1 Byte. Alles andere ist
> zusätzlicher Aufwand.

In diesem Falle ist die Leib- und Mageneinheit ein Frame, denn nur
einen solchen kann ein Transceiver nach IEEE 802.15.4 übertragen.

Ansonsten würde ich dem TE mal das µracoli-Projekt nahelegen,
besonders natürlich angesichts der Tatsache, dass sein Hauptaugenmerk
ja gar nicht auf der eigentlichen Datenübertragung, sondern auf dem
Antennendesign liegt.

Wenn du eine wirklich gute Vergleichsantenne haben willst: nimm die
aus der Appnote AVR2006.  An deren 6,5 dBi darfst du, gemessen am
vergleichsweise geringen Aufwand, den sie treibt, deine Experimente
messen lassen.  (Wenn du dich mal bei den Erklärungen zu meinen
Boards von „Tic-Tac-Toe Reloaded“ umsiehst, kann man diese Antenne
unter bestimmten Umständen direkt ohne Tiefpass an den ATmega128RFA1
klemmen, ohne die ETSI-Grenzwerte für die Störstrahlung zu 
überschreiten.
Nimm aber dann möglichst die Sendeleistung etwas zurück.)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren