[求助] g2553与nrf24l01接收端总能检测到载波

ZJ3024   2016-6-28 20:10 楼主
暑假期间要做一个5发一收的小玩意,因为以前调过51的24l01,决定移植到2553上,改用spi模块做,按教程一步一步调,发送端调完了,接收端出问题了,只有接收端,检测载波,不管哪个信道,全是有载波,把发送端上电,依旧没有接收,但是一直有载波没法调啊,是我家周围2.4G的wifi太多了的原因吗?

回复评论 (1)

我自己上个程序,万一程序的原因呢?
spi24l01.h

  1. #include <msp430.h>



  2. #define NRF24L01DIR                P1DIR
  3. #define NRF24L01REN                P1REN
  4. #define NRF24L01IE                P1IE
  5. #define NRF24L01IES                P1IES
  6. #define NRF24L01IFG                P1IFG
  7. #define MCU2NRF24L01        P1OUT
  8. #define NRF24L012MCU        P1IN

  9. #define CE                BIT5
  10. #define CSN                BIT3
  11. #define IRQ                BIT0

  12. #define                OUTDIR        NRF24L01DIR |= CE + CSN
  13. #define                IRQ_H        MCU2NRF24L01 |= IRQ
  14. #define                IRQ_REN        NRF24L01REN |= IRQ
  15. #define                IRQ_IE        NRF24L01IE |= IRQ
  16. #define                IRQ_IES        NRF24L01IES |= IRQ
  17. #define                IRQ_IFG        NRF24L01IFG         &= ~IRQ
  18. #define                CE_H        MCU2NRF24L01 |= CE
  19. #define                CE_L        MCU2NRF24L01 &= ~CE
  20. #define                CSN_H        MCU2NRF24L01 |= CSN
  21. #define                CSN_L        MCU2NRF24L01 &= ~CSN

  22. /**********  NRF24L01寄存器操作命令  ***********/
  23. #define R_REGISTER      0x00  //读配置寄存器,低5位为寄存器地址
  24. #define W_REGISTER      0x20  //写配置寄存器,低5位为寄存器地址
  25. #define R_RX_PAYLOAD    0x61  //读RX有效数据,1~32字节
  26. #define W_TX_PAYLOAD    0xA0  //写TX有效数据,1~32字节
  27. #define FLUSH_TX        0xE1  //清除TX FIFO寄存器.发射模式下用
  28. #define FLUSH_RX        0xE2  //清除RX FIFO寄存器.接收模式下用
  29. #define REUSE_TX_PL     0xE3  //重新使用上一包数据,CE为高,数据包被不断发送.
  30. #define NOP             0xFF  //空操作,可以用来读状态寄存器

  31. /**********  NRF24L01寄存器地址   *************/
  32. #define CONFIG          0x00  //配置寄存器地址
  33. #define EN_AA           0x01  //使能自动应答功能
  34. #define EN_RXADDR       0x02  //接收地址允许
  35. #define SETUP_AW        0x03  //设置地址宽度(所有数据通道)
  36. #define SETUP_RETR      0x04  //建立自动重发
  37. #define RF_CH           0x05  //RF通道
  38. #define RF_SETUP        0x06  //RF寄存器
  39. #define STATUS          0x07  //状态寄存器
  40. #define OBSERVE_TX      0x08  // 发送检测寄存器
  41. #define CD              0x09  // 载波检测寄存器
  42. #define RX_ADDR_P0      0x0A  // 数据通道0接收地址
  43. #define RX_ADDR_P1      0x0B  // 数据通道1接收地址
  44. #define RX_ADDR_P2      0x0C  // 数据通道2接收地址
  45. #define RX_ADDR_P3      0x0D  // 数据通道3接收地址
  46. #define RX_ADDR_P4      0x0E  // 数据通道4接收地址
  47. #define RX_ADDR_P5      0x0F  // 数据通道5接收地址
  48. #define TX_ADDR         0x10  // 发送地址寄存器
  49. #define RX_PW_P0        0x11  // 接收数据通道0有效数据宽度(1~32字节)
  50. #define RX_PW_P1        0x12  // 接收数据通道1有效数据宽度(1~32字节)
  51. #define RX_PW_P2        0x13  // 接收数据通道2有效数据宽度(1~32字节)
  52. #define RX_PW_P3        0x14  // 接收数据通道3有效数据宽度(1~32字节)
  53. #define RX_PW_P4        0x15  // 接收数据通道4有效数据宽度(1~32字节)
  54. #define RX_PW_P5        0x16  // 接收数据通道5有效数据宽度(1~32字节)
  55. #define FIFO_STATUS     0x17  // FIFO状态寄存器

  56. /******   STATUS寄存器bit位定义      *******/
  57. #define MAX_RT                  0x10            //达到最大发送次数中断
  58. #define TX_DS                   0x20            //数据发送完成中断
  59. #define RX_DR                   0x40            //接收到数据中断


  60. void init_hwspi(void);
  61. void init_nrf24l01_io(void);
  62. unsigned char SPI_RW(unsigned char Byte);
  63. unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value);
  64. unsigned char SPI_Read(unsigned char reg);
  65. unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes);
  66. unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes);


spi24l01.c
  1. #include <msp430.h>
  2. #include "spi24l01.h"

  3. void init_hwspi(void)
  4. {
  5.     //DataIn + DataOut + SerialClockOut
  6.     //UCA0SOMI+UCA0SIMO+UCA0CLK
  7.     P1SEL = BIT1 + BIT2 + BIT4;
  8.     P1SEL2 = BIT1 + BIT2 + BIT4;
  9.     //USCI复位状态。
  10.     UCA0CTL1 |= UCSWRST;
  11.     //USCI时钟源选择SMCLK
  12.     UCA0CTL1 |= UCSSEL_2;
  13.     //在第一个 UCLK 边沿上捕获的数据和在下列边沿上改变的数据,未激活的状态是低电平
  14.     //MSB优先+主控模式+3线SPI+同步模式
  15.     UCA0CTL0 |= UCCKPH + UCMSB + UCMST + UCMODE_0 + UCSYNC;
  16.     //设定波特率
  17.     UCA0BR0 = 2;
  18.     UCA0BR1 = 0;
  19.     //USCI复位操作释放
  20.     UCA0CTL1 &= ~UCSWRST;
  21.     //使能接收和发送中断
  22. //    IE2 |= UCA0RXIE + UCA0TXIE;
  23. }

  24. void init_nrf24l01_io(void)
  25. {
  26.         OUTDIR;
  27. //        IRQ_H;
  28. //        IRQ_REN;
  29. //        IRQ_IE;
  30. //        IRQ_IES;
  31. //        IRQ_IFG;
  32.         P1OUT |= BIT0;
  33.         P1REN |= BIT0;
  34.         P1IE |= BIT0;
  35.         P1IES |= BIT0;
  36.         P1IFG =0;
  37. }

  38. //硬件SPI数据交换函数
  39. //SPI_RW(待交换的数据)
  40. unsigned char SPI_RW(unsigned char byte)
  41. {
  42.         UCA0TXBUF = byte;
  43.         while((UCA0STAT&UCBUSY)>0);
  44.         return UCA0RXBUF;
  45. }

  46. //寄存器写值函数
  47. //SPI_RW_Reg(访问地址,要设定的值)
  48. unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
  49. {
  50.         //设定状态值
  51.     unsigned char status;
  52.     // 拉低CSN,初始化SPI传输
  53.     CSN_L;
  54.     // 写入待访问的地址(写寄存器命令(0x20)+寄存器地址),同时读取状态值
  55.     status = SPI_RW(reg);
  56.     // 写入要设定的值
  57.     SPI_RW(value);
  58.     // 拉高CSN,结束SPI传输
  59.     CSN_H;
  60.     // 返回状态值
  61.     return (status);
  62. }

  63. //读取寄存器值的函数
  64. //SPI_Read(要读取的寄存器地址)
  65. unsigned char SPI_Read(unsigned char reg)
  66. {
  67.         //设定读取到值
  68.     unsigned char reg_val;
  69.     // 拉低CSN,初始化SPI传输
  70.     CSN_L;
  71.     // 写入待访问的寄存器地址(读寄存器命令(0x00可省略)+寄存器地址),同时读取状态值
  72.     SPI_RW(reg);
  73.     //读取寄存器的值
  74.     reg_val = SPI_RW(0);
  75.     // 拉高CSN,结束SPI传输
  76.     CSN_H;
  77.     //返回读取到的寄存器的值
  78.     return (reg_val);
  79. }

  80. //读取多字节的数据(主要用来在接收时读取 FIFO 缓冲区中的值)
  81. //SPI_Read_Buf(待读寄存器地址,待读数据的存放地址(即存放读取数据的数组),数据的字节数)
  82. unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
  83. {
  84.         //设定状态值,当前字节数
  85.     unsigned char status, byte_ctr;
  86.     // 拉低CSN,初始化SPI传输
  87.     CSN_L;
  88.     // 写入待访问的地址(写寄存器命令(0x20)+寄存器地址),同时读取状态值
  89.     status = SPI_RW(reg);
  90.     //按照数据字节数读取每字节数据
  91.     for (byte_ctr = 0; byte_ctr < bytes; byte_ctr++)
  92.     {
  93.             //将读取到每字节数据存入对应的数据地址
  94.         pBuf[byte_ctr] = SPI_RW(0);
  95.     }
  96.     // 拉高CSN,结束SPI传输
  97.     CSN_H;
  98.     // 返回状态值
  99.     return (status);
  100. }

  101. //写入多字节的数据(主要用来把数组里的数放到发射 FIFO 缓冲区中)
  102. //SPI_Write_Buf(待写寄存器地址,待写数据的存放地址(即存放待写数据的数组),数据的字节数)
  103. unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
  104. {
  105.         //设定状态值,当前字节数
  106.     unsigned char status, byte_ctr;
  107.     // 拉低CSN,初始化SPI传输
  108.     CSN_L;
  109.     // 写入待访问的地址(写寄存器命令(0x20)+寄存器地址),同时读取状态值
  110.     status = SPI_RW(reg);
  111.     //按照数据字节数写入每字节数据
  112.     for (byte_ctr = 0; byte_ctr < bytes; byte_ctr++)
  113.     {
  114.             //写入当前地址的一字节数据,并移动到下一字节的地址
  115.             SPI_RW(*pBuf++);
  116.     }
  117.     // 拉高CSN,结束SPI传输
  118.     CSN_H;
  119.     // 返回状态值
  120.     return (status);
  121. }


发送端
  1. #include <msp430.h>
  2. #include "spi24l01.h"

  3. unsigned char sta;
  4. unsigned char fifo_s;
  5. unsigned char flag,i,flag_rx=0;

  6. unsigned char addr[5]={0,0,0,0,0};

  7. unsigned char TX[3]={1,2,3};
  8. unsigned char RX[3]={0,0,0};

  9. //有效数据宽度
  10. #define PLOAD_WIDTH                3
  11. //地址宽度
  12. #define ADR_WIDTH                5
  13. //发送地址&自动应答接收地址
  14. unsigned char ADDR[ADR_WIDTH]={1,2,3,4,5};

  15. void init_clock(void)
  16. {
  17.         // 检查校准信息是否被擦除
  18.         while(CALBC1_1MHZ==0xff||CALDCO_1MHZ==0XFF);
  19.         // 设置SELX的范围
  20.         DCOCTL=CALDCO_1MHZ;
  21.         // 设置SELX的范围
  22.         BCSCTL1=CALBC1_1MHZ;
  23.         //设置MCLK和SMCLK均为DCO_1MHz,8分频
  24.         BCSCTL2=DIVM_3+DIVS_3;
  25. }

  26. void delay_ms(unsigned int x)
  27. {
  28.   unsigned int i,j;
  29.   for (i=0;i<x;i++)
  30.             for(j=0;j<100;j++);
  31. }

  32. void TX_init(void)
  33. {
  34.     init_hwspi();
  35.     init_nrf24l01_io();
  36.         //模式选择,设定为待机模式
  37.         CE_L;
  38.         //停止寄存器读写
  39.         CSN_H;
  40.         //清除状态寄存器的值
  41.         SPI_RW_Reg(STATUS,0xff);
  42.         //设定发送节点的地址TX_ADDR, 地址数据, 地址宽度
  43.         SPI_Write_Buf(W_REGISTER + TX_ADDR, ADDR, ADR_WIDTH);
  44.         //设定应答信号待接收节点的地址RX_ADDR_P0, 地址数据, 地址宽度
  45.         SPI_Write_Buf(W_REGISTER + RX_ADDR_P0, ADDR, ADR_WIDTH);

  46.         //设定自动应答功能EN_AA,数据通道0自动应答允许
  47.         SPI_RW_Reg(W_REGISTER + EN_AA, 0x01);
  48.         //设定接收地址允许,接收数据通道0,允许接收数据通道0允许
  49.         SPI_RW_Reg(W_REGISTER + EN_RXADDR, 0x01);

  50.         //设定自动重发,等待500+86us,自动重发10次
  51.         SPI_RW_Reg(W_REGISTER + SETUP_RETR, 0x1a);

  52.         //设定通信通道频率RF_CH,选择信道为40
  53.         SPI_RW_Reg(W_REGISTER + RF_CH, 22);
  54.         //设定射频寄存器,发射功率0dBm 数据传输率2Mbps
  55.         SPI_RW_Reg(W_REGISTER + RF_SETUP, 0x07);


  56. }
  57. //发送数据包
  58. void TX_Packet(unsigned char * tx_buf)
  59. {
  60.         //模式选择,设定为待机模式
  61.         CE_L;
  62.         //清除状态寄存器的值
  63.         SPI_RW_Reg(W_REGISTER + STATUS,0xff);
  64.         //写TX有效数据,数据地址,数据量(选择TX_PLOAD_WIDTH(根据设定值))
  65.         SPI_Write_Buf(W_TX_PAYLOAD, tx_buf, PLOAD_WIDTH);
  66.         //设定配置寄存器,发射模式 上电 16位CRC校验 CRC使能
  67.         SPI_RW_Reg(W_REGISTER + CONFIG, 0x0e);
  68.         //启动发射
  69.         CE_H;
  70.         delay_ms(1);
  71. }

  72. /*
  73. * main.c
  74. */
  75. void main(void)
  76. {
  77.     WDTCTL = WDTPW | WDTHOLD;        // Stop watchdog timer

  78.     init_clock();
  79.     TX_init();

  80.     sta=SPI_Read(STATUS);
  81.     SPI_Read_Buf(RX_ADDR_P0,addr,5);

  82.     TX_Packet(TX);

  83.     sta=SPI_Read(STATUS);
  84.     sta=SPI_Read(STATUS);

  85.     _EINT();
  86.         while(1)
  87.         {
  88. //                sta=SPI_Read(STATUS);
  89.                 if(TX[2]>99)
  90.                         TX[2]=0;
  91.         }

  92. }

  93. //P1口中断服务函数
  94. #pragma vector=PORT1_VECTOR
  95. __interrupt void Port_1(void)
  96. {
  97.         if(P1IFG&BIT0)
  98.         {
  99.                 P1IFG &= ~BIT0;
  100.                 sta=SPI_Read(STATUS);
  101.                 SPI_RW_Reg(STATUS,0xff);
  102.                 if(sta&MAX_RT)
  103.                 {
  104.                         TX_Packet(TX);
  105.                 }
  106.                 else if(sta&TX_DS)
  107.                 {
  108.                         TX[2]++;
  109.                         TX_Packet(TX);
  110.                 }
  111.         }
  112. }


接收端
  1. #include <msp430.h>
  2. #include "spi24l01.h"

  3. unsigned char sta;
  4. unsigned char fifo_s;
  5. unsigned char flag,i,flag_rx=0;

  6. unsigned char addr[5]={0,0,0,0,0};
  7. unsigned char tx[3]={1,2,3};
  8. unsigned char RX[3]={0,0,0};

  9. //有效数据宽度
  10. #define PLOAD_WIDTH                3
  11. //地址宽度
  12. #define ADR_WIDTH                5
  13. //发送地址&自动应答接收地址
  14. unsigned char ADDR[ADR_WIDTH]={1,2,3,4,5};




  15. void init_clock(void)
  16. {
  17.         // 检查校准信息是否被擦除
  18.         while(CALBC1_1MHZ==0xff||CALDCO_1MHZ==0XFF);
  19.         // 设置SELX的范围
  20.         DCOCTL=CALDCO_1MHZ;
  21.         // 设置SELX的范围
  22.         BCSCTL1=CALBC1_1MHZ;
  23.         //设置MCLK和SMCLK均为DCO_1MHz,8分频
  24.         BCSCTL2=DIVM_3+DIVS_3;
  25. }

  26. void delay_ms(unsigned int x)
  27. {
  28.   unsigned int i,j;
  29.   for (i=0;i<x;i++)
  30.             for(j=0;j<100;j++);
  31. }



  32. void RX_init(void)
  33. {

  34.         init_hwspi();
  35.     init_nrf24l01_io();
  36.         delay_ms(1);
  37.         //模式选择,设定为待机模式
  38.         CE_L;
  39.         //停止寄存器读写
  40.         CSN_H;

  41.         //设定通信通道频率RF_CH,选择信道为40
  42.         SPI_RW_Reg(W_REGISTER + RF_CH,22);
  43.         //设定接收数据通道0有效数据量,选择PLOAD_WIDTH
  44.         SPI_RW_Reg(W_REGISTER + RX_PW_P0, PLOAD_WIDTH);
  45.         //设定射频寄存器,发射功率0dBm 数据传输率2Mbps
  46.         SPI_RW_Reg(W_REGISTER + RF_SETUP, 0x07);
  47. //        //设定发送节点的地址TX_ADDR, 地址数据, 地址宽度
  48. //        SPI_Write_Buf(W_REGISTER + TX_ADDR, ADDR, ADR_WIDTH);
  49.         //设定接收节点的地址RX_ADDR_P0, 地址数据, 地址宽度
  50.         SPI_Write_Buf(W_REGISTER +RX_ADDR_P0, ADDR, ADR_WIDTH);
  51.         //设定自动应答功能EN_AA,写0x01数据通道0自动应答允许
  52.         SPI_RW_Reg(W_REGISTER + EN_AA, 0x01);
  53.         //设定接收地址允许,接收数据通道0允许
  54.         SPI_RW_Reg(W_REGISTER + EN_RXADDR, 0x01);


  55. }


  56. void Set_RX()
  57. {
  58.         CE_L;
  59.         SPI_RW_Reg(W_REGISTER + CONFIG, 0x0f);
  60.         CE_H;
  61.         delay_ms(1);
  62. }

  63. unsigned char RX_PACKET(unsigned char * rx_buf)
  64. {
  65.         sta= SPI_Read(STATUS);
  66.         if(sta&RX_DR)
  67.         {
  68.                 CE_L;
  69.                 SPI_Read_Buf(R_RX_PAYLOAD,rx_buf,PLOAD_WIDTH);
  70.                 flag_rx=1;
  71.                 SPI_RW_Reg(W_REGISTER+STATUS,0xff);
  72.         }
  73.         return flag_rx;
  74. }

  75. /*
  76. * main.c
  77. */
  78. void main(void)
  79. {
  80.     WDTCTL = WDTPW | WDTHOLD;        // Stop watchdog timer
  81.     init_clock();

  82.     RX_init();
  83.     SPI_Read_Buf(RX_ADDR_P0,addr,5);
  84.     Set_RX();
  85.     _EINT();
  86.         while(1)
  87.         {
  88.                 i = SPI_Read(CD);
  89.                 if(i<1)
  90.                 {
  91.                         sta= SPI_Read(STATUS);
  92.                 }
  93.                 else if(i>0)
  94.                 {
  95.                         sta= SPI_Read(STATUS);
  96.                 }

  97.                 sta= SPI_Read(STATUS);
  98.                 if(sta&RX_DR)
  99.                 {
  100. //                        RX_PACKET(RX);
  101.                         //清除状态寄存器的值
  102.                         SPI_RW_Reg(W_REGISTER + STATUS,0xff);
  103.                         fifo_s =SPI_Read(FIFO_STATUS);
  104.                 }
  105.         }
  106. }

  107. ////P1口中断服务函数
  108. //#pragma vector=PORT1_VECTOR
  109. //__interrupt void Port_1(void)
  110. //{
  111. ////        if(P1IFG&BIT0)
  112. ////        {
  113. //                sta= SPI_Read(STATUS);
  114. //                if(sta&RX_DR)
  115. //                {
  116. //                        RX_PACKET(RX);
  117. //                }
  118. ////        }
  119. //}

  120. //P1口中断服务函数
  121. #pragma vector=PORT1_VECTOR
  122. __interrupt void Port_1(void)
  123. {
  124.         if(P1IFG&BIT0)
  125.         {
  126.                 P1IFG &= ~BIT0;
  127.                 sta=SPI_Read(STATUS);
  128. //                SPI_RW_Reg(STATUS,0xff);

  129.         }
  130. }



求助大神了
点赞  2016-6-28 20:14
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复