Menu Content/Inhalt
Home arrow Tutorials arrow RF-24G Transceiver Driver
RF-24G Transceiver Driver

The following circuits show the required connections to use a RF-24G 2.4GHz Transceiver. The SPI communication requires 5 pins: CLK, Data, Data Recieved, Chip Select and Chip Enable.

Image
RF-24G Transceiver Schematic

The following code was written in WinAVR as a driver for this Transceiver. This code does not require any specific pins, only requiring 5 IO lines on your microcontroller.

Change the header file definitions for your IO pin configuration.

Download example project with makefile for WinAVR

/*
** rf24g.c 
**
** Wireless communication functions for use with RF-24G
** Target: ATMEGA :: AVR-GCC
**
** Written by Tony Myatt - Quantum Torque, 2007
*/
#include <avr/io.h>
#include "rf24g.h"
 
// Pin defines - change pin definitions in the header file
#define CE_H()        CE_PORT |= CE_BIT
#define CE_L()        CE_PORT &= ~CE_BIT
#define CS_H()        CS_PORT |= CS_BIT
#define CS_L()        CS_PORT &= ~CS_BIT
#define CLK1_H()    CK_PORT |= CK_BIT
#define CLK1_L()    CK_PORT &= ~CK_BIT
#define DATA()        ((DA_PIN & DA_BIT) == 0)?0:1
#define DATA_H()    DA_PORT |= DA_BIT
#define DATA_L()    DA_PORT &= ~DA_BIT
#define DATA_O()    DA_DIR |= DA_BIT
#define DATA_I()    DA_DIR &= ~DA_BIT
 
// Sleep functions - change F_CPU for speed and for compiler
#define F_CPU 8000000UL
#include <util/delay.h>
#define sleep_ms(t)    _delay_ms(t)
 
// Function prototypes
void rf24g_send_byte(unsigned char byte);
unsigned char rf24g_read_byte(void);
 
// Setup the pin directions for use with the RF24G
void rf24g_init(void)
{
    // DR1 - input
    DR_DIR &= ~DR_BIT;
    
    // CE, CS, CLK - outputs
    CE_DIR |= CE_BIT;
    CS_DIR |= CS_BIT;
    CK_DIR |= CK_BIT;
}
 
// Setup up a RF-24G for either receiving or sending
void rf24g_configure(unsigned char recv)
{
    // Set the RF Module into configuration mode
    CE_L(); CS_H();
    
    sleep_ms(1);
    
    // DATAW_BITS bit data width (1 & 2 Channels)
    rf24g_send_byte(DATAW_BITS);
    rf24g_send_byte(0x00);
    rf24g_send_byte(0x00);
    rf24g_send_byte(0x00);
    rf24g_send_byte(0x00);
    rf24g_send_byte(address());
    rf24g_send_byte(0x00);
    rf24g_send_byte(0x00);
    rf24g_send_byte(0x00);
    rf24g_send_byte(0x00);
    rf24g_send_byte(address());
    rf24g_send_byte(0x23);            // 8 bit Address, 16bit CRC/CRC Enabled
    rf24g_send_byte(0x4E | 0x01);     // Power, Freq, 250kbps, Shockburst, 1 Ch
    rf24g_send_byte(0x04 | recv);     // Channel & Rxen
    
    sleep_ms(1);
    
    // If recv then active mode else sleep
    if(recv) {
        CE_H(); CS_L();
    } else {        
        CE_L(); CS_L();
    }
}
 
// Recieve a packet using the RF24G
unsigned char rf24g_receive(CommsPacket* pkt)
{
    // Power down RF Front end
    CE_L();
    
    // Clock in data
    unsigned char i;
    for(i=0;i<10;i++) {
        pkt->data[i] = rf24g_read_byte();
    }
 
    // Power up RF Front end
    CE_H();
    
    // Always valid (is this really required?)
    return 1;
}
 
// Transmit a packet using the RF24G
void rf24g_transmit(CommsPacket* pkt)
{    
    // Make sure we are in active for sending
    CE_H();
    
    // Power up time
    sleep_ms(1);
 
    // Clock in address (default, page 11)
    rf24g_send_byte(pkt->addr);
    
    // Clock in the payload
    unsigned char i;
    for(i=0;i<10;i++) {
        rf24g_send_byte(pkt->data[i]);
    }
    
    // Start transmission
    CE_L();
    
    // Wait for transmittion
    sleep_ms(10);
}
 
// Private send byte function
void rf24g_send_byte(unsigned char byte)
{
    // Make the data pin an output
    DATA_O();
 
    // For every bit
    unsigned char i;
    for(i=0;i<8;i++) {
        
        // Set the DATA pin value
        if((byte>>(7-i)) & 0x01) {
            DATA_H();
        } else {
            DATA_L();
        }
        
        // Toggle the clock
        CLK1_H();
        CLK1_L();
    }
}
 
// Private read byte function
unsigned char rf24g_read_byte(void)
{
    // Make the data pin an input
    DATA_I();
    
    // Value read
    unsigned char value = 0x00;
 
    // Make the data pin an input
    unsigned char i;
    for(i=0;i<8;i++) {
    
        // Read the current bit
        value |= (DATA()<<(7-i));
        
        // Toggle the clock
        CLK1_H();
        CLK1_L();
    }
    return value;
}