单片机
返回首页

stm32 驱动2.4g cc2500 无线模块

2020-09-09 来源:eefocus

驱动代码

 

BYTE spi_writebyte(BYTE value)
{
 BYTE i,T;
 
 for(i=8; i; i--)
 { 
  SPI_CLR_CLK();
  SETDATA(value); 

  Delay(3);
  value<<=1;
  SPI_SET_CLK();
  T <<= 1;
  T |= RF_SPI_MISO;
        Delay(1);

 }
 SPI_CLR_CLK();
 return T;
}
/**
*@brief send one byte
**/
void SpiStrobe(value)
{
 SPI_SELECT();
 spi_writebyte(value);
 SPI_DIS_SELECT();
}


/**
*@brief reset cc2500
*@
**/

void POWER_UP_RESET_CCxxx0(void)
{
 WORD i =0 ;

 SpiStrobe(CCxxx0_SIDLE);

 

 Delay(20);

 SPI_SELECT();
// while(1);
 Delay(20);

 SPI_DIS_SELECT();

 Delay(40);

 

 SpiStrobe(CCxxx0_SRES);


 

}


/**
*@brief wirte cc2500 register
*@
*
**/

void cc2500_WriteReg(BYTE addr, BYTE value)
{
 SPI_SELECT();

 addr &= 0x7F;
 spi_writebyte(addr);

 spi_writebyte(value);
 SPI_DIS_SELECT();
}

/**
*@brief read cc2500 register
*@
*
**/


BYTE cc2500_ReadReg(BYTE addr)
{
 BYTE value;

 SPI_SELECT();

 spi_writebyte(addr|0x80);
 value = spi_writebyte(0xff);
    SPI_DIS_SELECT();
 return value;
}

/**
*@brief wirte setting register to cc2500
*@
**/

void cc2500_WriteRfSettings()
{
 
 do{

  cc2500_WriteReg(CCxxx0_FSCTRL1, 0x09); // 0x0c
  cc2500_ReadReg(CCxxx0_FSCTRL1);
  cc2500_WriteReg(CCxxx0_FSCTRL0, 0x00);
  cc2500_WriteReg(CCxxx0_FREQ2, 0x5D);
  cc2500_WriteReg(CCxxx0_FREQ1, 0x93);
  cc2500_WriteReg(CCxxx0_FREQ0, 0xB1);
//#define _10k
#ifdef _10k
  cc2500_WriteReg(CCxxx0_MDMCFG4, 0x78); //0x78-10k   0x86
  cc2500_WriteReg(CCxxx0_MDMCFG3, 0x93); //0x93-10k   0x83
//  halSpiWriteReg(CCxxx0_MDMCFG2, 0x70);
  cc2500_WriteReg(CCxxx0_MDMCFG2, 0x03); //0x03-10k  0x03
  cc2500_WriteReg(CCxxx0_MDMCFG1, 0x22); //0x22-10k  0x22       // 0x22????
  cc2500_WriteReg(CCxxx0_MDMCFG0, 0xF8); //0xf8        0xf8  

#else
  cc2500_WriteReg(CCxxx0_MDMCFG4, 0x2D); //0x78-10k   0x86
  cc2500_WriteReg(CCxxx0_MDMCFG3, 0x3B); //0x93-10k   0x83
//  halSpiWriteReg(CCxxx0_MDMCFG2, 0x70);
  cc2500_WriteReg(CCxxx0_MDMCFG2, 0x73); //0x03-10k  0x03
  cc2500_WriteReg(CCxxx0_MDMCFG1, 0xA2); //0x22-10k  0x22       // 0x22????
  cc2500_WriteReg(CCxxx0_MDMCFG0, 0xF8); //0xf8        0xf8
#endif

  cc2500_WriteReg(CCxxx0_CHANNR, 0x00);
  cc2500_WriteReg(CCxxx0_DEVIATN, 0x01); //0x44       // 00
  cc2500_WriteReg(CCxxx0_FREND1, 0x56);        // 0xB6   56错误机率减少
  cc2500_WriteReg(CCxxx0_FREND0, 0x10);
  cc2500_WriteReg(CCxxx0_MCSM1, 0x00);        // 0X00>NO CCA; 0X30>CCA   ?????
  cc2500_WriteReg(CCxxx0_MCSM0, 0x18);
  cc2500_WriteReg(CCxxx0_FOCCFG, 0x15);        // 0x1D   频率偏移补偿
  cc2500_WriteReg(CCxxx0_BSCFG, 0x6C);        // 0x1c   位同步配置
  cc2500_WriteReg(CCxxx0_AGCCTRL2, 0x07);        // 0xc3    增益控制
  cc2500_WriteReg(CCxxx0_AGCCTRL1, 0x00);        // cca=0x10
  cc2500_WriteReg(CCxxx0_AGCCTRL0, 0x91);        // 0xb2
  cc2500_WriteReg(CCxxx0_FSCAL3, 0xEA);
  cc2500_WriteReg(CCxxx0_FSCAL2, 0x0A);  //0x0a - 250k  0x06 --10k,0x08-2.4k
  cc2500_WriteReg(CCxxx0_FSCAL1, 0x00);        // 增加频率同步校准

  cc2500_WriteReg(CCxxx0_FSCAL0, 0x11);
  cc2500_WriteReg(CCxxx0_FSTEST, 0x59);
  cc2500_WriteReg(CCxxx0_TEST2, 0x8F);        // 0x88
  cc2500_WriteReg(CCxxx0_TEST1, 0x21);        // 0x31
  cc2500_WriteReg(CCxxx0_TEST0, 0x0B);
  cc2500_WriteReg(CCxxx0_IOCFG2, 0x24); //29       // CCA=0x09:1=free   ??????
  cc2500_WriteReg(CCxxx0_IOCFG0, 0x06);        //                  ?????
  cc2500_WriteReg(CCxxx0_PKTCTRL1, 0x00); //04       //                      ??????
  cc2500_WriteReg(CCxxx0_PKTCTRL0, 0x40); //0x41 whiter+val  //crc on 05      //                          ????
  cc2500_WriteReg(CCxxx0_ADDR,  0x01);        //                     ?????
  cc2500_WriteReg(CCxxx0_PKTLEN, 0x05);//                      ??????
      // cc2500_ReadReg(CCxxx0_MDMCFG1);
 }while(cc2500_ReadReg(CCxxx0_FSCAL3) != 0xEA);
}

/**
*@brief read chip id
*@
**/

BYTE cc2500_GetChipId(void)
{
 BYTE id = 0;

 

 SPI_SELECT();
 spi_writebyte(0x30|0xc0);
 id = spi_writebyte(0xff);
 spi_writebyte(0x31|0xc0);
 id = spi_writebyte(0xff);
 SPI_DIS_SELECT();
    return id;
}


/**
*@brief set cc2500 to TX mode
*@
**/

void Set_CCxx00Rxd(void)
{
 SpiStrobe(CCxxx0_SIDLE);

 Delay(2);

 SpiStrobe(CCxxx0_SFRX);

 Delay(2);

 SpiStrobe(CCxxx0_SRX);
}


/**
*@brief setup cc2500
*@
**/
void cc2500_Init(void)
{

 BYTE i = 0;

 
 SPI_SELECT();
 while(RF_SPI_MISO);
 POWER_UP_RESET_CCxxx0();
    cc2500_GetChipId();
 
 cc2500_WriteRfSettings();

 //set pa

 SPI_SELECT();
 spi_writebyte(CCxxx0_PATABLE|0x40);
 for(i=0;i<8;i++)
 {
  spi_writebyte(paTable_CC2500[i]);
 }
 SPI_DIS_SELECT();

 Set_CCxx00Rxd();
}


/**
*@brief  send paket data to cc2500
*@
**/
BYTE cc2500_SendPacket(BYTE *txBuffer, BYTE size)
{
 BYTE i =0;
 
 SpiStrobe(CCxxx0_SIDLE);
 SpiStrobe(CCxxx0_SFTX);//SFRX SFTX只用于IDLE模式 执行后将FIFOs里上溢或下溢的数据清空

             //进入SLEEP模式FIFOs也同样清
// SpiStrobe(SPI1, CCxxx0_TXFIFO_Muti); 
 SPI_SELECT();
 spi_writebyte(CCxxx0_TXFIFO_Muti);
    for(i=0;i    {
     spi_writebyte(txBuffer[i]);

 }

 SPI_DIS_SELECT();

 SpiStrobe(CCxxx0_STX);
 cc2500_ReadStatus(0x3a);
 while(!GDO0);   //wait high
 while(GDO0);    //wait low ,end send
    return 0;
}

 

/**
*@brief read state
*@
**/
BYTE cc2500_ReadStatus(BYTE addr)
{
 BYTE  value;

 SPI_SELECT();
 addr  |= READ_BURST;

 spi_writebyte(addr);
 value = spi_writebyte(0xff);
 
 SPI_DIS_SELECT();

 return value;
}


/**
*@brief receive a paket data form cc2500
*@
**/

BYTE  cc2500_ReceivePacket(BYTE *rxBuffer)
{
    BYTE status;
    BYTE LEN=0,i=0;
 //BYTE n=0,l=0;

    status =1 | (cc2500_ReadStatus(CCxxx0_RXBYTES));          //RX FIFO 等于0 CRC校验失败 如果大于0CRC校验OK数据能读出
    if((status & 0x7F)==0x00)
    {
        status = cc2500_ReadStatus(CCxxx0_MARCSTATE);
        if((status!=0x0D)&&(status!=0x08))    //0x0D为RX状态
        {
         Set_CCxx00Rxd();    //激活(接收或传送)
        }
        return 0;
    }


 //LEN = cc2500_ReadReg(CCxxx0_RXFIFO_one);
    LEN = 0x06;   //采用定长模式
    if(LEN > 0)
    {
     SPI_SELECT();
  if(LEN<=RFTXDBUFFSIZE)
  {
   
   //SpiStrobe(CCxxx0_RXFIFO_Muti);
   SPI_SELECT();
   spi_writebyte(CCxxx0_RXFIFO_Muti);
   for(i=0;i   {
    rxBuffer[i] = spi_writebyte(0xff);
   }
   Set_CCxx00Rxd();
   SPI_DIS_SELECT();
   return LEN;//(status & CRC_OK);
  }
  else
  {
   SpiStrobe(CCxxx0_RXFIFO_Muti);
   for(i=0;i   {
    rxBuffer[i] = spi_writebyte(0xff);
   }

   Set_CCxx00Rxd();
   SPI_DIS_SELECT(); 
   return 0;
  }
  

    }
    else
    {
        Set_CCxx00Rxd();
        return 0;
    }
}


*/
/**
*@brief enter sleep mode,cc2500 strobe SPWD must in idle mode
*@
**/
void cc2500_Enter_Sleep(void)
{
 SpiStrobe(CCxxx0_SIDLE);
 SpiStrobe(CCxxx0_SPWD); 
 
}

/**
*@ brief read RSSI value
*@
**/

BYTE cc2500_ReadRSSIValue(void)
{
 return(cc2500_ReadStatus(0x34));
}

/**
*@brief Initial register for WOR mode
*@
**/
void cc2500_Init_WOR(void)
{
    SpiStrobe(CCxxx0_SIDLE);
    cc2500_WriteReg(CCxxx0_WORCTRL, 0x08); //
    cc2500_WriteReg(CCxxx0_WOREVT1, 0x2b);//43B5 500ms, 28A0 300ms 1B15 200ms
    cc2500_WriteReg(CCxxx0_WOREVT0, 0x15);// 876B 1S
    cc2500_WriteReg(CCxxx0_MCSM2, 0x03);  // RX_TIME // RX_TIME_RSSI= 1  RX_TIME_QUAL = 0
    // 0:12.5%, 1:6.25%, 2:3.125%, 3:1.563%, 4:0.781%
    cc2500_WriteReg(CCxxx0_MCSM0, 0x38);  // 频率校准方式,每4次从IDLE模式到RX模式进行一次频率合成器校准
    SpiStrobe(CCxxx0_SWORRST);
    SpiStrobe(CCxxx0_SWOR);

}

/**
*@brief enter WOR mode
*@
*****/
void cc2500_Enter_WOR(void)
{
  cc2500_Init_WOR();
  SpiStrobe(CCxxx0_SWORRST);
  SpiStrobe(CCxxx0_SWOR);
}

/**
*@brief RF go balk to WOR mode
*@
**/
void cc2500_REnter_WOR(void)
{
  SpiStrobe(CCxxx0_SWORRST);
  SpiStrobe(CCxxx0_SWOR);
}

/**
*@brief get connect
*@
**/
void cc2500_getConnect(void)
{
 BYTE i,j;

 j=0;
 i=0;
 for(i=0;i<64;i++)
 {
  bTempBuf[i] = 0x55;
 }
 bTempBuf[0] = 63;
 bTempBuf[1] = 0x00;
 cc2500_SendPacket(bTempBuf, 64);
  

}

/**
*@brief rf communication
*@
**/
void cc2500_Process()
{
 BYTE i;

#define GDO0_
#ifdef GDO0_
 if(!GDO0)
 {
  return;
 }

 while(GDO0);
#else
    if(!(cc2500_ReadStatus(0x38)&0x01))
    {
     return;
 }
 while((cc2500_ReadStatus(0x38)&0x01));
#endif

    i = cc2500_ReadRSSIValue();
    cc2500_ReceivePacket(bTempBuf);

    Set_CCxx00Rxd();
// cc2500_REnter_WOR();

 
#ifdef RF_DEBUG_
 Uart_SendStr('-');
 Uart_SendStr(bTempBuf);
#endif

}

/**
*@brief rf communication
*@
**/
int mian()
{
 sys_init();     //系统初始化
 cc2500_Init();  //初始化CC2500模块

  //send
  cc2500_SendPacket(bTempBuf, 6);
  //receive
  while(1)
  {
    cc2500_Process();
  }
  return 1;
 }


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 1瓦四级调频发射机

  • 500W MOS场效应管电源逆变器,12V转110V/220V

  • 红外开关

  • LM317过压保护

  • 0-30V/20A 大功率稳压电源(采用LM338)

    相关电子头条文章