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

📄 wireless.c

📁 关于PCB版的开发所需要的注意的情况,可以加快开发速度,是个设计人员的必要参考
💻 C
字号:
/* wireless.c ================================================================================================
 * 
 * This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTYT; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Author(s): Ole Saether
 *
 * NOTES:
 *
 * A frame is the time between each transmission of a packet.
 * A frame is divided into NSLOTS time-slots. The duration of a time-slot is 1/fs, where fs is the ADC
 * sampling frequency.
 *
 * The NOSYNC variable is used by the slave to keep track of how many frames have gone since it received a
 * valid packet. It is incremented once each frame in the TIMER2 irq handler and cleared each time a packet is
 * received. If the variable reaches the constant NSYNC (see below) the slave enters continuous receive mode.
 *
 * The pin P0.2 is used to select slave (P0.2 = 1) or master (P0.2 = 0).
 *
 * $Date: 8.10.03 12:02 $
 * $Revision: 1 $
 *
 *=============================================================================================================
*/
#include <Nordic\reg24e1.h>

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

#define FSZ         32                      // Buffer size
#define FMASK       FSZ-1

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

typedef struct RFConfig RFConfig;

#define NSLOTS      24                      // Number of samples in one packet
#define NSYNC       10                      // #frames wo/packets before the slave enters receive mode
#define RXSLOT      14                      // Wait from slot 14 to..
#define WTSLOT      21                      // ..slot 21 for reception of a packet
#define SYNCSLOT    20                      // When the slave receives a valid packet set the slot counter to this number


volatile unsigned char idata RxBuf[FSZ];
volatile unsigned char idata TxBuf[FSZ];
volatile unsigned char TxWrp, TxRdp, TxNum;
volatile unsigned char RxWrp, RxRdp, RxNum;
volatile unsigned char rec, slotn, nosync, slave, prevsample;

const RFConfig RxTxConf =
{
    15,
    0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xaa, 0xbb, 0x12, 0x34, 0x83, 0x6f, 0x04
};

void InitBuffers(void)
{
    RxWrp = RxRdp = RxRdp = RxNum = 0;
    TxWrp = TxRdp = TxRdp = TxNum = 0;
}

void Delay100us(volatile unsigned char n)
{
    unsigned char i;
    while(n--)
        for(i=0;i<35;i++)
            ;
}

unsigned char SpiReadWrite(unsigned char b)
{
    EXIF &= ~0x20;                          // Clear SPI interrupt
    SPI_DATA = b;                           // Move byte to send to SPI data register
    while((EXIF & 0x20) == 0x00)            // Wait until SPI hs finished transmitting
        ;
    return SPI_DATA;
}

void Init(void)
{
    unsigned char i;

    P0_DIR = 0x04;                          // P0.2 is input, the rest output
    P0 = 0x02;                              // P0.1 = 1 for the master/slave selection

    slotn = nosync = 0;
    InitBuffers();

    if ((P0 & 0x04) == 0x04)
        slave = 1;
    else
        slave = 0;

    // TIMER2:
    TR2 = 0;                                // Stop timer2 if running
    CKCON |= 0x20;                          // T2M=1 (/4 timer clock)

    RCAP2L = 0x0C;                          // 8KHz tick...
    RCAP2H = 0xFE;                          // ... = 65536-16e6/(4*8e3) = FE0Ch

    TF2 = 0;                                // Clear any pending timer2 interrupts
    TR2 = 1;                                // Start timer2
    ET2 = 1;                                // Enable timer2 interrupts

    // PWM:
    P0_ALT = 0x80;                          // Enable PWM output (P0.7)
    PWMCON = 0xC0;                          // Enable 8 bit PWM, pre=min
    PWMDUTY = 0xFF;

    // ADC:
    ADCSTATIC &= 0x1C;                      // DIFFM=0, SLEEP=0, CLK8=0
    ADCSTATIC |= 0x03;                      // 12 bit
    ADCCON = 0x32;                          // Channel 2, NPD=1, ADCRUN=0, EXTREF=1

    // RADIO:
    PWR_UP = 1;
    Delay100us(30);                         // Wait > 3ms
    
    // SPI:        
    SPICLK = 0x00;                          // Max SPICLK (=CLK/8)
    SPI_CTRL = 0x02;                        // Connect SPI to RADIO CH1
    
    // RADIO:
    CE = 0;
    CS = 1;                                 // RF SPI CS = 1
    Delay100us(0);
    for(i=0;i<RxTxConf.n;i++)
    {
        SpiReadWrite(RxTxConf.buf[i]);
    }
    CS = 0;
    EA = 1;                                 // Enable global interrupts
}

void TxPacket(void)
{
    unsigned char i, rp;
    
    CE = 1;
    Delay100us(0);
    // All packets start with the address:
    for (i=0;i<ADDR_COUNT;i++)
    {
        SpiReadWrite(RxTxConf.buf[ADDR_INDEX+i]);
    }
    /*
     * Read the packet from the transmit buffer and write it to the radio with inline
     * SPI commands (for increased speed) and update the buffer write pointer and
     * number of bytes in buffer:
     */        
    rp = TxRdp;
    for (i=0;i<NSLOTS;i++)
    {
        EXIF &= ~0x20;                      // Clear SPI interrupt
        SPI_DATA = TxBuf[rp];               // Move byte to send to SPI data register
        rp++;
        rp &= FMASK;        
        ET2 = 0;
        TxNum--;
        ET2 = 1;
        while((EXIF & 0x20) == 0x00)        // Wait until SPI hs finished transmitting
            ;        
    }
    CE = 0;
    TxRdp = rp;
}

void RxPacket(void)
{
    unsigned char wp;
    if(slave)
    {
        /*
         * Tell the interrupt routine that we have received 
         * a packet and it's time to sync to the master:
         */
        ET2 = 0;
        rec = 1;
        nosync = 0;
        ET2 = 1;
    }
    /*
     * Read the received packet from the radio with inline SPI commands (for increased speed)
     * and put it in the receive buffer and advance the buffer write pointer, and number of
     * bytes in the buffer:
     */
    while(DR1)
    {
        EXIF &= ~0x20;                      // Clear SPI interrupt
        SPI_DATA = 0;                       // Write dummy byte to SPI data register
        wp = RxWrp;
        RxWrp++;
        RxWrp &= FMASK;
        while((EXIF & 0x20) == 0x00)        // Wait until SPI hs finished receiving
            ;
        RxBuf[wp] = SPI_DATA;
        ET2 = 0;
        RxNum++;
        ET2 = 1;
    }
}

void Timer2ISR (void) interrupt 5  using 1
{
    unsigned char adc;
    
    TF2 = 0;                                // Clear timer2 interrupt    
    adc = ADCDATAH;                         // Read ADC and...
    ADCCON &= ~0x80;                        // ...start new...
    ADCCON |= 0x80;                         // ...conversion
    if(RxNum > 0)
    {
        /*
         * If there are any samples in receive buffer, write next
         * sample to the PWM and advance the buffer read pointer.
         */
        PWMDUTY = RxBuf[RxRdp];
        RxRdp++;
        RxRdp &= FMASK;
        RxNum--;
    }
    TxBuf[TxWrp] = adc;                     // Write ADC sample to the transmit buffer and..
    TxWrp++;                                // ..advance buffer..
    TxWrp &= FMASK;                         // ..write pointer
    TxNum++;
    if(rec != 0)                            // Valid packet received by slave?
    {
        rec = 0;                            // Yes, preset time...
        slotn = SYNCSLOT;                   // ...slot counter (sync to master)
    } else
    {
        slotn++;                            // Increment time slot counter
        if(slotn == NSLOTS)                 // If at beginning of frame....
        {
            slotn = 0;                      // ... reset time slot counter...
            if(nosync < 255)                // ...and update nosync counter
                nosync++;
        }
    }
}

void SetRxMode(void)
{
    CS = 1;
    Delay100us(0);
    SpiReadWrite(RxTxConf.buf[RxTxConf.n - 1] | 0x01);
    CS = 0;
}

void SetTxMode(void)
{
    CS = 1;
    Delay100us(0);
    SpiReadWrite(RxTxConf.buf[RxTxConf.n - 1]);
    CS = 0;
}

void WaitRx(void)
{
    SetRxMode();
    CE = 1;                                 // Radio CE = 1
    while(1)
    {
        if(DR1)                             // If data ready...
        {
            RxPacket();                     // ...receive packet
            break;
        }
        if(slave)
        {
            if(nosync > NSYNC)              // If slave has been out of sync for > NSYNC frames...
            {
                ET2 = 0;
                InitBuffers();              // ...initialize buffers and continue waiting
                ET2 = 1;
                continue;
            }            
        }
        if(slotn >= WTSLOT)
            break;
    }
    CE = 0;
}

void main(void)
{
    Init();    
    if(slave)
        WaitRx();                           // Perform syncing if slave
    while(1)
    {        
        while(slotn != 0)                   // Wait until slot no. 0 (Tx)
            ;
        if(TxNum >= NSLOTS)
        {
            SetTxMode();
            TxPacket();
        }
        while(slotn < RXSLOT)
            ;
        WaitRx();
    }
}

⌨️ 快捷键说明

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