OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3109|回复: 1

NRF24L01 发送不更新

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
25
金钱
25
注册时间
2015-11-8
在线时间
0 小时
发表于 2015-11-8 11:37:31 | 显示全部楼层 |阅读模式
5金钱
<span style="font-family:Simsun;line-height:normal;background-color:#E8E8E8;">楼主及各位高手你们好: &nbsp;我的&nbsp;nRF24L01 收发都正常。传送的数据超过32字节,分两次发。问题是新的数据发出后,收到的还是前一次的数据。要<br />
发二次或三次才能收到新数据。如有空请看看问题出在哪儿,
<div   style="background-color:#E8E8E8;">
[mw_shl_code=c,true]

/********************Copyright (c)*************************

*********************************************************/

#include  &lt;nrf24l01.h&gt;
//#include &lt;STC12C5A60S2.H&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

//**********
sbit CSN  = P0^5; //SPI片选端//就是SS
sbit CE   = P0^0;  //RX/TX模式选择端
sbit MOSI = P0^4;        //SPI主机输出从机输入端
sbit SCK  = P0^1;        //SPI时钟端
sbit IRQ  = P0^3; //可屏蔽中断端
sbit MISO = P0^2;        //SPI主机输出从机输出端

//sbit led = P0^0;
sbit BELL = P2^5;//P3^4;
//---------------



bdata uchar comm_f;              //系统标志
    sbit send_2_end  = comm_f^0;
    sbit rec_2_end   = comm_f^1;
    sbit send_1_end = comm_f^2;
    sbit rec_1_end  = comm_f^3;

    sbit t10ms_ov     = comm_f^4;
    sbit t_sec_ov     = comm_f^5;

    sbit wait_getad = comm_f^6;
    sbit tone_ctr = comm_f^7;


//*************************************************

void Delay_ms(uchar x)                         //@33.1776MHz  1ms
{
        unsigned char i, j;
        while(x--)
        {
                i = 33;
                j = 66;
                do
                {
                        while (--j);
                } while (--i);
        }
}

void send_232(uchar ll)
{
    send_1_end = 0;
    send_pt  = 0;
    send_1_leg = ll;
        TI=1;
}

void sys_parameter_init()
{
        rec_pt=0;        //接收指针 =0
        send_1_end = 1;         //LCD 发送结束
}


//------------------
uchar SPI_RW(uchar byte)
{
        uchar bit_ctr;

           for(bit_ctr=0;bit_ctr&lt;8;bit_ctr++)   // output 8-bit
           {

                   MOSI = (byte &amp; 0x80);         // output 'byte', MSB to MOSI
                   byte = (byte &lt;&lt; 1);           // shift next bit into MSB..
                   SCK = 1;                      // Set SCK high..
                   byte |= MISO;                         // capture current MISO bit
                   SCK = 0;                              // ..then set SCK low again
           }
    return(byte);                             // return read byte
}


//-----------------------
void init_io(void)
{
        CE=0;                        // chip enable
        CSN=1;                        // Spi disable       
        SCK=0;                        // Spi clock line init high
}


/****************************************************************
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
/*描述:把pBuf缓存中的数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址
/********************************************************************/
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars) //reentrant
{
        uint status,i;
       
        CSN = 0;               //CSN置低,开始传输数据      
        status = SPI_RW(reg);  //选择寄存器,同时返回状态字
        Delay_ms(2);
        for(i=0; i&lt;uchars; i++)
                SPI_RW(*pBuf++);        //逐个字节写入nRF24L01
        CSN = 1;           //CSN拉高,结束数据传输
        return(status);    //返回状态寄存器
}


/***************************************************/
/*功能:NRF24L01读写寄存器函数
/*描述:写数据value到reg寄存器
/*************************************************************/
uint SPI_RW_Reg(uchar reg, uchar value)
{
        uchar status;
       
        CSN = 0;               // CSN置低,开始传输数据      CSN low, init SPI transaction
        status = SPI_RW(reg);  // 选择寄存器,同时返回状态字 select register
        SPI_RW(value);         // 然后写数据到该寄存器       ..and write value to it..
        CSN = 1;               // CSN拉高,结束数据传输      CSN high again
       
        return(status);        // 返回状态寄存器             return nRF24L01 status uchar
}


/***********************************
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
/***********************************/
void nRF24L01_TxPacket(uchar *nrf_s_buf)
{
        CE=0;    //StandBy I模式
        SPI_Write_Buf(WR_TX_PLOAD, nrf_s_buf,TX_PLOAD_WIDTH);     // 装载数据
        SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);   // IRQ收发完成中断响应,16位CRC,主发送
        CE=1;   //置高CE,激发数据发送
        Delay_ms(1);
}


/**********************************************/
/*函数:void SetRX_Mode(void)
/*功能:数据接收配置
/**********************************************/

void SetRX_Mode(void)
{
        CE=0;
          SPI_RW_Reg(WRITE_REG + RF_CH, 0x20);        // Select RF channel 40
          SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     // Set PWR_UP bit, enable CRC(2 bytes) &amp; Prim:RX. RX_DR enabled..
          CE = 1;
}



/****************************************/
/*NRF24L01初始化
/*****************************************/
void init_NRF24L01(void)
{
        CE=0;    // 芯片使能
        CSN=1;   // 禁止 SPI
        SCK=0;   // SPI时钟置低
        SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址       
        SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
        SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      //  频道0自动        ACK应答允许       
        SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 自动重发功能设置
        SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21  
        SPI_RW_Reg(WRITE_REG + RF_CH, 0x20);      //   设置信道工作为2.4GHZ,收发必须一致
        SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
        SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);                   //设置发射速率为1MHZ,发射功率为最大值0dB
        CE=1;
}


/******************************************************/
/*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
/*功能:数据读取后放入rx_buf接收缓冲区中
/******************************************************/
uchar nRF24L01_RxPacket(uchar* rx_buf)
{
    unsigned char revale=0;

        sta = SPI_Read(STATUS);        // 读取状态寄存其来判断数据接收状况
        if(RX_DR)                                // 判断是否接收到数据
        {
            CE = 0;                         //SPI使能
                SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
                revale =1;                        //读取数据完成标志
        }
        SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
        return revale;
}



/******************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI时序-----------从reg寄存器读一字节
/****************************************************/
uchar SPI_Read(uchar reg)
{
        uchar reg_val;
       
        CSN = 0;             //CSN置低,开始传输数据  CSN low, initialize SPI communication...
        SPI_RW(reg);         //选择寄存器             Select register to read from..
        reg_val = SPI_RW(0); //然后从该寄存器读数据   ..then read registervalue
        CSN = 1;             //CSN拉高,结束数据传输  CSN high, terminate SPI communication
       
        return(reg_val);     //返回寄存器数据         return register value
}



/**************************************/
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,
  reg:为寄存器地址,
  pBuf:为待读出数据地址,
  uchars:读出数据的个数
/*描述: 从reg寄存器读出bytes个字节,通常用来读取接收通道数据或接收/发送地址
/******************************************/
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
        uint status,i;
       
        CSN = 0;                 //CSN置低,开始传输数据   Set CSN low, init SPI tranaction
        status = SPI_RW(reg);    //选择寄存器,同时返回状态字 Select register to write to and read status uchar
        for(i=0;i&lt;uchars;i++)
                pBuf = SPI_RW(0); //逐个字节从nRF24L01读出
        CSN = 1;                 //CSN拉高,结束数据传输         
        return(status);          //返回状态寄存器      return nRF24L01 status uchar
}




/*******************************************/
/*  主程序   */
//////
/********************************************/

void main()
{
        uchar i;


        init_io();
        sys_ini();
        sys_parameter_init();

        Delay_ms(1);

        init_NRF24L01();
        CE=0;
        CSN=1;  
        SCK=0;
        IRQ=1;

        SetRX_Mode();

    while(1)
    {
                if(_testbit_(rec_1_end))
                {
                        if((uart_r_buf[0]==0x55)&amp;&amp;(uart_r_buf[1]==0xaa))
                        {
                                for(i=0;i&lt;32;i++)
                                        nrf_s_buf = uart_r_buf[2]+i;

                                SPI_RW_Reg(WRITE_REG+STATUS,0xff); // 清除所有中断标志
                                Delay_ms(1);
                                nRF24L01_TxPacket(nrf_s_buf);
                                nrf24_s =1;

                        }
                        else if((uart_r_buf[0]==0x33)&amp;&amp;(uart_r_buf[1]==0xcc))
                        {
                                for(i=0;i&lt;32;i++)
                                        nrf_r_buf = 0;
                                SetRX_Mode();
                        }
                        uart_s_buf[0] = uart_r_buf[0];
                        uart_s_buf[1] = uart_r_buf[2];
                        send_232(2);
                }
       
                if(!IRQ)
                {
                        IRQ = 1;
                        sta =  SPI_Read(READ_REG+STATUS);
                        if(RX_DR)
                        {
                                BELL = 0;
                                Delay_ms(30);
                                BELL = 1;
                                nRF24L01_RxPacket(nrf_r_buf);  //接收数据
                                for(i=0;i&lt;32;i++)
                                        uart_s_buf = nrf_r_buf;
                                send_232(32);
                                SPI_RW_Reg(WRITE_REG+STATUS,0xff); // 清除所有中断标志
                                for(i=0;i&lt;32;i++)
                                        nrf_r_buf = 0;
                               
                        }
                        else if(TX_DS &amp;&amp; nrf24_s)
                        {
                                nrf24_s = 0;
                                for(i=0;i&lt;32;i++)
                                        nrf_s_buf = 0xa0+i;
                                SPI_RW_Reg(WRITE_REG+STATUS,0xff); // 清除所有中断标志
                                nop;
                                nRF24L01_TxPacket(nrf_s_buf);
                        }
                        else
                        {
                                SPI_RW_Reg(WRITE_REG+STATUS,0xff); // 清除所有中断标志
                                SPI_RW(FLUSH_TX);
                        }

                        CE = 1;
                        Delay_ms(1);
                }
    }
}

//************************************
//  定时中断

//void Timer0Init(void)                   //100微秒@33.000MHz

void timer0_int(void) interrupt 1  using 3
{
    uint sec_count;

        TL0 = 0x00;                              //        5ms = 0xca00
        TH0 = 0x94;                            //         ca
                            
        if(sec_count &lt; 400)          // 30 为0.6秒
        sec_count++;
    else
    {
        t_sec_ov = 1;           // 1秒中断
        sec_count = 0;
    }
}

//--------- 串口一  中断-----------

void serial0_int ()interrupt 4 using 3
{
//          uchar i;
  if (_testbit_(RI))                   //测试与清零            JBC指令来测试位b并清零
    {
                uart_r_buf[rec_pt] = SBUF;
        rec_pt++;

                if(rec_pt &gt;= 3)
                {
                        rec_1_end = 1;
                        rec_pt = 0;
                }
    }

    if (_testbit_(TI))
    {
                nop;
        if (send_1_end)
        {
            TI = 0;
                        send_pt = 0;
            send_1_end = 1;
        }
        else
        {
            SBUF = uart_s_buf[send_pt];
               send_pt ++;
            if(send_pt == send_1_leg)
            {
                send_1_end = 1;          // 发送数据?
                send_pt  = 0;
                TI=0;
            }
        }
    }
}          


/***********************************************************************/
/*  单片机初始化   */
/**********************************************************************/
//   初始化 定时,串口,外中断等

void sys_ini()
{
        PCON &amp;= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位数据,可变波特率

        AUXR |= 0x04;                //独立波特率发生器时钟为Fosc,即1T 115200
        BRT = 0xF6;                    // 36.864M         =f6        115200

        AUXR |= 0x01;                //串口1选择独立波特率发生器为波特率发生器
        AUXR |= 0x10;                //启动独立波特率发生器

        AUXR &amp;= 0x7F;                //定时器时钟12T模式
    TMOD = 0X11;    //定时器0,1 为16位计数器.
        TL0 = 0x00;                //设置定时初值
        TH0 = 0x94;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时

        ET0 = 1;         // 定时器0        中断允许
    ES  = 1;         // 开串口1中断允许
    EADC = 1;         // AD 中断允许

        EA  = 1;
}

[/mw_shl_code]
</div>
<br />
多谢了。<br />
</span>

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2015-11-8 22:45:20 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 12:43

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表