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

📄 at86rf230.h

📁 AVR单片机C语言程序设计实例精粹
💻 H
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 * at86rf230.h
 * April 2007
 ****************************************************************************/


/****************************************************************************/
#ifndef _DELAY_INCLUDED_
    #include <delay.h>
#endif

#ifndef _AT86RF230_INCLUDED_
    #define _AT86RF230_INCLUDED_
#endif

#ifndef _SPI_INCLUDED_
    #include <spi.h>
#endif

/****************************************************************************/
//List of Transceiver Registers
#define TRX_STATUS       0x01
#define TRX_STATE        0x02
#define TRX_CTRL_0       0x03
#define PHY_TX_PWR       0x05
#define PHY_RSSI         0x06
#define PHY_ED_LEVEL     0x07
#define PHY_CC_CCA       0x08
#define CCA_THRES        0x09
#define IRQ_MASK         0x0E
#define IRQ_STATUS       0x0F
#define VREG_CTRL        0x10
#define BATMON           0x11
#define XOSC_CTRL        0x12
#define FTN_CTRL         0x18
#define PLL_CF           0x1A
#define PLL_DCU          0x1B
#define PART_NUM         0x1C
#define VERSION_NUM      0x1D
#define MAN_ID_0         0x1E
#define MAN_ID_1         0x1F
#define SHORT_ADDR_0     0x20
#define SHORT_ADDR_1     0x21
#define PAN_ID_0         0x22
#define PAN_ID_1         0x23
#define IEEE_ADDR_0      0x24
#define IEEE_ADDR_1      0x25
#define IEEE_ADDR_2      0x26
#define IEEE_ADDR_3      0x27
#define IEEE_ADDR_4      0x28
#define IEEE_ADDR_5      0x29
#define IEEE_ADDR_6      0x2A
#define IEEE_ADDR_7      0x2B
#define XAH_CTRL         0x2C
#define CSMA_SEED_0      0x2D
#define CSMA_SEED_1      0x2E

//List of Transceiver States
#define NOP              0x00
#define TX_START         0x02
#define FORCE_TRX_OFF    0x03
#define RX_ON            0x06
#define TRX_OFF          0x08
#define PLL_ON           0x09
#define RX_AACK_ON       0x22
#define TX_ARET_ON       0x25

//SPI data direction register (DDR)
#define DDR_SS   DDRB.4  //Slave Select
#define DDR_MOSI DDRB.5  //Master Out - Slave In
#define DDR_MISO DDRB.6  //Master In - Slave Out
#define DDR_SCLK DDRB.7  //SPI Clock
//SPI chip select (CS)
#define RF230_SEL        PORTC.3
#define DDR_RF230_SEL    DDRC.3
//GPIO (General purpose input output) interface
#define RF230_IRQ        PINC.0
#define DDR_RF230_IRQ    DDRC.0
#define RF230_SLP_TR     PORTC.1
#define DDR_RF230_SLP_TR DDRC.1
#define RF230_RESET      PORTC.2
#define DDR_RF230_RESET  DDRC.2

//IRQ status masks
#define IRQ_BAT_LOW      0x80  //Battery low signal
#define IRQ_TRX_UR       0x40  //FIFO underrun signal
#define IRQ_TRX_END      0x08  //End of frame (transmit and receive)
#define IRQ_RX_START     0x04  //Beginning of receive frame
#define IRQ_PLL_UNLOCK   0x02  //PLL goes from lock to unlock state
#define IRQ_PLL_LOCK     0x01  //PLL goes from unlock to lock state

//Protocol Commands
#define PING             0xA1  //See if there is a transmitter in range
#define DATA_REQ         0xA5  //Request data from transmitter

//energy detection threshold
#define ED_THRESH        0x10

/****************************************************************************/
//Function Prototypes
unsigned char RF_RX_channel_scan(void);
unsigned char RF_TX_channel_scan(void);
void init_spi(void);
void set_transceiver_clock(void);
void RF_init_spi(void);
unsigned char RF_read_register(unsigned char address);
void RF_write_register(unsigned char address, unsigned char data);
void RF_init_transmitter(void);
void RF_transmit_test(void);
void RF_init_receiver(void);
void RF_receive_test(void);
void RF_download_frame(void);
void RF_transmit_frame(void);
void RF_receiver_listen(void);
void RF_upload_frame(void);
unsigned char RF_update_IRQ_status(void);
unsigned char RF_transmit_done(void);
unsigned char RF_receiver_listen_timeout(unsigned char loop_count);
unsigned char RF_TX_channel_scan(void);
void RF_TX_sync(void);
void RF_tx_to_rx(void);
void RF_rx_to_tx(void);
void RF_RX_sync(void);

/****************************************************************************/
//Global Variables to use for interfacing
unsigned char transmit_frame[20];  //User code fills transmit_frame
unsigned char receive_frame[20];   //User code reads receive_frame
unsigned char LQI;                 //User may use LQI after receiving frame
unsigned char tx_frame_length;     //User can set frame length before transmit
unsigned char rx_frame_length;     //Read frame length while receiving
unsigned char curr_IRQ_status;

/****************************************************************************/
void RF_clear_IRQ(void)  {
  curr_IRQ_status = RF_read_register(IRQ_STATUS);
  curr_IRQ_status = 0;
}

/****************************************************************************/
//Function determines if channel is clear or not using CCA
//CCA = clear channel assessment
//channel parameter must be between 11 and 26
//Returns 0 if channel is busy and 1 if channel is clear
unsigned char RF_CCA(unsigned char channel)  {
  unsigned char status = 0;
  if ((channel < 11) || (channel > 26)) return 0;  //invalid input
  channel = (channel | 0b10000000); //Set bit 7 to 1 to start CCA check
  RF_write_register(PHY_CC_CCA,channel);
  delay_us(140);
  status = RF_read_register(TRX_STATUS);
  if ((status&0b01000000) != 0) return 1;  //channel is available
  else return 0;
}

/****************************************************************************
*  Function scans for clear channel using CCA. Sets channel to best option
*  for reception. Need another function to transmit beacon frame over that 
*  channel, listen for a response. This function returns 0 if there is no good 
*  channel, or it returns the value of the channel with the strongest signal.
***************************************************************************/
unsigned char RF_RX_channel_scan(void)  {
  unsigned char i = 0;
  unsigned char status;
  for (i=16;i<=26;i++)  {
    RF_write_register(PHY_CC_CCA,(0b10000000 | i));  
    //see if channel i is available
    do {
      status = RF_read_register(TRX_STATUS);
    } while((status&0b10000000) == 0);
    if ((status&0b01000000) == 0)  return i;  //return clear channel
  }
  for (i = 11; i<16; i++)  {
    RF_write_register(PHY_CC_CCA,(0b10000000 | i));  
    //see if channel i is available
    do {
      status = RF_read_register(TRX_STATUS);
    } while((status&0b10000000) == 0);
    if ((status&0b01000000) != 0)  return i;  //return clear channel
  }
  return 0;
}

/****************************************************************************
*  Function scans for channel with highest signal quality above a certain
*  threshold, returns best channel. Need another function to listen for beacon 
*  frame, respond with acknowledgement frame.
*****************************************************************************/
unsigned char RF_TX_channel_scan(void)  {
  unsigned char max_channel_strength = 0;
  unsigned char max_channel = 0;
  unsigned char curr_channel_strength;
  unsigned char i;

  for (i=11;i<=26;i++)  {
    RF_write_register(PHY_CC_CCA,i);  //change to specific channel
    delay_us(400);  //wait for channel change to complete
    RF_write_register(PHY_ED_LEVEL,0x00);  //start ED calculation
    delay_us(130);  //wait for conversion to complete
    curr_channel_strength = RF_read_register(PHY_ED_LEVEL);
    if ((curr_channel_strength > ED_THRESH) && 
        (curr_channel_strength > max_channel_strength))  {
      max_channel_strength = curr_channel_strength;
      max_channel = i;
    }
  }
  return max_channel;
}

/****************************************************************************/
void RF_TX_sync(void)  {
  unsigned char channel;
  while (1)  {   //keep searching until a receiver is found
    do  {
      //find best channel, if any available
      channel = RF_TX_channel_scan();
    } while(channel == 0);
    RF_write_register(PHY_CC_CCA,channel);  //switch to channel
    delay_us(200);
    RF_tx_to_rx();  //switch to reception mode
    delay_us(200);
    if (RF_receiver_listen_timeout(50) == 1)  break;  
    //wait for a short time for a frame to be received
  }
  RF_rx_to_tx();
  delay_us(200);
  tx_frame_length = 1;
  transmit_frame[0] = 0xAA;
  RF_download_frame();
  RF_transmit_frame();
}

/****************************************************************************/
void RF_RX_sync(void)  {
  unsigned char channel,i;
  do  {
    channel = RF_RX_channel_scan();
  } while(channel==0);
  RF_write_register(PHY_CC_CCA,channel);  //switch to channel
  delay_us(200);
  while (1)  {
    RF_rx_to_tx();  //switch to transmission mode
    delay_us(200);
    tx_frame_length = 10;
    for (i=0;i<10;i++)  {
      transmit_frame[i] = 0xAA;
    }
    RF_download_frame();
    RF_transmit_frame();
    RF_tx_to_rx();  //switch to reception mode
    delay_us(200);
    if (RF_receiver_listen_timeout(50) == 1) break;
  }
}

/****************************************************************************/
unsigned char RF_receiver_listen_timeout(unsigned char loop_count)  {
  do {
    if (RF230_IRQ != 0)  {
      curr_IRQ_status = RF_read_register(IRQ_STATUS);
    }
    delay_us(250);
    loop_count--;
  } while (((curr_IRQ_status & IRQ_TRX_END) == 0 )&&((loop_count) > 0));
  if ((curr_IRQ_status&IRQ_TRX_END) != 0) {
    curr_IRQ_status = 0;
    return (loop_count+1);
  }
  curr_IRQ_status = 0;
  return loop_count;
}

/****************************************************************************/
void init_spi(void) {
  //Set up SPI I/O data direction
  DDR_MOSI = 1;
  DDR_MISO = 0;
  DDR_SCLK = 1;
  DDR_SS = 1;  //SS must be configured as output to set MCU as SPI master
  PORTB.4 = 0;

  //Set up SPI Control Registers
  //Bit 7 - Interrupt Enable SPIE=0 -> no ISR
  //Bit 6 - SPI Enable SPE=1 -> enable spi
  //Bit 5 - Data Order DORD=0 -> msb first
  //Bit 4 - Master/Slave Select MSTR=1 ->MCU is SPI master
  //Bit 3 - Clock Polarity CPLO=0 (for the transceiver initially)
  //Bit 2 - Clock Phase CPHA=0 (for the transceiver initially)
  //Bits 1:0 - SPR1, SPR0: SPI Clock Rate Select 1 and 0
  //SPR1:SPR0=00 along with SPI2X=1 sets SCK to f_osc/2 = 8MHz/2 = 4MHz
  SPCR0 = 0b01010000;  //SPI Control Register
  SPSR0 = 1;           //SPI Status Register (SPI2X)

}

/****************************************************************************/
void set_transceiver_clock(void) {
  //Set the clock polarity and phase for the transceiver if other slaves
  //(with different clock settings) are also being used by the MCU
  SPCR0 = 0b01010000;
  SPSR0 = 1;
  //SPCR0 &= 0b11110111;  //Bit 3 – Clock Polarity CPLO=0
  //SPCR0 &= 0b11111011;  //Bit 2 – Clock Phase CPHA=0
}

/****************************************************************************/
void RF_init_spi(void) {
  //Set up GPIO data directions

⌨️ 快捷键说明

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