⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radio.c

📁 这个程序是控制NRF24E1的跳频的测试程序
💻 C
字号:
/*= radio.c ========================================================================================
 *
 * Copyright (C) 2004 Nordic VLSI ASA
 *
 * Author(s): Ole Saether
 *
 * DESCRIPTION:
 *
 *  Packet format:
 *
 *  [4bytes address][1byte msg ID][0-25bytes msg data][16bit CRC]
 *
 *
 * COMPILER:
 *  
 *   This program has been tested with Keil C51 V7.08
 *
 * $Revision: 3 $
 *
 *==================================================================================================
*/
#include <reg24e1.h>
#include "util.h"
#include "radio.h"

const unsigned char code rnd_tab[256] =
{
	// This table contains four each of the numbers 2 to 65 (0x02-0x41) randomly distributed.
	// If you need longer random cycles than this you could use an 8-bit pseudo random generator
	// and use it to index this table.
    0x28, 0x29, 0x38, 0x07, 0x19, 0x17, 0x2F, 0x1F, 0x14, 0x16, 0x1F, 0x06, 0x38, 0x1B, 0x3B, 0x33,
	0x33, 0x2F, 0x37, 0x1A, 0x32, 0x15, 0x19, 0x34, 0x1B, 0x2D, 0x13, 0x02, 0x3F, 0x18, 0x10, 0x10,
	0x0A, 0x1D, 0x0D, 0x37, 0x3D, 0x0B, 0x2A, 0x25, 0x1F, 0x20, 0x41, 0x21, 0x2F, 0x2A, 0x36, 0x09,
	0x1C, 0x2C, 0x0F, 0x1E, 0x39, 0x03, 0x06, 0x03, 0x2B, 0x0A, 0x1D, 0x02, 0x24, 0x3A, 0x32, 0x10,
	0x16, 0x16, 0x13, 0x12, 0x20, 0x06, 0x13, 0x1F, 0x0D, 0x41, 0x1E, 0x08, 0x3D, 0x31, 0x09, 0x16,
	0x23, 0x12, 0x2D, 0x12, 0x31, 0x1C, 0x36, 0x0B, 0x11, 0x21, 0x37, 0x13, 0x38, 0x41, 0x0B, 0x32,
	0x1B, 0x33, 0x20, 0x29, 0x0E, 0x05, 0x41, 0x1E, 0x05, 0x0C, 0x38, 0x1D, 0x20, 0x2F, 0x29, 0x39,
	0x3D, 0x04, 0x26, 0x10, 0x12, 0x36, 0x3B, 0x08, 0x3D, 0x3C, 0x1A, 0x24, 0x08, 0x07, 0x35, 0x15,
	0x2A, 0x40, 0x2C, 0x11, 0x31, 0x28, 0x2A, 0x1E, 0x02, 0x07, 0x19, 0x32, 0x28, 0x39, 0x1A, 0x28,
	0x19, 0x22, 0x03, 0x21, 0x39, 0x09, 0x03, 0x0F, 0x3E, 0x2D, 0x0D, 0x37, 0x18, 0x3E, 0x09, 0x25,
	0x26, 0x11, 0x36, 0x1A, 0x18, 0x25, 0x3E, 0x29, 0x08, 0x3C, 0x2B, 0x33, 0x02, 0x0A, 0x05, 0x0A,
	0x1C, 0x2C, 0x07, 0x23, 0x3E, 0x1B, 0x3F, 0x2E, 0x3B, 0x31, 0x2B, 0x24, 0x35, 0x26, 0x1D, 0x2E,
	0x11, 0x3C, 0x15, 0x2B, 0x15, 0x24, 0x2C, 0x27, 0x0D, 0x34, 0x14, 0x23, 0x21, 0x04, 0x3A, 0x27,
	0x0F, 0x40, 0x27, 0x0B, 0x30, 0x2E, 0x17, 0x25, 0x3C, 0x34, 0x40, 0x34, 0x0C, 0x2D, 0x30, 0x18,
	0x40, 0x0F, 0x22, 0x26, 0x27, 0x3F, 0x30, 0x22, 0x30, 0x3F, 0x23, 0x14, 0x3A, 0x14, 0x3B, 0x0C,
	0x06, 0x04, 0x05, 0x3A, 0x35, 0x0E, 0x0E, 0x0C, 0x17, 0x1C, 0x35, 0x0E, 0x04, 0x2E, 0x17, 0x22
};

#define ADDR_INDEX  8                           // Index to default address bytes in RxTxConf.buf 
#define ADDR_COUNT  4                           // Number of address bytes

static unsigned char idata rfAddress[ADDR_COUNT];

struct RFConfig
{
    unsigned char n;
    unsigned char buf[15];
};

typedef struct RFConfig RFConfig;

const RFConfig RxTxConf =
{
    15,
    0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xcd, 0xef, 0x12, 0xaa, 0x83, 0x6c, 0x04
};

static unsigned char seq, hopIdx, nBytes;
static unsigned rxTout, txTout;

static void SetRxMode(void)
{
    // Put the transceiver into receive mode on current hopping frequency:
    unsigned char ch;
    CS = 1;
    Delay100us(0);
    ch = rnd_tab[hopIdx] << 1;
    SpiReadWrite(ch | 0x01);
    CS = 0;
}

static void SetTxMode(void)
{
    // Put the transceiver into transmit mode on current hopping frequency:
    unsigned char ch;
    CS = 1;
    Delay100us(0);
    ch = rnd_tab[hopIdx] << 1;
    SpiReadWrite(ch);
    CS = 0;
}

static void InitCommon(unsigned char *pAddr)
{
    unsigned char i;

    hopIdx = 0;                                 // Start at index #0 in the channel table above
    if (pAddr != 0)
    {
        for(i=2;i<ADDR_INDEX;i++)
            SpiReadWrite(RxTxConf.buf[i]);
        for(i=0;i<ADDR_COUNT;i++)
        {
            rfAddress[i] = pAddr[i];
            SpiReadWrite(pAddr[i]);
        }
        for(i=0;i<3;i++)
            SpiReadWrite(RxTxConf.buf[RxTxConf.n-3+i]);
    } else
    {
        for (i=0;i<ADDR_COUNT;i++)
        {
            rfAddress[i] = RxTxConf.buf[ADDR_INDEX+i];
        }
        for(i=2;i<RxTxConf.n;i++)
        {
            SpiReadWrite(RxTxConf.buf[i]);
        }
    }
    CS = 0;
    PWR_UP = 1;                                 // Turn on power on radio
    Delay100us(30);                             // Wait > 3ms
}

static void TransmitBytes(unsigned char *pBuf, unsigned char msgid)
{
    // Transmit one packet with the format specified in the header of this file:
    unsigned char i;

    SetTxMode();
    CE = 1;
    Delay100us(1);

    for (i=0;i<ADDR_COUNT;i++)
    {
        SpiReadWrite(rfAddress[i]);
    }
    SpiReadWrite(msgid);                        // All packets start with a one byte ID
    for (i=0;i<nBytes;i++)
    {
        SpiReadWrite(pBuf[i]);
    }
    CE = 0;
    Delay100us(5);                              // Wait until finished transmitting (200us + 256us)
}

static void SendAck(unsigned char msgid)
{
    // Send a one byte acknowledge
    unsigned char i;

    SetTxMode();
    CE = 1;
    Delay100us(1);

    for (i=0;i<ADDR_COUNT;i++)
    {
        SpiReadWrite(rfAddress[i]);
    }
    SpiReadWrite(msgid);                        // An ACK contains only the ID and no data
    CE = 0;
    Delay100us(3);                              // Wait until finished transmitting
}


static unsigned char ReceiveBytes(unsigned char *pBuf)
{
    unsigned char i, cmd;

    SetRxMode();
    CE = 1;    
    ResetTimer(1);
    while(DR1 == 0)
    {
        if ((rxTout != 0) && (GetTimer(1) > rxTout))
        {
            CE = 0;
            return 0;
        }
    }
    cmd = SpiReadWrite(0);
    i = 0;
    while(DR1)
    {
        pBuf[i++] = SpiReadWrite(0);
        if (i == nBytes)
            break;
    }
    while(DR1)
    {
        SpiReadWrite(0);
    }
    CE = 0;
    return cmd;
}

static unsigned char WaitAck(void)
{
    unsigned char ack;
    SetRxMode();
    CE = 1;
    ResetTimer(0);
    while(DR1 == 0)
    {
        if (GetTimer(0) > 2)                    // 3ms time-out
        {
            CE = 0;
            return 0;
        }
    }
    ack = SpiReadWrite(0);
    while(DR1)
    {
        SpiReadWrite(0);
    }
    CE = 0;
    return ack;
}

unsigned char TransmitPacket(unsigned char *pBuf)
{
    unsigned int i;
    unsigned char cmdt, cmdr, j;

    seq++;
    cmdt = 0x10 | (seq & 0x0f);
    cmdr = 0;
    ResetTimer(1);
    for(;;)
    {
        for (i=0;i<256;i++)
        {
            // Repeat two times on all channels if no ACK is received
            for (j=0;j<2;j++)
            {
                TransmitBytes(pBuf, cmdt);
                cmdr = WaitAck();
                if ((cmdr != 0) && ((cmdr & 0x0f) == (cmdt & 0x0f)))
                {
                    hopIdx++;
                    return 1;
                }
            }
            hopIdx++;
            if ((txTout != 0) && (GetTimer(1) > txTout))
                return 0;
        }
    }
    return 0;
}

unsigned char ReceivePacket(unsigned char *pBuf)
{
    unsigned char cmd, done;

    done = 0;
    while(done == 0)
    {
        cmd = ReceiveBytes(pBuf);
        cmd = (cmd & 0x0f) | 0x20;
        SendAck(cmd);
        hopIdx++;
        if ((cmd & 0x0f) != seq)
        {
            seq = cmd & 0x0f;
            done = 1;
        }
    }
    return 1;
}

void ReceiverTimeout(unsigned tOut)
{
	// Set the receiver timeout in ms.
	// 1ms = min timeout, 65536ms is max, 0 means wait forever
	rxTout = tOut;
}

void TransmitterTimeout(unsigned tOut)
{
	// Set the transmitter timeout in ms
	// 1ms is min timeout, 65536ms is max, 0 means wait forever
	txTout = tOut;
}

void InitReceiver(unsigned char n, unsigned char *pAddr)
{
    seq = 15;
    rxTout = 3000;								// Default 3s timeout    
    nBytes = n;                                 // Number of data bytes (0-25)

    SPICLK = 0;                                 // Max SPI clock
    SPI_CTRL = 0x02;                            // Connect internal SPI controller to Radio
    CE = 0;
    CS = 1;                                     // RF SPI CS = 1
    Delay100us(0);

    SpiReadWrite(0x00);                         // We are not using the DuoCeiver functionallity
    SpiReadWrite((n+1)*8);                      // Number of Rx data bits
    InitCommon(pAddr);
}

void InitTransmitter(unsigned char n, unsigned char *pAddr)
{
    seq = 0;
    txTout = 3000;								// Default 3s timeout
    nBytes = n;                                 // Number of data bytes (0-25)
    SPICLK = 0;                                 // Max SPI clock
    SPI_CTRL = 0x02;                            // Connect internal SPI controller to Radio
    CE = 0;
    CS = 1;                                     // RF SPI CS = 1
    Delay100us(0);
    SpiReadWrite(0x00);                         // We are not using the DuoCeiver functionallity
    SpiReadWrite(8);                            // Number of Rx data bits is 8 for the transmitter
    InitCommon(pAddr);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -