打印

[求助SPI2奇怪问题]SPI2与NRF24L01的问题

[复制链接]
1897|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
bloceanc|  楼主 | 2013-10-24 22:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用STM32的SPI2链接NRF2L01,使用单步调试,NRF24LO1可以正常的设置,状态REG的值也正确,
而直接运行后,NRF24L01的状态REG的值就不对了。哪位大侠帮我看下啊,,,,,
已经两个星期了,搞不定啊。。。。。。

void nrf_spi2_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef SPI_InitStructure;
       
       
    /* SPI1 Init, before continuing, start the spio clock */
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE, ENABLE );       
          RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE);
       
    /* initialize GPIO A5.A6.A7 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
   
                /*
             GPIO B5 --- CSN(SPI NSS  chip select)
                         GPIO B6 --- CE (chip mode set)
          */
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_5;
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                GPIO_Init(GPIOB, &GPIO_InitStructure);
               
               
                /*
                                idle
                */
                NRF_HIGH(NRFB_CSE_PORT, NRFB_CSE_PIN);
                NRF_LOW(NRFB_CE_PORT, NRFB_CE_PIN);
               
                /*
                                GPIO B1 for nRF2401 IRQ
                */
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
                GPIO_Init(GPIOB, &GPIO_InitStructure);
                  
    SPI_Cmd(SPI2, DISABLE);

    /* configure spi1 */
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI2, &SPI_InitStructure);
   
    /* enable spi */
    SPI_Cmd(SPI2, ENABLE);
}



void nrf_spi_rxmode(SPI_TypeDef* SPIx, unsigned char *dest_addr, int len, unsigned char channel)
{       
                NRF_CE_LOW(SPIx);                                                                // 拉底CE不是CS
                if(SPI1 == SPIx)       
                        NRF_LOW(NRFA_CE_PORT, NRFA_CE_PIN);       
                else       
                        NRF_LOW(NRFB_CE_PORT, NRFB_CE_PIN);
                nrf_spi_writereg(SPIx, OPT_FLUSH_RX, 0xff);                // RESET Receive FIFO
                nrf_spi_writebuf(SPIx, OPT_W_REGISTER + RA_RX_ADDR_P0, dest_addr, len);        // 指定接收地址,只接受目的地址是指定地址的数据
                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_EN_AA, 0x01);                                                        // 使能通道0自动应答
                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_EN_RXADDR, 0x01);                                        // 使能接收通道0
                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_RF_CH, channel);                                                // 选择射频频段
                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_RX_PW_P0, NRF_FRAM_LEN);                // 设置接收数据长度
                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_RF_SETUP, 0x07);           // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_CONFIG, 0x03);             // CRC使能,16位CRC校验,上电,接收模式
       
                NRF_CE_HIGH(SPIx);                                                // 拉高CE
                delay_ms(100);
}

void nrf_spi_txmode(SPI_TypeDef* SPIx, unsigned char *dest_addr, int dest_len, unsigned char channel)
{
                NRF_CE_LOW(SPIx);                                                                                                // 拉底CE不是CS
       
          nrf_spi_writereg(SPIx, OPT_FLUSH_TX, 0xff);                // RESET send FIFO
                nrf_spi_writebuf(SPIx, OPT_W_REGISTER + RA_TX_ADDR,dest_addr, dest_len);                                //写TX节点地址
          nrf_spi_writebuf(SPIx, OPT_W_REGISTER + RA_RX_ADDR_P0, dest_addr, dest_len);                 //设置TX节点地址,主要为了使能ACK          
//                nrf_spi_writebuf(SPIx, OPT_W_TX_PAYLOAD, buf, buflen);                                                                                                  // 装载数据
       
    nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_EN_AA, 0x01);                                                                                     //  频道0自动        ACK应答允许       
                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_EN_RXADDR, 0x01);                                                                          //  允许接收地址只有频道0,如果需要多频道可以参考Page21  
                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_SETUP_RETR, 0x1a);                                                                         // 设置自动重发时间和次数:500us + 86us, 10 retrans...
                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_RF_CH, channel);                                                                //   设置信道工作为2.4GHZ,收发必须一致
//                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_RX_PW_P0, NRF_FRAM_LEN); //NRF_FRAM_LEN                                                //设置接收数据长度,本次设置为32字节
                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_RF_SETUP, 0x07);                                                                           //设置发射速率为1MHZ,发射功率为最大值0dB

                nrf_spi_writereg(SPIx, OPT_W_REGISTER + RA_CONFIG, 0x02);//0x0E);
       
                NRF_CE_HIGH(SPIx);                                                // 拉高CE
               
//                delay_ms(100);        // CE 拉高要持续一段时间
}

void main(void *p_arg)
{
   
                unsigned char channel = 128;
                unsigned char spi1_addr[5] = {0x5,0x4,0x3,0x2,0x1};
                unsigned char spi2_addr[5] = {0x5,0x4,0x3,0x2,0x2};
                unsigned char senddata[32] = {0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,
                                                                                                                                        0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,
                                                                                                                                        0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,
                                                                                                                                        0x6,0x6};
int err = 0;
unsigned char status = 0;
                                                                                                                                       
    nrf_spi1_init();
                nrf_spi2_init();
//                mySPI_Init();
//    nrf_spi_irqconfig();        // 配置中断等
                  
                // sp1 进入接收模式
                nrf_spi_rxmode(SPI1, spi2_addr, 5, channel);

                // sp2 发送模式,并发送数据
                nrf_spi_txmode(SPI2, spi2_addr, 5, channel);       

                // sp2 发送数据
                nrf_spi_sendframe(SPI2, spi2_addr, 5, senddata, 32);                                                                                                                                       
                while(1)
                {
                                status = nrf_spi_readreg(SPI1, RA_STATUS);        // 读取状态寄存其来判断中断原因

                                status = nrf_spi_readreg(SPI2, RA_STATUS);        // 读取状态寄存其来判断中断原因
                       
                                if(status == 0)
                                {
                                        err++;
                                }
                }
}
沙发
airwill| | 2013-10-25 15:48 | 只看该作者
使用单步调试,NRF24LO1可以正常的设置,状态REG的值也正确,而直接运行后,NRF24L01的状态REG的值就不对了。

估计这样的问题, 大都是初始化里的延时不够导致的. 情况是设备还没有处理完接受的上次命令, 下一个命令就到了.

使用特权

评论回复
板凳
bloceanc|  楼主 | 2013-10-25 19:12 | 只看该作者
airwill 发表于 2013-10-25 15:48
使用单步调试,NRF24LO1可以正常的设置,状态REG的值也正确,而直接运行后,NRF24L01的状态REG的值就不对了 ...

我用SPI1试了下,是没有问题的,而且让STM32 72M最高频率运行,SPI1也没有问题。。真是奇怪。。
SPI2的频分也已经开到最大了。。。现在STM32 32M频率运行还是有问题。。真奇怪。。。。
不知道晚上的那些都是怎么运行起来的。。。

使用特权

评论回复
地板
香如故| | 2013-10-26 10:07 | 只看该作者
while(1) 里怎么又是spi1,又有spi2?,接了两个?
              while(1)
                {
                                status = nrf_spi_readreg(SPI1, RA_STATUS);        // 读取状态寄存其来判断中断原因

                                status = nrf_spi_readreg(SPI2, RA_STATUS);        // 读取状态寄存其来判断中断原因
                        
                                if(status == 0)
                                {
                                        err++;
                                }
                }

使用特权

评论回复
5
bloceanc|  楼主 | 2013-10-30 19:16 | 只看该作者
香如故 发表于 2013-10-26 10:07
while(1) 里怎么又是spi1,又有spi2?,接了两个?
              while(1)
                {

是的,两片nrf24l01互相收发,在一个stm32系统下

使用特权

评论回复
6
jxlxq| | 2014-6-17 00:19 | 只看该作者
兄弟,我也遇到SPI2工作异常的情况啊。SPI2有时候可以正常工作,有时候异常,郁闷中。。。。,你的问题解决了吗?传授点经验。。。。

使用特权

评论回复
7
jxlxq| | 2014-6-17 00:20 | 只看该作者
我用了三个SPI. SPI1,SPI3工作都正常,就是SPI2工作不正常。

使用特权

评论回复
8
sail8498| | 2014-12-3 22:29 | 只看该作者
LZ求代码,我也在学用NRF24L01

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

10

帖子

1

粉丝