找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7838|回复: 8
打印 上一主题 下一主题
收起左侧

驱动cc2500底层 C程序 可移植

[复制链接]
跳转到指定楼层
楼主
cc2500的底层驱动 C程序 而且可移植:

全部源码下载:
Desktop.zip (13.7 KB, 下载次数: 79)

单片机主程序预览:

  1. #include "CC2500.h"                                        // CC2500无线数传模块驱动头文件

  2. #define C25_Pin_CSn(x)      PORTB_PB5 = x                 // 芯片选择  (MCU output)
  3. #define C25_Pin_SCLK(x)     PORTB_PB1 = x                 // 时钟输入  (MCU output)
  4. #define C25_Pin_SI(x)       PORTB_PB0 = x                 // 数据输入  (MCU output)
  5. #define C25_Pin_SO          PORTB_PB2                     // 数据输出  (MCU input)
  6. #define C25_Pin_GDO0        PORTB_PB4                     // 通用输出  (MCU input)
  7. //#define C25_Pin_GDO2        PORTB_PJ6                     // 通用输入  (MCU input)



  8. byte   C25_Send_Buff[C25_Buff_Len]={1,2,3,4,5,6,7,8,9,10};// 发送数据缓冲区
  9. byte   C25_Rece_Buff[C25_Buff_Len]={0};                   // 接收数据缓冲区
  10. byte   flag_send_ok = 0;                                //发送完成标志位 0完成  1正在发送

  11. // 函数: C25_Soft_Dly()
  12. // 描述: 软件延时  10us
  13. // 参数: 无
  14. void C25_Soft_Dly(int ms)            
  15. {
  16.     int ii,jj;
  17.     if (ms<1) ms=1;
  18.     for(ii=0;ii<ms;ii++)
  19.         for(jj=0;jj<200;jj++);    //K60默认频率for(jj=0;jj<160;jj++);
  20. }

  21. // 函数: C25_SPI_WR_Byte()
  22. // 描述: 通过SPI写一个byte到CC2500,同时从CC2500读取一个Byte
  23. // 参数: byte         待写入字节数据
  24. //                 return 读取到的字节数据
  25. byte C25_SPI_WR_Byte(byte temp)
  26. {
  27.     byte j;
  28.     for(j=0; j<8; j++)                                   // 循环8次
  29.     {                                 
  30.         C25_Pin_SI((temp & 0x80)>>7);                    // 将byte最高位输出到SI
  31.         temp <<= 1;                                                    // 低一位移位到最高位
  32.         C25_Pin_SCLK(1);                                 // 拉高SLCK,CC2500从SI读入1位数据,同时CC2500从SO输出1位数据
  33.         temp |= C25_Pin_SO;                              // 读SO到byte最低位
  34.         C25_Pin_SCLK(0);                                 // SCLK置低
  35.     }
  36.     return(temp);                                              // 返回读取的1Byte数据
  37. }

  38. // 函数: C25_SPI_W_Cmd_Strobes()
  39. // 描述: 向芯片中写入指令控制字
  40. // 参数: cmd   待写入的指令控制字
  41. void C25_SPI_W_Cmd_Strobes(byte cmd)
  42. {
  43.     C25_Pin_CSn(0);                                            // CSn置低,开始数据传输过程
  44.     (void)C25_SPI_WR_Byte(C25_RW_WRITE_SINGLE | cmd);    // 写入指令控制字
  45.     C25_Pin_CSn(1);                                      // CSn置高,结束数据传输过程
  46. }

  47. // 函数: C25_SPI_W_Reg_Single()
  48. // 描述: 向1个寄存器中写入数据,同时读取状态字
  49. // 参数: addr   待写入的寄存器地址
  50. //       value         待写入的字节数据
  51. //                 return 读取到状态字
  52. byte C25_SPI_W_Reg_Single(byte addr,byte value)
  53. {
  54.     byte status;
  55.     C25_Pin_CSn(0);                                            // CSn置低,开始数据传输过程
  56.     (void)C25_SPI_WR_Byte(C25_RW_WRITE_SINGLE | addr);   // 写入寄存器地址及读写控制
  57.     status = C25_SPI_WR_Byte(value);                     // 写入寄存器数值,并读取状态字
  58.     C25_Pin_CSn(1);                                      // CSn置高,结束数据传输过程
  59.     return(status);                                      // 返回状态字
  60. }

  61. // 函数: C25_SPI_W_Reg_Burst()
  62. // 描述: 向寄存器中写入多个数据
  63. // 参数: addr   待写入的寄存器首地址
  64. //       *p         待写入的数据首地址
  65. //                 num    待写入的数据长度
  66. void C25_SPI_W_Reg_Burst(byte addr,byte num,byte *p)
  67. {
  68.     byte j;
  69.     C25_Pin_CSn(0);                                      // CSn置低,开始数据传输过程
  70.     (void)C25_SPI_WR_Byte(C25_RW_WRITE_BURST | addr);    // 写入寄存器地址及读写控制(多字节)
  71.     for(j=0; j<num; j++)
  72.     {
  73.     (void)C25_SPI_WR_Byte(p[j]);                         // 写入寄存器数值
  74.     }
  75.     C25_Pin_CSn(1);                                      // CSn置高,结束数据传输过程
  76. }

  77. // 函数: C25_SPI_R_Reg_Burst()
  78. // 描述: 从寄存器中读取多个数据
  79. // 参数: addr   待读取的寄存器首地址
  80. //       *p         待读取的寄存器数据存放首地址
  81. //                 num    待读取的数据长度
  82. void C25_SPI_R_Reg_Burst(byte addr,byte num,byte *p)
  83. {
  84.     byte j;
  85.     C25_Pin_CSn(0);                                      // CSn置低,开始数据传输过程
  86.     (void)C25_SPI_WR_Byte(C25_RW_READ_BURST | addr);     // 写入寄存器地址及读写控制(多字节)
  87.     for(j=0; j<num; j++)
  88.     {
  89.         p[j]=C25_SPI_WR_Byte(0);                         // 读取寄存器数值
  90.     }
  91.     C25_Pin_CSn(1);                                      // CSn置高,结束数据传输过程
  92. }

  93. // 函数: C25_Power_ON_Reset()
  94. // 描述: CC2500芯片上电后的复位
  95. // 参数: 无
  96. void C25_Power_ON_Reset(void)
  97. {
  98.     long delay_num = 0;
  99.     DDRB = 0X23;                                                //输入输出方向
  100.     PUCR_PUPBE = 0xff;                                             //端口上拉
  101.     PORTB = 0X00;                                               //端口初始化
  102.     C25_Pin_SCLK(0);                                                                                        // SCLK置低
  103.     C25_Pin_SI(0);                                                                                        // SI置低
  104.     C25_Pin_CSn(1);                                             // CSN置高
  105.     C25_Soft_Dly(1);                                            // 延时
  106.     C25_Pin_CSn(0);                                              // CSn置低
  107.     C25_Soft_Dly(1);                                            // 延时
  108.     C25_Pin_CSn(1);                                             // CSn置高
  109.     C25_Soft_Dly(50);                                           // 保持CSn为高至少40uS
  110.     C25_Pin_CSn(0);                                             // CSn置低
  111.     delay_num = 0;
  112.                                                                 //等待时间过长强制跳出 以免卡死程序
  113.     while(C25_Pin_SO==1 && delay_num<500000)    delay_num++;    // 等待SO置低(CHIP_RDYn)
  114.     (void)C25_SPI_WR_Byte(C25_RW_WRITE_SINGLE | C25_CS_SRES);   // 写入芯片复位指令字
  115.     delay_num = 0;
  116.                                                                 //等待时间过长强制跳出 以免卡死程序
  117.     while(C25_Pin_SO==1 && delay_num<500000)    delay_num++;    // 等待SO再置低,复位完成,此时芯片处于IDLE状态
  118.     C25_Pin_CSn(1);                                             // CSn置高,结束复位过程
  119. }

  120. // 函数: C25_Reg_Config()
  121. // 描述: CC2500寄存器设置
  122. //       工作频率: 2400.0MHz (基频:2400.0MHz, 通道:0, 通道间隔:200kHz)
  123. //       调制模式: GFSK
  124. //       数据速率: 2.4kbps
  125. //       发射功率: +1dBm
  126. //       数据包  : 固定长度
  127. //       CRC校验 : 开启
  128. //       数据白化: 开启
  129. //       曼切斯特: 关闭
  130. //       FEC     : 关闭
  131. void C25_Reg_Config(void)
  132. {
  133.     (void)C25_SPI_W_Reg_Single(C25_RA_IOCFG2,     C25_CR_IOCFGx_INV_DI              // GDO2:不反转输出电平
  134.                                           | C25_CR_IOCFGx_SYNC_WORD);               // GDO2:发送/接收到同步字时置位,并在数据包的末尾取消置位
  135.     (void)C25_SPI_W_Reg_Single(C25_RA_IOCFG0,     C25_CR_IOCFG0_TEMP_SENS_DI        // GDO0:禁用模拟温度传感器
  136.                                           | C25_CR_IOCFGx_INV_DI                    // GDO0:不反转输出电平
  137.                                           | C25_CR_IOCFGx_ABOVE_RX_FIFO_THR_END);   // GDO0:达到或超出RX_FIFO阈值 填充RX_FIFO时置位,或到达数据包结尾时置位.
  138.     (void)C25_SPI_W_Reg_Single(C25_RA_FIFOTHR,    C25_CR_FIFOTHR_TX_1_RX_64);       // 设置TX_FIFO和RX_FIFO阀值(TX:1,RX:64)
  139.     (void)C25_SPI_W_Reg_Single(C25_RA_SYNC1,      C25_CR_SYNC1);                    // 同步字高位(默认0xD3=11010011)
  140.     (void)C25_SPI_W_Reg_Single(C25_RA_SYNC0,      C25_CR_SYNC0);                    // 同步字低位
  141.     (void)C25_SPI_W_Reg_Single(C25_RA_PKTLEN,     C25_Buff_Len);                    // 固定长度数据包时为数据包长度;可变长度数据包时为允许的最大数据包长度
  142.     (void)C25_SPI_W_Reg_Single(C25_RA_PKTCTRL1,   C25_CR_PKTCTRL1_PQT               // 前导质量评估门限(默认值0)(等于0时同步字总能被接收)
  143.                                           | C25_CR_PKTCTRL1_CRC_AUTOFLUSH_EN        // 当接收数据CRC校验失败时,自动清空RX_FIFO
  144.                                           | C25_CR_PKTCTRL1_APPEND_STATUS_EN        // 在有效负载上添加状态字
  145.                                           | C25_CR_PKTCTRL1_ADR_CHK_DI);            // 不检查地址
  146.     (void)C25_SPI_W_Reg_Single(C25_RA_PKTCTRL0,   C25_CR_PKTCTRL0_WHITE_DATA_EN     // 开启数据白化
  147.                                           | C25_CR_PKTCTRL0_NORMAL_MODE             // 普通模式,使用FIFO
  148.                                           | C25_CR_PKTCTRL0_CRC_EN                  // 开启CRC校验
  149.                                           | C25_CR_PKTCTRL0_PTKLEN_FIXED);          // 固定数据包长度模式,在PKTLEN寄存器中配置长度数据
  150.     (void)C25_SPI_W_Reg_Single(C25_RA_ADDR,       C25_CR_ADDR);                     // 数据包过滤时使用的地址.可选广播地址为0x00和0xFF
  151.     (void)C25_SPI_W_Reg_Single(C25_RA_FSCTRL1,    C25_CR_FSCTRL1_500KBPS);          // 建议使用SmartRF Studio进行计算
  152.     (void)C25_SPI_W_Reg_Single(C25_RA_FSCTRL0,    C25_CR_FSCTRL0);                  // 建议使用SmartRF Studio进行计算
  153.     (void)C25_SPI_W_Reg_Single(C25_RA_FREQ2,      C25_CR_FREQ2_2400MHz);            // 基频为2400MHz时的FREQ2寄存器值
  154.     (void)C25_SPI_W_Reg_Single(C25_RA_FREQ1,      C25_CR_FREQ1_2400MHz);            // 基频为2400MHz时的FREQ1寄存器值
  155.     (void)C25_SPI_W_Reg_Single(C25_RA_FREQ0,      C25_CR_FREQ0_2400MHz);            // 基频为2400MHz时的FREQ0寄存器值
  156.     (void)C25_SPI_W_Reg_Single(C25_RA_MDMCFG4,    C25_CR_MDMCFG4_500KBPS);          // 建议使用SmartRF Studio进行计算
  157.     (void)C25_SPI_W_Reg_Single(C25_RA_MDMCFG3,    C25_CR_MDMCFG3_500KBPS);          // 建议使用SmartRF Studio进行计算
  158.     (void)C25_SPI_W_Reg_Single(C25_RA_MDMCFG2,    C25_CR_MDMCFG2_DEM_DCFILT_OFF_EN  // 在解调前禁用数字DC阻断滤波器,使能(更佳的灵敏度)
  159.                                           | C25_CR_MDMCFG2_MOD_FORMAT_2FSK          // 2FSK
  160.                                           | C25_CR_MDMCFG2_MANCHESTER_DI            // 禁用曼切斯特编码/解码
  161.                                           | C25_CR_MDMCFG2_30_32_B_SYNC);           // 检测30/32同步字bit
  162.     (void)C25_SPI_W_Reg_Single(C25_RA_MDMCFG1,    C25_CR_MDMCFG1_FEC_DI             // 禁用交错向前纠错
  163.                                           | C25_CR_MDMCFG1_NUM_PREAMBLE_4BYTE       // 最小前导4Byte
  164.                                           | C25_CR_MDMCFG1_CHANSPC_E);              // 通道间隔的2bit指数
  165.     (void)C25_SPI_W_Reg_Single(C25_RA_MDMCFG0,    C25_CR_MDMCFG0_CHANSPC_M);        // 通道间隔的8bit尾数
  166.     (void)C25_SPI_W_Reg_Single(C25_RA_DEVIANT,    C25_CR_DEVIANT_500KBPS);          // 建议使用SmartRF Studio进行计算
  167.     (void)C25_SPI_W_Reg_Single(C25_RA_MCSM2,      C25_CR_MCSM2_RX_TIME_RSSI_DI      // 不使用RSSI测量执行RX终止
  168.                                           | C25_CR_MCSM2_RX_TIME_QUAL_SYNC          // 在RX_TIME定时器超时时,芯片检查是否找到同步字
  169.                                           | C25_CR_MCSM2_RX_TIME);                  // 在WOR模式和标准RX运行时,RX中的同步字搜索时限
  170.     (void)C25_SPI_W_Reg_Single(C25_RA_MCSM1,      C25_CR_MCSM1_CCA_MODE_RB_UCRPKT   // 如果RSSI在阀值之下且除当前接收数据包外,清空通道指示
  171.                                           | C25_CR_MCSM1_RXOFF_MODE_RX              // 数据包接收完成后保持RX状态
  172.                                           | C25_CR_MCSM1_TXOFF_MODE_RX);            // 数据包发送完成后进入RX状态
  173.     (void)C25_SPI_W_Reg_Single(C25_RA_MCSM0,      C25_CR_MCSM0_FS_AUTOCAL_IDLE_RTX  // 从IDLE转到RX,TX,FSTXON时进行自动校准
  174.                                           | C25_CR_MCSM0_PO_TIMEOUT_EC_64           // 终止计数次数64
  175.                                           | C25_CR_MCSM0_PIN_CTRL_DI                // 禁用由引脚直接进行的无线状态控制
  176.                                           | C25_CR_MCSM0_XOSC_FORCE_ON_DI);         // XOSC在SLEEP状态下关闭
  177.     (void)C25_SPI_W_Reg_Single(C25_RA_FOCCFG,     C25_CR_FOCCFG_500KBPS);           // 建议使用SmartRF Studio进行计算
  178.     (void)C25_SPI_W_Reg_Single(C25_RA_BSCFG,      C25_CR_BSCFG_500KBPS);            // 建议使用SmartRF Studio进行计算
  179.     (void)C25_SPI_W_Reg_Single(C25_RA_AGCCTRL2,   C25_CR_AGCCTRL2_500KBPS);         // 建议使用SmartRF Studio进行计算
  180.     (void)C25_SPI_W_Reg_Single(C25_RA_AGCCTRL1,   C25_CR_AGCCTRL1_500KBPS);         // 建议使用SmartRF Studio进行计算
  181.     (void)C25_SPI_W_Reg_Single(C25_RA_AGCCTRL0,   C25_CR_AGCCTRL0_500KBPS);         // 建议使用SmartRF Studio进行计算
  182.     (void)C25_SPI_W_Reg_Single(C25_RA_WOREVT1,    C25_CR_WOREVT1_EVENT0_HBYTE);     // 事件0超时时间高位
  183.     (void)C25_SPI_W_Reg_Single(C25_RA_WOREVT0,    C25_CR_WOREVT0_EVENT0_LBYTE);     // 事件0超时时间低位
  184.     (void)C25_SPI_W_Reg_Single(C25_RA_WORCTRL,    C25_CR_WORCTRL_RC_PD_EN           // 向RC振荡器发送掉电信号
  185.                                           | C25_CR_WORCTRL_EVENT1_48                // 约1.333~1.385ms
  186.                                           | C25_CR_WORCTRL_RC_CAL_EN                // 开启RC振荡器校准
  187.                                           | C25_CR_WORCTRL_WOR_RES_1P);             // 精度1周期,最大时限1.8~1.9秒
  188.     (void)C25_SPI_W_Reg_Single(C25_RA_FREND1,     C25_CR_FREND1_500KBPS);           // 建议使用SmartRF Studio进行计算
  189.     (void)C25_SPI_W_Reg_Single(C25_RA_FREND0,     C25_CR_FREND0_LODIV_BUF_CURRENT_TX// 调节当前TX LO缓冲器(PA的输入)
  190.                                           | C25_CR_FREND0_PA_POWER_0);              // 选择PA功率设置
  191.     (void)C25_SPI_W_Reg_Single(C25_RA_FSCAL3,     C25_CR_FSCAL3_500KBPS);           // 建议使用SmartRF Studio进行计算
  192.     (void)C25_SPI_W_Reg_Single(C25_RA_FSCAL2,     C25_CR_FSCAL2);                   // 建议使用SmartRF Studio进行计算
  193.     (void)C25_SPI_W_Reg_Single(C25_RA_FSCAL1,     C25_CR_FSCAL1_500KBPS);           // 建议使用SmartRF Studio进行计算
  194.     (void)C25_SPI_W_Reg_Single(C25_RA_FSCAL0,     C25_CR_FSCAL0_500KBPS);           // 建议使用SmartRF Studio进行计算
  195.     (void)C25_SPI_W_Reg_Single(C25_RA_RCCTRL1,    C25_CR_RCCTRL1);                  // 建议使用SmartRF Studio进行计算
  196.     (void)C25_SPI_W_Reg_Single(C25_RA_RCCTRL0,    C25_CR_RCCTRL0);                  // 建议使用SmartRF Studio进行计算
  197.     (void)C25_SPI_W_Reg_Single(C25_RA_PATABLE,    C25_PS_PATABLE_1dBm);             // 写入PATABLE(+1.5dBm,21.4mA)
  198.     C25_SPI_W_Cmd_Strobes(C25_CS_SRX);                                              // 开启RX
  199. }

  200. // 函数: C25_Send_Packet()
  201. // 描述: 通过CC2500发送数据包,发送完成后返回接收状态
  202. // 参数: *p                待发送数据的首地址


  203. void C25_Send_Packet(byte *p)
  204. {
  205.     Cpu_DisableInt();

  206.     if(!flag_send_ok)//检测是否正在发送  //中断使用
  207.     {
  208.     C25_SPI_W_Cmd_Strobes(C25_CS_SIDLE);                                     // 进入IDLE空闲模式
  209.     C25_SPI_W_Cmd_Strobes(C25_CS_SFTX);                                      // 清空TX_FIFO
  210.     C25_SPI_W_Reg_Burst(C25_RA_TXFIFO, C25_Buff_Len, p);        // 将数据写入TX_FIFO寄存器
  211.     C25_SPI_W_Cmd_Strobes(C25_CS_STX);                                      // 开启TX
  212.     //flag_send_ok = 1;                                   // 数据发射准备就绪标志位
  213.     //while(C25_Pin_GDO2 == 0);                                                                                     // 等待发送结束  //中断触发时注释这两句
  214.     //while(C25_Pin_GDO2 == 1);                                                                                                                  // 等待发送结束  //中断触发时注释这两句
  215.     }                                                                 
  216.     Cpu_EnableInt();

  217. }

  218. // 函数: C25_Rece_Packet()
  219. // 描述: 检查CC2500是否接收到数据;有接收时将数据返回至接收缓存区
  220. // 参数: *p                接收数据存放地址
  221. //                 return        接收成功标志,为1时表明数据接收成功
  222. byte C25_Rece_Packet(byte *p)
  223. {
  224.     if(C25_Pin_GDO0==1)                                           // 检查接收数据包是否完成
  225.     {                                                
  226.       C25_SPI_R_Reg_Burst(C25_RA_RXFIFO, C25_Buff_Len+2, p);    // 读取RX_FIFO及附加状态字
  227.       C25_SPI_W_Cmd_Strobes(C25_CS_SIDLE);                                        // 进入IDLE空闲模式
  228.       C25_SPI_W_Cmd_Strobes(C25_CS_SFRX);                                          // 清空RX_FIFO
  229.             C25_SPI_W_Cmd_Strobes(C25_CS_SRX);                                          // 重新开启RX
  230.       return 1;
  231.     }
  232.     return 0;                                                     // 返回接收失败标志
  233. }


  234. // 函数: C25_Get_RX_dBm()
  235. // 描述: 在完成数据接收后,获取接收功率
  236. // 参数: rssi   接收信号强度指示
  237. //                 return        接收功率
  238. char C25_Get_RX_dBm(byte rssi)
  239. {
  240.         char t=rssi;
  241.         if(rssi>=128){t-=255;}                                          // 取绝对值
  242.     return(t/2-71);                                               // 计算RSSI值
  243. }                                                   
复制代码

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:198559 发表于 2017-5-9 11:42 | 只看该作者
学习学习
回复

使用道具 举报

板凳
ID:302326 发表于 2018-4-5 11:53 | 只看该作者
同样也要来学习
回复

使用道具 举报

地板
ID:241128 发表于 2018-5-5 08:51 | 只看该作者
移植后出现这两句是什么意思啊?求楼主解救...
CC2500.h(4): warning C318: can't open file 'Includes.h'
CC2500.h(6): error C129: missing ';' before 'C25_Send_Buff'
回复

使用道具 举报

5#
ID:26275 发表于 2018-6-21 23:01 | 只看该作者
fzhlpp 发表于 2018-5-5 08:51
移植后出现这两句是什么意思啊?求楼主解救...
CC2500.h(4): warning C318: can't open file 'Includes.h' ...

你手里有Includes.h 这个文件吗? 需要放到目录下去,

程序移植过去,还需要针对你自己的电路做一些IO口的修改, 不是直接照搬使用的

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

6#
ID:403593 发表于 2020-3-2 17:39 | 只看该作者
可以用来参考,感谢分享!
回复

使用道具 举报

7#
ID:743449 发表于 2020-5-17 22:13 | 只看该作者
谢谢分享,正在找呢
回复

使用道具 举报

8#
ID:149139 发表于 2021-5-6 09:56 | 只看该作者
非常感谢,正在研究
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表