请教我的NRF24L01怎样在中断方式下执行?
我用msp430单片机调试nrf24l01,但我找到的实例程序都是用查询方式做nrf24l01通信的,为了提高通讯的速率并减轻cpu的负担,我想改为中断方式,就是PTX的24l01每发完一个包,就申请cpu中断,进入中断服务程序。PRX的24l01每收到一个包,就申请一个中断,将数据递交cpu进行处理。但是现在问题是我的24l01只能进入一次中断,如果我在中断服务程序中清除了中断标志位,就无法再进入中断服务程序了。
给大家看看我的代码。
//--------------------射频芯片相关定义-------------------
#define NRF24L01_TxRxBuf_Len 32
#define TXRX_ADDR_WIDTH 5
//---------------------NRF24L01引脚定义------------------------
// MSP430F261x/241x
// -----------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// | |
// | |
// | P3.7|-> CE
// | P3.6|-> CSN
// | P3.1|-> Data Out (UCB0SIMO)
// | |
// |P1.0 P3.2|<- Data In (UCB0SOMI)
// | |
// IRQ ->|P1.1 P3.3|-> Serial Clock Out (UCB0CLK)
// Date:2009.12.18
#define CE_DDR_OUT() P3DIR |= BIT7
#define CE_ON(); P3OUT |= BIT7
#define CE_OFF() P3OUT &= ~BIT7
#define CSN_DDR_OUT() P3DIR |= BIT6
#define CSN_ON(); P3OUT |= BIT6
#define CSN_OFF() P3OUT &= ~BIT6
#define MOSI_DDR_OUT() P3DIR |= BIT1
#define MOSI_ON(); P3OUT |= BIT1
#define MOSI_OFF() P3OUT &= ~BIT1
#define SCK_DDR_OUT() P3DIR |= BIT3
#define SCK_ON(); P3OUT |= BIT3
#define SCK_OFF() P3OUT &= ~BIT3
#include <msp430x26x.h>
#include "nRF24L01.h"
void main(void)
{
volatile unsigned int i;
WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer
if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
{
while(1); // If calibration constants erased
// do not load, trap CPU!!
}
BCSCTL1 = CALBC1_8MHZ; // Set DCO
DCOCTL = CALDCO_8MHZ;
for(i=2100;i>0;i--); // Wait for DCO to stabilize.
BCSCTL2 &= ~(BIT1+BIT2);
P5DIR |= 0x70; // P5.6,5,4 outputs
P5SEL |= 0x70; // P5.6,5,4 options
SPI_Init();
P1DIR |= BIT0;
NRF24L01_Init();
NRF24L01_Write_RxADDR();
NRF24L01_SetRxMode();
_EINT();
NRF24L01_Write_TxADDR();
NRF24L01_TxPacket();
}
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
NRF24L01_Write_TxADDR();
NRF24L01_TxPacket();
P1OUT &= ~BIT0;
delay_ms(160);
P1OUT |= BIT0;
delay_ms(160);
P1IFG &= ~BIT1; // P1.1 IFG cleared
} 然后这是我的nrf24l01.h头文件
#ifndef NRF24L01_H_
#define NRF24L01_H_
#endif /*NRF24L01_H_*/
#include "nRF24L01_def.h"
#ifndef _RX_
unsigned char NRF24L01_TxRxBuf= "NRF24L01 is working all right!!";
#endif
#ifdef _RX_
unsigned char NRF24L01_TxRxBuf= "Transmition works well !";
#endif
unsigned char NRF24L01_TxAddr= {0xcc,0xcc,0xcc,0xcc,0xcc};
unsigned char NRF24L01_RxAddr= {0xcc,0xcc,0xcc,0xcc,0xcc};
unsigned char flag = 0;
//------------------------NRF24L01寄存器配置------------------------
unsigned char NRF24L01_Config =
{
#ifdef _RX_
MASK_TX_DS| MASK_MAX_RT|EN_CRC|CRC16,//CONFIG
#endif
#ifndef _RX_
EN_CRC|CRC16,//CONFIG
#endif
0,//EN_AA
ERX_ADDR_P0,//EN_RXADDR
AW_5,//SETUP_AW
0x1a,//SETUP_RETR
0,//RF_CH
RF_DR_2Mbps|RF_PWR_0|LAN_HCURR,//RF_SETUP
};
//---------------------------NRF24L01射频芯片初始化函数--------------------------------------
void NRF24L01_Init(void)
{
unsigned int i;
// unsigned char j;
//掉电模式
CE_OFF();
NRF24L01_WriteReg(CONFIG,~PWR_UP);
// delay_ms(1);
for(i=2100;i>0;i--);
// for(l=255;l>0;l--);
//默认配置
NRF24L01_WriteReg(EN_AA, NRF24L01_Config);
NRF24L01_WriteReg(EN_RXADDR, NRF24L01_Config);
NRF24L01_WriteReg(SETUP_AW, NRF24L01_Config);
NRF24L01_WriteReg(SETUP_RETR, NRF24L01_Config);
NRF24L01_WriteReg(RF_CH, NRF24L01_Config);
NRF24L01_WriteReg(RF_SETUP, NRF24L01_Config);
NRF24L01_WriteReg(CONFIG,NRF24L01_Config);
NRF24L01_WriteReg(RX_PW_P0, NRF24L01_TxRxBuf_Len);
NRF24L01_Write_RxADDR();
NRF24L01_Write_TxADDR();
}
//---------------------------NRF24L01设置接收模式函数--------------------------------------
void NRF24L01_SetRxMode(void)
{
// unsigned char j;
CE_OFF();
NRF24L01_WriteReg(CONFIG, ((NRF24L01_ReadReg(CONFIG))&0xfc)|PWR_UP|PRIM_RX);
CE_ON();
delay_10us(13);
// for(j=135;j>0;j--);
}
//---------------------------NRF24L01数据包接收函数--------------------------------------
unsigned char NRF24L01_RxPacket(void)
{
unsigned char i,cur_status,rev;
// unsigned char status = 0;
// _DINT();
cur_status = NRF24L01_ReadReg(STATUS);
if(RX_DR&cur_status)
{
CSN_OFF();
// SPI_Write(RRP);
SPI_RW(RRP);
for(i=0; i<NRF24L01_TxRxBuf_Len; i++)
{
// NRF24L01_TxRxBuf = SPI_Read();
NRF24L01_TxRxBuf = SPI_RW(RR);
}
CSN_ON();
CSN_OFF();
// SPI_Write(FRX);
SPI_RW(FRX);
CSN_ON();
CE_OFF();
rev =TRUE;
}
else
{
rev =FALSE;
}
// status = NRF24L01_ReadReg(STATUS);
NRF24L01_WriteReg(STATUS,cur_status);
// _EINT();
return rev;
}
//---------------------------NRF24L01数据包发送函数--------------------------------------
void NRF24L01_TxPacket(void)
{
unsigned char i;
// _DINT();
CE_OFF();
CSN_OFF();
SPI_RW(FTX)
// SPI_Write(FTX);
CSN_ON();
CSN_OFF();
// SPI_Write(WRP);
SPI_RW(WRP);
for(i=0; i<NRF24L01_TxRxBuf_Len; i++)
{
// SPI_Write( NRF24L01_TxRxBuf);
SPI_RW( NRF24L01_TxRxBuf);
}
CSN_ON();
NRF24L01_WriteReg(CONFIG, ((NRF24L01_ReadReg(CONFIG))&0xfc)|PWR_UP);
CE_ON();
// _EINT();
}
//---------------------------NRF24L01寄存器写入函数--------------------------------------
voidNRF24L01_WriteReg(unsigned charaddr, unsigned char value)
{
CSN_OFF();
// SPI_Write(addr|WR);
// SPI_Write(value);
SPI_RW(addr|WR);
SPI_RW(value);
CSN_ON();
}
//---------------------------NRF24L01寄存器读取函数--------------------------------------
unsigned charNRF24L01_ReadReg(unsigned charaddr)
{
unsigned char value;
CSN_OFF();
// SPI_Write(addr|RR);
// value = SPI_Read();
value = SPI_RW(addr|RR);
CSN_ON();
return value;
}
//---------------------------NRF24L01接收地址设置函数--------------------------------------
void NRF24L01_Write_RxADDR(void)
{
unsigned char i;
CSN_OFF();
// SPI_Write(RX_ADDR_P0|WR);
SPI_RW(RX_ADDR_P0|WR);
for(i=0; i<TXRX_ADDR_WIDTH; i++)
{
// SPI_Write(NRF24L01_RxAddr);
SPI_RW(NRF24L01_RxAddr);
}
CSN_ON();
}
//---------------------------NRF24L01发送地址设置函数--------------------------------------
void NRF24L01_Write_TxADDR(void)
{
unsigned char i;
CSN_OFF();
// SPI_Write(TX_ADDR|WR);
SPI_RW(TX_ADDR|WR);
for(i=0; i<TXRX_ADDR_WIDTH; i++)
{
// SPI_Write(NRF24L01_TxAddr);
SPI_RW(NRF24L01_TxAddr);
}
CSN_ON();
}
// *
// *
void SPI_Init(void)
{
CE_DDR_OUT();
CSN_DDR_OUT();
// P3DIR |= (BIT1+BIT3);
P3SEL |= 0x0E; // P3.3,2,1 option select
UCB0CTL0 |= UCMST+UCSYNC+UCCKPH+UCMSB; // 3-pin, 8-bit sync SPI master
// UCB0CTL0 |= UCMST+UCSYNC+UCMSB; // 3-pin, 8-bit sync SPI master
UCB0CTL1 |= UCSSEL_2; // SMCLK
UCB0BR0 = 0; // SMCLK
UCB0BR1 = 0;
UCB0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
P1IE |= 0x02; // P1.1 interrupt enabled
P1IES |= 0x02; // P1.1 Hi/Lo edge
P1IFG &= ~0x02; // P1.1 IFG cleared
CSN_ON();
// SCK_OFF();
}
unsigned char SPI_RW(unsigned char txdata)
{
// unsigned char rec;
while (!(IFG2 & UCB0TXIFG)); // USCI_B0 TX buffer ready?
UCB0TXBUF = txdata;
// rec = UCB0RXBUF;
while (!(IFG2 & UCB0RXIFG)); // USCI_B0 RX buffer ready?
return (UCB0RXBUF);
} 程序写的很杂,都不太好意思贴出来,贴出来的的主程序是PTX,就是发送端的程序,还望大家不吝赐教 你进中断了后需要判断是何种原因引起的中断,也有可能是发送达到最大次数引起的中断,你要对这些情况都做处理才可以,你需要一点点地跟踪程序.尤其是中断服务函数里的执行情况,从而找出原因. 我现在在单独调试RX_DR的中断,但是现在又遇到了另一个问题,每次我用JTAG进入调试时,中断信号就不能正常产生了,必须要把nrf24l01和单片机断电,再上电,才能正常产生中断信号。我想可能是nrf24l01初始化的问题,因为程序初始化2401时是先进入掉电模式,但是进入掉电模式后,数据还在寄存器里面,当程序执行到2401上电时,就产生了一个中断信号,然后再无论如何设置2401都没有中断了。 好像没看到你设置 P1.1中断啊
P1IES_bit.P1IES_1 = 1;//下降沿
P1IFG_bit.P1IFG_1 = 0;
P1IE_bit.P1IE_1 = 1;
还有你代码貌似没进低功耗模式,跑飞了吧 我碰到的问题很奇怪:自动应答发送时,如果得不到响应,再不会来IRQ低电平,即使对状态REG写0X71,重初始化,都不行,断电后才恢复,不知道原因 我设置了中断方式,下降沿触发的。
奋斗了几个晚上,终于把PRX端搞通了,每次中断信号发送出来后,都必须写入STATUS寄存器对应的中断位“1”来清中断,比如我的PRX设备就要在进入中断后NRF24L01_WriteReg(STATUS,RX_DR);
回复【6楼】888888888888
我昨天也遇到了,后来发现就是用上述的方法可以解决这个问题。
现在是我的PTX端了,最新的情况是我的TX_DS中断正常工作,而且可以正常发送数据,但是,当我把PRX端设备断电,还是能够正常进入中断,读STATUS寄存器的值是0x2E也就是说依然是TX_DS中断,拿不到MAX_RT中断让我很迷茫。
还有一个问题就是我平均下来每秒钟只能收发1.4k个包,拿每个包32字节算也不到40kb/s。这个速度太慢了,视频很难加载上来啊。请教怎样才能更快呢,nrf24L01可是号称2M速率啊 楼主很幸运了,我倒现在用F2616的USCI都没调通发送。看来得下功夫拿示波器量了。 hyrtster 发表于 2010-2-7 22:01
我设置了中断方式,下降沿触发的。
奋斗了几个晚上,终于把PRX端搞通了,每次中断信号发送出来后,都必须写 ...
是2Mbps。。。。。。不是2M。 楼主,关于数据传输速率,我的个人理解是:2Mbps 是指的数据在空中的传输速率,真正限制你数据传输速率的是将数据送入nrf24L01发送端的那些程序段,每发送一个包都要延时等等,所以,不可能达到真正2Mbps的 。
页:
[1]