lgymilu 发表于 2010-12-21 10:03:41

NRF24L01接收问题,接收寄存器不能清零,标志位不置位

最近一直在调NRF24L01,刚有些进展,昨天再拿出以前调好的程序跑发现不能接收了,发现问题出在不能产生接收终端标志位,所以串口一直没有数据发送,后来虽然改了一下可以接收了但是很奇怪,每次在串口读完之后还要再读一遍RX_PAYLOAD才能让STATUS的RX_DR置位,而且好像也不能给STATUS复位了,一下是我的程序,请高手解答一下,很困惑啊程序的顺序是收到信号给STATUS的RX_DR置位,之后串口传数据,然后清楚RX_DR位,等待下次接收RX_DR再置位,但是不加那句“SPI_Read_Buf(RD_RX_PLOAD,rx_buf,20);”就不能继续接收了

#include "msp430x14x.h"
void init_chip(void);               
void init_uart(void);
void init_clock(void);

unsigned char SPI_RW(unsigned char byte);
unsigned char SPI_Write(unsigned char byte);
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value);
unsigned char SPI_Read(unsigned char reg);
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes);
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes);
void StandbyI(void);
void StadbyII(void);
void RX_Mode(void);
void TX_Mode(void);
void setupnrf(void);

void delay(int a);
void LED(void);
/******************************************************************************/
#define ADR_WIDTH    5   // 5 bytes TX(RX) address width (地址长度)
#define PLOAD_WIDTH20// 20 bytes TX payload (最大是 32 bytes)

unsigned char        TX_ADDRESS                = {0x34,0x43,0x10,0x10,0x01}; // Define a static TX address (即目标地址)
unsigned char        Local_ADDRESS        = {0x34,0x43,0x10,0x10,0x01}; // Define a static RX address (即本地地址)
                                                                                          
unsigned char rx_buf;        //接收缓存容器
unsigned char tx_buf={'c','o','n','g','r','a','t','u','l','a','t','i','o','n',' ','r','i','g','h','t'};        //发送缓存容器
//unsigned char tx_buf={0x01,0x02,0x03,0x04,0x05,0x01,0x02,0x03,0x04,0x05,0x01,0x02,0x03,0x04,0x05,0x34,0x43,0x10,0x10,0x01};        //发送缓存容器
unsigned char flag;                                        //标志
int flag_r;
int flag_t;
int flag_e;
//************************************************************************************

/**************************************************************************************/
unsigned char        sta;                          //状态标志
#define RX_DR      sta&0x40       // RX_DR=sta^6;接收数据中断,当接收到有效数据后置1
#define TX_DS      sta&0x20       //TX_DS =sta^5;数据发送完成中断
#define MAX_RT   sta&0x10       // MAX_RT =sta^4; 达到最多次重发中断
/**************************************************************************************/
/**************************************************************************************/
//DEFINE IO
#define SET_CSN P5OUT|=0X01
#define CLR_CSN P5OUT&=0XFE
//#define SET_CEP5OUT|=0X10
//#define CLR_CEP5OUT&=0XEF
#define SET_CE    P1OUT|=0X40
#define CLR_CE    P1OUT&=0XBF
#define SET_MOSIP5OUT|=0X02
#define CLR_MOSIP5OUT&=0XFD
#define SET_SCK   P5OUT|=0X08
#define CLR_SCK   P5OUT&=0XF7

/**************************************************************************************/
// SPI(nRF24L01) commands
#define READ_REG      0x00// Define read command to register
#define WRITE_REG       0x20// Define write command to register
#define RD_RX_PLOAD   0x61// Define RX payload register address
#define WR_TX_PLOAD   0xA0// Define TX payload register address
#define FLUSH_TX      0xE1// Define flush TX register command
#define FLUSH_RX      0xE2// Define flush RX register command
#define REUSE_TX_PL   0xE3// Define reuse TX payload register command
#define NOP             0xFF// Define No Operation, might be used to read status register
// SPI(nRF24L01) registers(addresses)
#define CONFIG          0x00// 'Config' register address
#define EN_AA         0x01// 'Enable Auto Acknowledgment' register address
#define EN_RXADDR       0x02// 'Enabled RX addresses' register address
#define SETUP_AW      0x03// 'Setup address width' register address
#define SETUP_RETR      0x04// 'Setup Auto. Retrans' register address
#define RF_CH         0x05// 'RF channel' register address
#define RF_SETUP      0x06// 'RF setup' register address
#define STATUS          0x07// 'Status' register address
#define OBSERVE_TX      0x08// 'Observe TX' register address
#define CD            0x09// 'Carrier Detect' register address
#define RX_ADDR_P0      0x0A// 'RX address pipe0' register address
#define RX_ADDR_P1      0x0B// 'RX address pipe1' register address
#define RX_ADDR_P2      0x0C// 'RX address pipe2' register address
#define RX_ADDR_P3      0x0D// 'RX address pipe3' register address
#define RX_ADDR_P4      0x0E// 'RX address pipe4' register address
#define RX_ADDR_P5      0x0F// 'RX address pipe5' register address
#define TX_ADDR         0x10// 'TX address' register address
#define RX_PW_P0      0x11// 'RX payload width, pipe0' register address
#define RX_PW_P1      0x12// 'RX payload width, pipe1' register address
#define RX_PW_P2      0x13// 'RX payload width, pipe2' register address
#define RX_PW_P3      0x14// 'RX payload width, pipe3' register address
#define RX_PW_P4      0x15// 'RX payload width, pipe4' register address
#define RX_PW_P5      0x16// 'RX payload width, pipe5' register address
#define FIFO_STATUS   0x17// 'FIFO Status Register' register address
/***************************************************************************************/
void init_chip()
{
P5SEL=0;
P5DIR|=0X1B;                  //P5.0 5.1 5.35.4输出P5.2输入
P1SEL=0;
P1DIR|=0X40;
CLR_CE;
SET_CSN;
CLR_SCK;
CLR_MOSI;
P1OUT=0X00;
P1IE|=0X80;
P1IES|=0X80;
P1IFG=0X00;
//_EINT();
}
void init_clock()
{
BCSCTL1=0X80;
do
{IFG1&=~OFIFG;
delay(159);}
while(IFG1&OFIFG);
BCSCTL2=SELM0+SELM1;

}
void init_uart()
{
P3SEL|=0X30;
UCTL0=SWRST;
ME1|=UTXE0+URXE0;                     //使能发送接收
UCTL0|=CHAR;
UTCTL0=SSEL0;
U0BR0=0X03;
U0BR1=0X00;
U0MCTL=0X4A;   
UCTL0&=~SWRST;                  
IE1|=URXIE0+UTXIE0;                   //使能中断
}
unsigned char SPI_Write(unsigned char byte)
{
int i;
for(i=0;i<8;i++)
{
    if(byte&0x80!=0)
      SET_MOSI;
    else
      CLR_MOSI;
    byte=byte<<1;
    SET_SCK;
    if(P5IN&0x40)
      byte|=0x01;
    else
      byte&=0xfe;
    CLR_SCK;
   
}
return(byte);
}

void StandbyI()
{
SPI_RW_Reg(WRITE_REG+CONFIG,0X0E);
}
void StandbyII()
{
SPI_RW_Reg(WRITE_REG+CONFIG,0X3E);
SPI_RW(FLUSH_TX);
delay(1000);
SET_CE;
}
void setupnrf()
{
SPI_RW_Reg(WRITE_REG+EN_RXADDR,0X01);
SPI_RW_Reg(WRITE_REG+SETUP_AW,0X03);
}

unsigned char SPI_RW(unsigned char byte)
{
int i;
for(i=0;i<8;i++)
{
    if(byte&0x80)
    P5OUT|=0X02;
else
    P5OUT&=0XFD;
byte<<=1;
_NOP();_NOP();_NOP();
   _NOP();_NOP();_NOP();
P5OUT|=0X08;
_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();
_NOP();
if(P5IN&0X04)
    byte|=0x01;
else
    byte&=0xfe;
    _NOP();_NOP();_NOP();
   _NOP();_NOP();_NOP();
P5OUT&=0XF7;
}
return(byte);
}
unsigned char SPI_RW_Reg(unsigned char reg,unsigned char value)
{
    unsigned char status;
    SET_CSN;
    CLR_CSN;
    status=SPI_RW(reg);
    SPI_RW(value);
    SET_CSN;
    return(status);
}
unsigned char SPI_Read(unsigned char reg)
{
unsigned char reg_val;
SET_CSN;
CLR_CSN;
SPI_RW(reg);
reg_val=SPI_RW(0);
SET_CSN;
return(reg_val);
}
unsigned char SPI_Write_Buf(unsigned char reg,unsigned char *pBuf,unsigned char bytes)
{
unsigned char status,byte_ctr;
SET_CSN;
CLR_CSN;
status=SPI_RW(reg);
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
    SPI_RW(*pBuf++);
SET_CSN;
return(status);
}
unsigned char SPI_Read_Buf(unsigned char reg,unsigned char *pBuf,unsigned char bytes)
{
unsigned char status,byte_ctr;
SET_CSN;
CLR_CSN;
status=SPI_RW(reg);
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
{
    pBuf=SPI_RW(0);
}
SET_CSN;
return(status);
}
void TX_Mode(void)
{
//P1OUT&=0XBF;          //P1.6=0
CLR_CE;      //P5.4=0
SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,ADR_WIDTH);
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,ADR_WIDTH);
SPI_Write_Buf(WR_TX_PLOAD,tx_buf,PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG+CONFIG,0X0E);
SPI_RW_Reg(WRITE_REG+EN_AA,0X00);
SPI_RW_Reg(WRITE_REG+EN_RXADDR,0X01);
SPI_RW_Reg(WRITE_REG+SETUP_RETR,0X1a);
SPI_RW_Reg(WRITE_REG+RF_CH,0X00);
SPI_RW_Reg(WRITE_REG+RF_SETUP,0X07);

//P1OUT|=0X40;          //P1.6=1
SET_CE;      //P5.4=1
delay(159);
CLR_CE;
}
void RX_Mode(void)
{
//P1OUT&=0XBF;          //P1.6=0
CLR_CE;            //P5.4=0
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,Local_ADDRESS,ADR_WIDTH);
SPI_RW_Reg(WRITE_REG+EN_AA,0X00);
SPI_RW_Reg(WRITE_REG+EN_RXADDR, 0x01);
SPI_RW_Reg(WRITE_REG+SETUP_AW,0X03);
SPI_RW_Reg(WRITE_REG+RF_CH,0X00);
SPI_RW_Reg(WRITE_REG+RF_SETUP,0X07);
SPI_RW_Reg(WRITE_REG+RX_PW_P0,PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG+CONFIG,0X0F);
//P1OUT|=0X40;          //P1.6=1
SET_CE;         //P5.4=1
delay(159);
}
void flash_write(unsigned char byte)
{
/*unsigned char data;
for(int i=0;i<24;i++)
{
    data=i;
}*/

unsigned char *tp;//,*write_ptr;
tp=(unsigned char *)0x1000;
FCTL2=FWKEY+FSSEL0+FN0;
FCTL3=FWKEY;
//*tp=1;
FCTL1=FWKEY+WRT;
//for(i=0;i<24;i++)
//{
    *tp=byte;
    //tp++;
//}
FCTL1=FWKEY;
FCTL3=FWKEY+LOCK;
}
void delay(int a)
{
while(a--){}
}
void IRQEINT()
{
sta=SPI_Read(STATUS);
int i;
if(RX_DR)
{
    SPI_Read_Buf(RD_RX_PLOAD,rx_buf,20);
    flash_write( rx_buf);
    for(i=0;i<PLOAD_WIDTH;i++)
    {TXBUF0=rx_buf;
    while((UTCTL0&TXEPT)!=TXEPT);}
    flag=1;
    //TX_Mode();
    delay(1000);
}
else
    flag=0;
SPI_RW(FLUSH_RX);                      //主要的问题出在这几句,FLUSH_RX之后读FIF0_STATUS应该是0x11吧,可是实际是0x12
delay(1000);
SPI_RW_Reg(WRITE_REG+STATUS,sta);       //这一句之后STATUS应该置位了,但是没有变……
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,20);    //这句就更奇怪了,加上这句接收就没有问题,不加就只能接收一次……可这句有什么用啊……
sta=SPI_Read(STATUS);
}
int main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
//int i;
init_chip();
init_clock();
init_uart();

StandbyI();
SPI_RW(FLUSH_RX);
//_EINT();
//RX_Mode();
while(1)
{
   RX_Mode();
   IRQEINT();
   sta=SPI_Read(STATUS);
//SPI_RW_Reg(WRITE_REG+STATUS,0X0E);
//LPM1;
    /*if(RX_DR)
    {
      flag_r=0;
      TX_Mode();
      delay(159);
      SPI_RW_Reg(STATUS,sta);
    }
    if(TX_DS)
    {
      flag_t=0;
      RX_Mode();
      delay(159);
      SPI_RW_Reg(STATUS,sta);
    }
    if(MAX_RT)
    {
      flag_r=0;
      RX_Mode();
      SPI_RW_Reg(STATUS,sta);
    }
    IRQEINT();*/
}
}

lgymilu 发表于 2010-12-21 10:04:17

突然出现了这个奇怪的问题,很不理解啊……请高手指教!

lgymilu 发表于 2010-12-21 11:26:42

调试了一下,发现问题出在SPI_Read_Buf(RD_RX_PLOAD,rx_buf,20);    使RX_DR置位了所以能继续下一次接收,可接收缓存还是不能清除,所以我串口收到的数应该是第一次就收到的……可是发送端不发送了,这边标志位也没了也就不发送了……

zhanmcu 发表于 2011-2-13 23:10:57

查看下FIFO_STATUS是否为空 不为空说明还有数据 不读的话可以强制刷新BUF

rfinchina2011 发表于 2011-2-13 23:41:56

发送完后一定要清下

点击此处下载 ourdev_612616Z6NMKL.pdf
(文件大小:716K) (原文件名:UTC-1212无线模块使用文档2.0.pdf)
点击此处下载 ourdev_612617SAH7NP.pdf
(文件大小:1.18M) (原文件名:UTC-2303使用手册2.0.pdf)
点击此处下载 ourdev_612030EKE7Y1.rar(文件大小:11K)
(原文件名:UTC1212-C51参考程序.rar)
点击此处下载 ourdev_612031XYUJW9.rar(文件大小:4.63M)
(原文件名:UTC2303驱动.rar)
点击此处下载 ourdev_612032HBJX03.rar(文件大小:311K)
(原文件名:UTC-121配置软件.rar)
页: [1]
查看完整版本: NRF24L01接收问题,接收寄存器不能清零,标志位不置位