cc2500的底层驱动 C程序 而且可移植:
全部源码下载:
Desktop.zip
(13.7 KB, 下载次数: 79)
单片机主程序预览:
- #include "CC2500.h" // CC2500无线数传模块驱动头文件
- #define C25_Pin_CSn(x) PORTB_PB5 = x // 芯片选择 (MCU output)
- #define C25_Pin_SCLK(x) PORTB_PB1 = x // 时钟输入 (MCU output)
- #define C25_Pin_SI(x) PORTB_PB0 = x // 数据输入 (MCU output)
- #define C25_Pin_SO PORTB_PB2 // 数据输出 (MCU input)
- #define C25_Pin_GDO0 PORTB_PB4 // 通用输出 (MCU input)
- //#define C25_Pin_GDO2 PORTB_PJ6 // 通用输入 (MCU input)
- byte C25_Send_Buff[C25_Buff_Len]={1,2,3,4,5,6,7,8,9,10};// 发送数据缓冲区
- byte C25_Rece_Buff[C25_Buff_Len]={0}; // 接收数据缓冲区
- byte flag_send_ok = 0; //发送完成标志位 0完成 1正在发送
- // 函数: C25_Soft_Dly()
- // 描述: 软件延时 10us
- // 参数: 无
- void C25_Soft_Dly(int ms)
- {
- int ii,jj;
- if (ms<1) ms=1;
- for(ii=0;ii<ms;ii++)
- for(jj=0;jj<200;jj++); //K60默认频率for(jj=0;jj<160;jj++);
- }
- // 函数: C25_SPI_WR_Byte()
- // 描述: 通过SPI写一个byte到CC2500,同时从CC2500读取一个Byte
- // 参数: byte 待写入字节数据
- // return 读取到的字节数据
- byte C25_SPI_WR_Byte(byte temp)
- {
- byte j;
- for(j=0; j<8; j++) // 循环8次
- {
- C25_Pin_SI((temp & 0x80)>>7); // 将byte最高位输出到SI
- temp <<= 1; // 低一位移位到最高位
- C25_Pin_SCLK(1); // 拉高SLCK,CC2500从SI读入1位数据,同时CC2500从SO输出1位数据
- temp |= C25_Pin_SO; // 读SO到byte最低位
- C25_Pin_SCLK(0); // SCLK置低
- }
- return(temp); // 返回读取的1Byte数据
- }
- // 函数: C25_SPI_W_Cmd_Strobes()
- // 描述: 向芯片中写入指令控制字
- // 参数: cmd 待写入的指令控制字
- void C25_SPI_W_Cmd_Strobes(byte cmd)
- {
- C25_Pin_CSn(0); // CSn置低,开始数据传输过程
- (void)C25_SPI_WR_Byte(C25_RW_WRITE_SINGLE | cmd); // 写入指令控制字
- C25_Pin_CSn(1); // CSn置高,结束数据传输过程
- }
- // 函数: C25_SPI_W_Reg_Single()
- // 描述: 向1个寄存器中写入数据,同时读取状态字
- // 参数: addr 待写入的寄存器地址
- // value 待写入的字节数据
- // return 读取到状态字
- byte C25_SPI_W_Reg_Single(byte addr,byte value)
- {
- byte status;
- C25_Pin_CSn(0); // CSn置低,开始数据传输过程
- (void)C25_SPI_WR_Byte(C25_RW_WRITE_SINGLE | addr); // 写入寄存器地址及读写控制
- status = C25_SPI_WR_Byte(value); // 写入寄存器数值,并读取状态字
- C25_Pin_CSn(1); // CSn置高,结束数据传输过程
- return(status); // 返回状态字
- }
- // 函数: C25_SPI_W_Reg_Burst()
- // 描述: 向寄存器中写入多个数据
- // 参数: addr 待写入的寄存器首地址
- // *p 待写入的数据首地址
- // num 待写入的数据长度
- void C25_SPI_W_Reg_Burst(byte addr,byte num,byte *p)
- {
- byte j;
- C25_Pin_CSn(0); // CSn置低,开始数据传输过程
- (void)C25_SPI_WR_Byte(C25_RW_WRITE_BURST | addr); // 写入寄存器地址及读写控制(多字节)
- for(j=0; j<num; j++)
- {
- (void)C25_SPI_WR_Byte(p[j]); // 写入寄存器数值
- }
- C25_Pin_CSn(1); // CSn置高,结束数据传输过程
- }
- // 函数: C25_SPI_R_Reg_Burst()
- // 描述: 从寄存器中读取多个数据
- // 参数: addr 待读取的寄存器首地址
- // *p 待读取的寄存器数据存放首地址
- // num 待读取的数据长度
- void C25_SPI_R_Reg_Burst(byte addr,byte num,byte *p)
- {
- byte j;
- C25_Pin_CSn(0); // CSn置低,开始数据传输过程
- (void)C25_SPI_WR_Byte(C25_RW_READ_BURST | addr); // 写入寄存器地址及读写控制(多字节)
- for(j=0; j<num; j++)
- {
- p[j]=C25_SPI_WR_Byte(0); // 读取寄存器数值
- }
- C25_Pin_CSn(1); // CSn置高,结束数据传输过程
- }
- // 函数: C25_Power_ON_Reset()
- // 描述: CC2500芯片上电后的复位
- // 参数: 无
- void C25_Power_ON_Reset(void)
- {
- long delay_num = 0;
- DDRB = 0X23; //输入输出方向
- PUCR_PUPBE = 0xff; //端口上拉
- PORTB = 0X00; //端口初始化
- C25_Pin_SCLK(0); // SCLK置低
- C25_Pin_SI(0); // SI置低
- C25_Pin_CSn(1); // CSN置高
- C25_Soft_Dly(1); // 延时
- C25_Pin_CSn(0); // CSn置低
- C25_Soft_Dly(1); // 延时
- C25_Pin_CSn(1); // CSn置高
- C25_Soft_Dly(50); // 保持CSn为高至少40uS
- C25_Pin_CSn(0); // CSn置低
- delay_num = 0;
- //等待时间过长强制跳出 以免卡死程序
- while(C25_Pin_SO==1 && delay_num<500000) delay_num++; // 等待SO置低(CHIP_RDYn)
- (void)C25_SPI_WR_Byte(C25_RW_WRITE_SINGLE | C25_CS_SRES); // 写入芯片复位指令字
- delay_num = 0;
- //等待时间过长强制跳出 以免卡死程序
- while(C25_Pin_SO==1 && delay_num<500000) delay_num++; // 等待SO再置低,复位完成,此时芯片处于IDLE状态
- C25_Pin_CSn(1); // CSn置高,结束复位过程
- }
- // 函数: C25_Reg_Config()
- // 描述: CC2500寄存器设置
- // 工作频率: 2400.0MHz (基频:2400.0MHz, 通道:0, 通道间隔:200kHz)
- // 调制模式: GFSK
- // 数据速率: 2.4kbps
- // 发射功率: +1dBm
- // 数据包 : 固定长度
- // CRC校验 : 开启
- // 数据白化: 开启
- // 曼切斯特: 关闭
- // FEC : 关闭
- void C25_Reg_Config(void)
- {
- (void)C25_SPI_W_Reg_Single(C25_RA_IOCFG2, C25_CR_IOCFGx_INV_DI // GDO2:不反转输出电平
- | C25_CR_IOCFGx_SYNC_WORD); // GDO2:发送/接收到同步字时置位,并在数据包的末尾取消置位
- (void)C25_SPI_W_Reg_Single(C25_RA_IOCFG0, C25_CR_IOCFG0_TEMP_SENS_DI // GDO0:禁用模拟温度传感器
- | C25_CR_IOCFGx_INV_DI // GDO0:不反转输出电平
- | C25_CR_IOCFGx_ABOVE_RX_FIFO_THR_END); // GDO0:达到或超出RX_FIFO阈值 填充RX_FIFO时置位,或到达数据包结尾时置位.
- (void)C25_SPI_W_Reg_Single(C25_RA_FIFOTHR, C25_CR_FIFOTHR_TX_1_RX_64); // 设置TX_FIFO和RX_FIFO阀值(TX:1,RX:64)
- (void)C25_SPI_W_Reg_Single(C25_RA_SYNC1, C25_CR_SYNC1); // 同步字高位(默认0xD3=11010011)
- (void)C25_SPI_W_Reg_Single(C25_RA_SYNC0, C25_CR_SYNC0); // 同步字低位
- (void)C25_SPI_W_Reg_Single(C25_RA_PKTLEN, C25_Buff_Len); // 固定长度数据包时为数据包长度;可变长度数据包时为允许的最大数据包长度
- (void)C25_SPI_W_Reg_Single(C25_RA_PKTCTRL1, C25_CR_PKTCTRL1_PQT // 前导质量评估门限(默认值0)(等于0时同步字总能被接收)
- | C25_CR_PKTCTRL1_CRC_AUTOFLUSH_EN // 当接收数据CRC校验失败时,自动清空RX_FIFO
- | C25_CR_PKTCTRL1_APPEND_STATUS_EN // 在有效负载上添加状态字
- | C25_CR_PKTCTRL1_ADR_CHK_DI); // 不检查地址
- (void)C25_SPI_W_Reg_Single(C25_RA_PKTCTRL0, C25_CR_PKTCTRL0_WHITE_DATA_EN // 开启数据白化
- | C25_CR_PKTCTRL0_NORMAL_MODE // 普通模式,使用FIFO
- | C25_CR_PKTCTRL0_CRC_EN // 开启CRC校验
- | C25_CR_PKTCTRL0_PTKLEN_FIXED); // 固定数据包长度模式,在PKTLEN寄存器中配置长度数据
- (void)C25_SPI_W_Reg_Single(C25_RA_ADDR, C25_CR_ADDR); // 数据包过滤时使用的地址.可选广播地址为0x00和0xFF
- (void)C25_SPI_W_Reg_Single(C25_RA_FSCTRL1, C25_CR_FSCTRL1_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_FSCTRL0, C25_CR_FSCTRL0); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_FREQ2, C25_CR_FREQ2_2400MHz); // 基频为2400MHz时的FREQ2寄存器值
- (void)C25_SPI_W_Reg_Single(C25_RA_FREQ1, C25_CR_FREQ1_2400MHz); // 基频为2400MHz时的FREQ1寄存器值
- (void)C25_SPI_W_Reg_Single(C25_RA_FREQ0, C25_CR_FREQ0_2400MHz); // 基频为2400MHz时的FREQ0寄存器值
- (void)C25_SPI_W_Reg_Single(C25_RA_MDMCFG4, C25_CR_MDMCFG4_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_MDMCFG3, C25_CR_MDMCFG3_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_MDMCFG2, C25_CR_MDMCFG2_DEM_DCFILT_OFF_EN // 在解调前禁用数字DC阻断滤波器,使能(更佳的灵敏度)
- | C25_CR_MDMCFG2_MOD_FORMAT_2FSK // 2FSK
- | C25_CR_MDMCFG2_MANCHESTER_DI // 禁用曼切斯特编码/解码
- | C25_CR_MDMCFG2_30_32_B_SYNC); // 检测30/32同步字bit
- (void)C25_SPI_W_Reg_Single(C25_RA_MDMCFG1, C25_CR_MDMCFG1_FEC_DI // 禁用交错向前纠错
- | C25_CR_MDMCFG1_NUM_PREAMBLE_4BYTE // 最小前导4Byte
- | C25_CR_MDMCFG1_CHANSPC_E); // 通道间隔的2bit指数
- (void)C25_SPI_W_Reg_Single(C25_RA_MDMCFG0, C25_CR_MDMCFG0_CHANSPC_M); // 通道间隔的8bit尾数
- (void)C25_SPI_W_Reg_Single(C25_RA_DEVIANT, C25_CR_DEVIANT_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_MCSM2, C25_CR_MCSM2_RX_TIME_RSSI_DI // 不使用RSSI测量执行RX终止
- | C25_CR_MCSM2_RX_TIME_QUAL_SYNC // 在RX_TIME定时器超时时,芯片检查是否找到同步字
- | C25_CR_MCSM2_RX_TIME); // 在WOR模式和标准RX运行时,RX中的同步字搜索时限
- (void)C25_SPI_W_Reg_Single(C25_RA_MCSM1, C25_CR_MCSM1_CCA_MODE_RB_UCRPKT // 如果RSSI在阀值之下且除当前接收数据包外,清空通道指示
- | C25_CR_MCSM1_RXOFF_MODE_RX // 数据包接收完成后保持RX状态
- | C25_CR_MCSM1_TXOFF_MODE_RX); // 数据包发送完成后进入RX状态
- (void)C25_SPI_W_Reg_Single(C25_RA_MCSM0, C25_CR_MCSM0_FS_AUTOCAL_IDLE_RTX // 从IDLE转到RX,TX,FSTXON时进行自动校准
- | C25_CR_MCSM0_PO_TIMEOUT_EC_64 // 终止计数次数64
- | C25_CR_MCSM0_PIN_CTRL_DI // 禁用由引脚直接进行的无线状态控制
- | C25_CR_MCSM0_XOSC_FORCE_ON_DI); // XOSC在SLEEP状态下关闭
- (void)C25_SPI_W_Reg_Single(C25_RA_FOCCFG, C25_CR_FOCCFG_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_BSCFG, C25_CR_BSCFG_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_AGCCTRL2, C25_CR_AGCCTRL2_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_AGCCTRL1, C25_CR_AGCCTRL1_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_AGCCTRL0, C25_CR_AGCCTRL0_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_WOREVT1, C25_CR_WOREVT1_EVENT0_HBYTE); // 事件0超时时间高位
- (void)C25_SPI_W_Reg_Single(C25_RA_WOREVT0, C25_CR_WOREVT0_EVENT0_LBYTE); // 事件0超时时间低位
- (void)C25_SPI_W_Reg_Single(C25_RA_WORCTRL, C25_CR_WORCTRL_RC_PD_EN // 向RC振荡器发送掉电信号
- | C25_CR_WORCTRL_EVENT1_48 // 约1.333~1.385ms
- | C25_CR_WORCTRL_RC_CAL_EN // 开启RC振荡器校准
- | C25_CR_WORCTRL_WOR_RES_1P); // 精度1周期,最大时限1.8~1.9秒
- (void)C25_SPI_W_Reg_Single(C25_RA_FREND1, C25_CR_FREND1_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_FREND0, C25_CR_FREND0_LODIV_BUF_CURRENT_TX// 调节当前TX LO缓冲器(PA的输入)
- | C25_CR_FREND0_PA_POWER_0); // 选择PA功率设置
- (void)C25_SPI_W_Reg_Single(C25_RA_FSCAL3, C25_CR_FSCAL3_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_FSCAL2, C25_CR_FSCAL2); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_FSCAL1, C25_CR_FSCAL1_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_FSCAL0, C25_CR_FSCAL0_500KBPS); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_RCCTRL1, C25_CR_RCCTRL1); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_RCCTRL0, C25_CR_RCCTRL0); // 建议使用SmartRF Studio进行计算
- (void)C25_SPI_W_Reg_Single(C25_RA_PATABLE, C25_PS_PATABLE_1dBm); // 写入PATABLE(+1.5dBm,21.4mA)
- C25_SPI_W_Cmd_Strobes(C25_CS_SRX); // 开启RX
- }
- // 函数: C25_Send_Packet()
- // 描述: 通过CC2500发送数据包,发送完成后返回接收状态
- // 参数: *p 待发送数据的首地址
- void C25_Send_Packet(byte *p)
- {
- Cpu_DisableInt();
- if(!flag_send_ok)//检测是否正在发送 //中断使用
- {
- C25_SPI_W_Cmd_Strobes(C25_CS_SIDLE); // 进入IDLE空闲模式
- C25_SPI_W_Cmd_Strobes(C25_CS_SFTX); // 清空TX_FIFO
- C25_SPI_W_Reg_Burst(C25_RA_TXFIFO, C25_Buff_Len, p); // 将数据写入TX_FIFO寄存器
- C25_SPI_W_Cmd_Strobes(C25_CS_STX); // 开启TX
- //flag_send_ok = 1; // 数据发射准备就绪标志位
- //while(C25_Pin_GDO2 == 0); // 等待发送结束 //中断触发时注释这两句
- //while(C25_Pin_GDO2 == 1); // 等待发送结束 //中断触发时注释这两句
- }
- Cpu_EnableInt();
- }
- // 函数: C25_Rece_Packet()
- // 描述: 检查CC2500是否接收到数据;有接收时将数据返回至接收缓存区
- // 参数: *p 接收数据存放地址
- // return 接收成功标志,为1时表明数据接收成功
- byte C25_Rece_Packet(byte *p)
- {
- if(C25_Pin_GDO0==1) // 检查接收数据包是否完成
- {
- C25_SPI_R_Reg_Burst(C25_RA_RXFIFO, C25_Buff_Len+2, p); // 读取RX_FIFO及附加状态字
- C25_SPI_W_Cmd_Strobes(C25_CS_SIDLE); // 进入IDLE空闲模式
- C25_SPI_W_Cmd_Strobes(C25_CS_SFRX); // 清空RX_FIFO
- C25_SPI_W_Cmd_Strobes(C25_CS_SRX); // 重新开启RX
- return 1;
- }
- return 0; // 返回接收失败标志
- }
- // 函数: C25_Get_RX_dBm()
- // 描述: 在完成数据接收后,获取接收功率
- // 参数: rssi 接收信号强度指示
- // return 接收功率
- char C25_Get_RX_dBm(byte rssi)
- {
- char t=rssi;
- if(rssi>=128){t-=255;} // 取绝对值
- return(t/2-71); // 计算RSSI值
- }
复制代码
|