zjsxwc 发表于 2013-3-24 17:41:49

nrf24l01 IRQ脚无法恢复到高电位

本帖最后由 zjsxwc 于 2013-3-24 17:43 编辑

我用中断写的接收端程序,但是只有第一次他irq脚由高电位跳到低电位,然后向status寄存器写相应的位
为1后,irq脚仍旧没有恢复为高电位。然后就无法响应后面的事情了#include <reg52.h>
#include <intrins.h>


typedef unsigned char uint;//uint is a byte long

sbit         MISO        =P1^5;
sbit         MOSI        =P1^1;
sbit        SCK          =P1^6;
sbit        CE          =P1^7;
sbit        CSN                =P1^2;
sbit        IRQ                =P3^3;

sbit LED=P3^7;

#define ADR_WIDTH 5       
#define AW_ADR_WIDTH 0x03
#define PLOAD_WIDTH20


uint const TX_ADDRESS= {0x34,0x43,0x10,0x10,0x01};        //address that the RF packets contain
uint const RX_ADDRESS= {0x34,0x43,0x10,0x10,0x01};        //RF packets with *which address* that the pipes like to receive

//THE COMMANDS
#define READ_REG      0x00       
#define WRITE_REG       0x20        
#define RD_RX_PLOAD   0x61       
#define WR_TX_PLOAD   0xA0       
#define FLUSH_TX      0xE1        
#define FLUSH_RX      0xE2       
#define REUSE_TX_PL   0xE3       
#define NOP             0xFF       

//THE REGISTERS' ADDRESSES
#define CONFIG          0x00   
#define EN_AA         0x01
#define EN_RXADDR       0x02   
#define SETUP_AW      0x03   
#define SETUP_RETR      0x04
#define RF_CH         0x05
#define RF_SETUP      0x06   
#define STATUS          0x07   
#define OBSERVE_TX      0x08   
#define CD            0x09   
#define RX_ADDR_P0      0x0A   
#define RX_ADDR_P1      0x0B
#define RX_ADDR_P2      0x0C
#define RX_ADDR_P3      0x0D
#define RX_ADDR_P4      0x0E
#define RX_ADDR_P5      0x0F   
#define TX_ADDR         0x10   
#define RX_PW_P0      0x11
#define RX_PW_P1      0x12   
#define RX_PW_P2      0x13   
#define RX_PW_P3      0x14
#define RX_PW_P4      0x15   
#define RX_PW_P5      0x16   
#define FIFO_STATUS   0x17


uint         bdata sta;
sbit        RX_DR        =sta^6;
sbit        TX_DS        =sta^5;
sbit        MAX_RT        =sta^4;


//THE FUNCTIONS
uint SPI_write_byte(uint the_byte){
        uint count;
        SCK=0;
        for (count=0;count<8;count++){
                MOSI=(the_byte&0x80);//get the left most bit of the byte,and put on MOSI
                the_byte=the_byte<<1;//left move one bit
                SCK=1;                                                        //the SCK upside occurs,nrf24 eats the bit on mosi,nrf24 generates the bit on miso
                the_byte = the_byte|MISO;//the right most bit of the byte become MISO
                SCK=0;
        }
        return the_byte;
}

uint SPI_WRITE_REG_DATA_OR_CMD(uint reg,uint data_cmd){
        uint status;
        CSN =0;
        status =SPI_write_byte(reg);
        SPI_write_byte(data_cmd);
        CSN=1;
        return status;
}

uint SPI_WRITE_REG_ARRAY(uint reg,uint * array,uint length){
        uint status,count;
        CSN=0;
        status =SPI_write_byte(reg);
        for (count=0;count<length;count++){
                SPI_write_byte(array);
        }
        CSN=1;
        return status;
}

void inerDelay_us(unsigned char n){
        for(;n>0;n--) _nop_();
}
void init_NRF24L01(void){
        inerDelay_us(200);//100 us is okay,but 100 us as redundance
        CE=0;         //let nrf24 stop Trans/Recev packets
        CSN=0;        //let spi starts to work
        SCK=0;        //ready for SCK upside
       
        //set the addresses width
        SPI_WRITE_REG_DATA_OR_CMD(WRITE_REG+SETUP_AW,AW_ADR_WIDTH);
        //write the addr width
        SPI_WRITE_REG_ARRAY(WRITE_REG+TX_ADDR,TX_ADDRESS,ADR_WIDTH);
        SPI_WRITE_REG_ARRAY(WRITE_REG+RX_ADDR_P0,RX_ADDRESS,ADR_WIDTH);
       
        SPI_WRITE_REG_DATA_OR_CMD(WRITE_REG+EN_RXADDR,0x01);        //allow pipe0 to receive packets
//        SPI_WRITE_REG_DATA_OR_CMD(WRITE_REG+EN_AA,0x01);                        //allow pipe0 auto ACK,enter the SHOCKBURST MODE
        SPI_WRITE_REG_DATA_OR_CMD(WRITE_REG+EN_AA,0x00);
        SPI_WRITE_REG_DATA_OR_CMD(WRITE_REG+RF_CH,0);                                        //let the channel become 2.4000 GHz
        SPI_WRITE_REG_DATA_OR_CMD(WRITE_REG+RX_PW_P0,PLOAD_WIDTH);//set the payload width of pipe0
SPI_WRITE_REG_DATA_OR_CMD(WRITE_REG+RF_SETUP,0x07);                //let the data rate 1 Mbps,the power amplifier 0 dBm
       
        CSN=1;
       
}

void SET_RX_MODE(void){
        CE=0;                //stop nrf24 Trans/Recv
        SPI_WRITE_REG_DATA_OR_CMD(WRITE_REG+CONFIG,0x0f);
        //1. allow all 3 interrupts,
        //2. allow 16 bits CRC code,
        //3. start PWR_UP,
        //4. PRIM_RX=1,let nrf24 become RX MODE
       
        CE=1;                //start listining to receive packets
        inerDelay_us(200);//130 us is okay,but 70 us as redundance
}






uint SPI_READ_REG(uint reg){
        uint status,val;
        CSN=0;
        status=SPI_write_byte(READ_REG+reg);//bcs READ_REG =0,so just a form for uinty
        val=SPI_write_byte(READ_REG+0);
        CSN=1;
        return val;
}

uint SPI_READ_REG_ARRAY(uint reg, uint * array, uint length)
{
        uint status,count;
       
        CSN = 0;                                 
        status = SPI_write_byte(reg);                      
       
        for(count=0;count<length;count++)
                array = SPI_write_byte(0);   
        SPI_write_byte(FLUSH_RX );
        CSN = 1;                           
       
        return(status);                  
}

       








//THE NORMAL FUNCTION
/*
void longdelay(void){
        uint n=100,m=100,k=200;
        for (;k>0;k--) for (;m>0;m--) for (;n>0;n--) _nop_();
}*/
uint payload={0};

void main(){



init_NRF24L01();
        CE=0;
        SET_RX_MODE();
        CE=1;

        IT1=0;
        EX1=1;
        EA=1;
        PX1=0;


        LED=0;
while (1){
                        payload=0;
                        sta=SPI_READ_REG(STATUS);
       
                        if (RX_DR)        {
                                SPI_READ_REG_ARRAY(RD_RX_PLOAD,payload,PLOAD_WIDTH);
       
               
               
                        }
                                SPI_WRITE_REG_DATA_OR_CMD(WRITE_REG+STATUS,sta);//回写后irq没恢复。
                        if (payload) LED=~LED;
               
        }
               
}

void Renrf24() interrupt 2
{
        payload=0;
       
        sta=SPI_READ_REG(STATUS);
       
        if (RX_DR)        {
                SPI_READ_REG_ARRAY(RD_RX_PLOAD,payload,PLOAD_WIDTH);
                SPI_WRITE_REG_DATA_OR_CMD(WRITE_REG+STATUS,sta);//回写后irq没恢复。
       
               
        }

       
       
       
       
        if (payload==1) {
                if (LED=0) LED=1;
                else LED=0;
        }

}

noynot 发表于 2013-3-24 17:49:09

中断状态要手动清除,回写状态字

zjsxwc 发表于 2013-3-24 17:49:55

noynot 发表于 2013-3-24 17:49 static/image/common/back.gif
中断状态要手动清除,回写状态字

就是回写了后没有恢复

noynot 发表于 2013-3-24 21:13:30

中断PIN是几个共用的,特别是接收数据缓冲,需要把缓冲区的数据都读取

zjsxwc 发表于 2013-3-24 22:29:13

本帖最后由 zjsxwc 于 2013-3-24 22:31 编辑

noynot 发表于 2013-3-24 21:13 static/image/common/back.gif
中断PIN是几个共用的,特别是接收数据缓冲,需要把缓冲区的数据都读取

多谢你的回复,我发现原因了,是因为我本来不想使用自动回复,于是把AA都设置为0,把pipe 0的AA设置为自动恢复后就可以恢复irq脚了。应该是在没有自动回复时tx fifo中有东西没发完

页: [1]
查看完整版本: nrf24l01 IRQ脚无法恢复到高电位