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 static/image/common/back.gif
中断状态要手动清除,回写状态字
就是回写了后没有恢复 中断PIN是几个共用的,特别是接收数据缓冲,需要把缓冲区的数据都读取 本帖最后由 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]