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;
}
- 意法半导体中国本地造STM32微控制器启动规模量产
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 基于机智云与STM32的智能拐杖安全监测系统在养老物联网中的应用
- 内置全栈安全,一站式满足CRA法案与IEC 62443标准——米尔STM32MP257核心板
- 如何用 STM32 FLASH 实现等效 100 万次擦写的 EEPROM 功能?
- 实战解析:通过一个小项目掌握STM32所有外设
- STM32学了两年半,却还是不会做项目
- 意法半导体推出最新STM32MP21微处理器,兼具高性价比、低功耗、高灵活性
- 基于STM32的矿井作业环境监测系统设计与实现
- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 模组复用与整机重测在SRRC、CCC、CTA/NAL认证中的实践操作指南
- 从控制到系统:TI利用边缘AI重塑嵌入式MCU的边界
- 有源晶振与无源晶振的六大区别详解
- 英飞凌持续巩固全球微控制器市场领导地位
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 蓝牙信道探测技术原理与开发套件实践
- Microchip 推出生产就绪型全栈边缘 AI 解决方案,赋能MCU和MPU实现 智能实时决策
- LoRa、LoRaWAN、NB-IoT与4G DTU技术对比及工业无线方案选型分析




