求助NRF24L01不能通信

[复制链接]
739|2
 楼主 | 2016-8-13 00:36 | 显示全部楼层 |阅读模式
/********** 头文件 *****************************************/
#include "./head/INTRINS.H"
#include "./head/SH79F081A.h"
#include "./head/global.h"
#include "./head/nRF24L01.h"

//***********************************************************
#define HIBYTE(var)     ((uchar)(var>>8))
#define LOBYTE(var)     ((uchar)var&0xff)

//1ms  t=(65536-(12300000/(除以需要的频率)))
//#define CLOCK_1MS     (65536-12300) //(递增计数)
//#define CLOCK_2MS     (65536-24600) //2ms
//#define CLOCK_200us   (65536-2460)  //200us =5KHz  
#define CLOCK_250us   (65536-1530)       //250us =4KHz

/************ <time flag> ************************/
bit     SDian_bz;
bit     T_2ms_bz;                        //
bit     T_500ms_bz;                      //
bit     T_1s_bz;                         //
bit     T_3s_bz;                         //
uchar   T_2msCnt;                        //
uchar   T_500msCnt;                      //

/*** NUM TAB *************************************/
#define SMG_A  0X01                      //
#define SMG_B  0X02                      //
#define SMG_C  0X04                      //
#define SMG_D  0X08                      //
#define SMG_E  0X10                      //
#define SMG_F  0X20                      //
#define SMG_G  0X40                      //  
#define SMG_H  0X80                      //                     
//-----disp ------------------------------------------
const uchar code SMG_K_NUM[] ={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};

/*** < Control/out > *****************************/
uchar   SMG_Com;                         //
ulong   TimeData;                        //  
uchar   SMG_Data[4];

sbit    com1      =P0^6;                 //com1 Prot
sbit    com2      =P0^4;                 //com2 Prot
sbit    com3      =P2^5;                 //com3 Prot
sbit    com4      =P1^5;                 //com4 Prot
sbit    SMG_A1    =P1^4;                 //segA bit
sbit    SMG_B1    =P1^3;                 //segB bit
sbit    SMG_C1    =P0^2;                 //segC bit
sbit    SMG_D1    =P0^3;                 //segD bit
sbit    SMG_E1    =P0^5;                 //segE bit
sbit    SMG_F1    =P0^7;                 //segF bit
sbit    SMG_G1    =P1^2;                 //segG bit

//**** 蜂鸣变量定义 ********************************
sbit    BeepBit=P3^2;  // 蜂鸣端口   
uint    r_buz_time=0;  // r_buz_time=C_short
uchar   B_Count=55;    // 稍停一会儿
uchar        r_buz_cnt=1;   // 响几次(上电长鸣)
#define        C_short        500    // 短响
#define C_long  2000   // 长响

//------key ---------------------------------------
uchar   XiaoDouCnt;
uchar   KeyVal;
uchar   KeyRecord;
bit     Key_bz;
bit     RX_TX_Roll_bz;

//*************************************************
//函数声明-----------------------------------------
//*************************************************
void TimeDeal(void);                     //  
void DispDeal(void);                     //     
void AdcnDeal(void);                     //      
void LaodDeal(void);
void Delayus(uint k);                    //
void KeyeDeal(void);
void KeyeScan(void);
void KeyPress(void);
void Clr_K_ALLSMG(void);                 //  
void Display_A(uchar date);


//*************************************************
//---------- < 延时100us > ------------------------
//*************************************************
void Delayus(uint k)                     //  
{  while(k--);
}                                        //

//*************************************************
//----------< 系统初始化 >------------------------
//*************************************************
void InitSys(void)                       //
{   Delayus(2000);                       //
        //---------------------------------------------
        //sysclock config
        //---------------------------------------------
        RSTSTAT=Bin(00000000);               // 上电复位
        EA=0;                                // disable all interrupt
        CLKCON=Bin(00000000);                // RC Fsys(00=12.3MHz,01=12.3M/2,10=12.3/4,11=12.3/12)
        INSCON=Bin(00000000);                //   
                    
        //---------------------------------------------
        // I/O Prot config   
        // Prot (1=上拉)(0=取消上拉)         (1=输出)(0=输入)  
        //---------------------------------------------
        P0PCR=Bin(00000000);                 // 上拉register   
        P1PCR=Bin(00000000);                 //
        P2PCR=Bin(11011010);                 //
        P3PCR=Bin(00000010);                 //

        P0OS =Bin(11111111);                 // input /output register
        P0CR =Bin(11111111);                 // P0.2 AD
        P1CR =Bin(11111111);                 // 1.6BUZZ
        P2CR =Bin(00100101);                 //
        P3CR =Bin(11111101);                 //
       
        P0   =Bin(00000000);                 // data prot register
        P1   =Bin(00000000);                 //
        P2   =Bin(11011000);                 //
        P3   =Bin(00100100);                 //
          
        //------------------------------------------
        // timer 2 config
        //------------------------------------------
        T2CON=Bin(00000000);                 // 方式1(自动重载16位数据)
        T2MOD=Bin(00000000);                 // 12.3MHz(递增计数)
        TL2=LOBYTE(CLOCK_250us);             // 设置低位寄存器
        TH2=HIBYTE(CLOCK_250us);             // 设置高位寄存器
        RCAP2L=LOBYTE(CLOCK_250us);          // 设置重载寄存器
        RCAP2H=HIBYTE(CLOCK_250us);          //
        TF2=0;                               // clear flowfalg
        TR2=1;                               // start timer2
        ET2=1;                               // enable timer2 interrupt

        //-------------------------------------------
        EA=1; //Enadle interrupt  
        //-------------------------------------------

}                                        //

void Clr_K_ALLSMG(void)                  // 共阴
{
        com1=1;                              //
        com2=1;                              //
        com3=1;                              //
        com4=1;                              //
        SMG_A1=0;                            //
        SMG_B1=0;                            //
        SMG_C1=0;                            //
        SMG_D1=0;                            //
        SMG_E1=0;                            //
        SMG_F1=0;                            //
        SMG_G1=0;                            //
}
void Display_A(uchar date)               //
{
    if(date & SMG_A) SMG_A1=1;           // A
        else SMG_A1=0;
        if(date & SMG_B) SMG_B1=1;           // B
        else SMG_B1=0;       
        if(date & SMG_C) SMG_C1=1;           // C
        else SMG_C1=0;       
        if(date & SMG_D) SMG_D1=1;           // D
        else SMG_D1=0;       
        if(date & SMG_E) SMG_E1=1;           // E
        else SMG_E1=0;       
        if(date & SMG_F) SMG_F1=1;           // F
        else SMG_F1=0;       
    if(date & SMG_G) SMG_G1=1;           // G
        else SMG_G1=0;
}

//********************************************
//---< 显示处理 >-----------------------------
//********************************************
void DispDeal(void)                      //
{               
        SMG_Data[0]=SMG_K_NUM[TimeData/100];
        SMG_Data[1]=SMG_K_NUM[TimeData%100/10];
        SMG_Data[2]=SMG_K_NUM[TimeData%100%10];
        //-----------------------------------------
        Clr_K_ALLSMG();
        SMG_Com++;
        if(SMG_Com>3)SMG_Com=0;
        switch(SMG_Com)
        {
                case 0:{Display_A(SMG_Data[0]); com1=0;}break;
                case 1:{Display_A(SMG_Data[1]); com2=0;}break;
                case 2:{Display_A(SMG_Data[2]); com3=0;}break;       
                case 3:{Display_A(SMG_Data[3]); com4=0;}break;
                default:{_nop_();_nop_();_nop_();_nop_();}break;
        }       
}                                                 //                                       

//**********************************************************
//函数功能:初始化硬件SPI口
//输入参数:
//
//输出参数:
//**********************************************************
void SPI_Init(void)
{       
        NRF_CE=0;                        // 待机模式1   
        NRF_CSN=1;                       //
        NRF_CLK=0;                       //
        NRF_IRQ=1;                             //
}

//**********************************************************
//函数功能:SPI数据收发函数
//输入参数:data
//
//输出参数: date
//**********************************************************
uchar SPI_RW(uchar date)
{
        uchar i;
        for(i=0;i<8;i++)                 // 循环8次
        {
                if(date&0x80) NRF_MOSI=1;
                else NRF_MOSI=0;             // byte最高位输出到MOSI
                date<<=1;                    // 低一位移位到最高位
                NRF_CLK=1;                   // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据
                if(NRF_MISO) date|=0x01;     // 读MISO到byte最低位
                NRF_CLK=0;                         // SCK置低
        }
        return(date);                        // 返回读出的一字节
}

//**********************************************************
//函数功能:读24L01的寄存器值
//输入参数:reg   寄存器地址   len 数组字节长度
//         *pBuf 读出寄存器值的存放数组     
//输出参数: status 状态值
//**********************************************************
uchar NRF24L01_Read_Buf(uchar reg,uchar *pBuf,uchar len)
{
        uchar status,u8_ctr;
        NRF_CSN=0;                        // CSN=0      
          status=SPI_RW(reg);               // 发送寄存器地址,并读取状态值             
        for(u8_ctr=0;u8_ctr<len;u8_ctr++)
        pBuf[u8_ctr]=SPI_RW(0XFF);        // 读出数据
        NRF_CSN=1;                        // CSN=1
          return status;                    // 返回读到的状态值
}

//**********************************************************
//函数功能:写24L01的寄存器值
//输入参数:reg   寄存器地址   len 数组字节长度
//         *pBuf 读出寄存器值的存放数组     
//输出参数:
//**********************************************************
uchar NRF24L01_Write_Buf(uchar reg, uchar *pBuf, uchar len)
{
        uchar status,u8_ctr;
        NRF_CSN=0;                         //
          status = SPI_RW(reg);              // 发送寄存器值(位置),并读取状态值
          for(u8_ctr=0; u8_ctr<len; u8_ctr++)
        SPI_RW(*pBuf++);                   // 写入数据
        NRF_CSN=1;
          return status;                     // 返回读到的状态值
}                                                                                                    

//**********************************************************
//函数功能:写24L01的寄存器值
//输入参数:reg 要写的寄存器地址   value 给寄存器写的值
//              
//输出参数: status 状态值
//**********************************************************
uchar NRF24L01_Write_Reg(uchar reg,uchar value)
{
        uchar status;

        NRF_CSN=0;                         // CSN=0;   
          status = SPI_RW(reg);              // 发送寄存器地址,并读取状态值
        SPI_RW(value);                     //
        NRF_CSN=1;                         // CSN=1;

        return status;
}

//**********************************************************
//函数功能:读24L01的寄存器值         
//输入参数: reg  要读的寄存器地址               
//
//输出参数: value 读出寄存器的值               
//**********************************************************
uchar NRF24L01_Read_Reg(uchar reg)
{
        uchar value;

        NRF_CSN=0;                         // CSN=0;   
          SPI_RW(reg);                       // 发送寄存器值(位置),并读取状态值
        value = SPI_RW(NOP);
        NRF_CSN=1;                         // CSN=1;

        return value;
}

//**********************************************************
//函数功能:24L01发送一个字节数据        
//输入参数: Txbuf[0] 数组数据               
//
//输出参数:                 
//**********************************************************
void NRF24L01_TxPacket(uchar *txbuf)
{
     NRF_CE=0;//CE拉低,使能24L01配置
     NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//装载接收端地址 低5位地址
     NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//装载数据 1个字节(1~32个字节)
         NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e); //发送模式
         NRF_CE=1;//CE置高,使能发送       
         Delayus(10); //10US
}

//**********************************************************
//函数功能:24L01接收一个字节数据        
//输入参数:              
//
//输出参数: Txbuf[0]               
//**********************************************************
void NRF24L01_RxPacket(uchar *rxbuf)
{   
         uchar state;
         NRF_CE=0;//CE置高,使能发送       
         NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0f); //接收模式
         NRF_CE=1;//CE置高,使能发送       
         Delayus(100);
       
         state=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值  
         if(state & RX_DR)
         {   NRF_CE=0;//CE置高,使能发送       
             NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,TX_PLOAD_WIDTH); //把数据从NRF24L01当中读出
             NRF24L01_Write_Reg(WRITE_REG+STATUS,state);
         }// 接收到数据后,RX_DR/TX_DS/MAX_RT都置高为1,写1清中断状态标志
}

//**********************************************************
//函数功能:检测24L01是否存在      
//输入参数:              
//
//输出参数: 1=不存在   0=存在                 
//**********************************************************
uchar NRF24L01_Check(void)
{
        uchar check_in_buf[5]={0x11,0x22,0x33,0x44,0x55};
        uchar check_out_buf[5]={0x00};

        NRF_CE=0;//NRF24L01-处于待机模式
        NRF24L01_Write_Buf(WRITE_REG+TX_ADDR, check_in_buf, 5);//把数据写入NRF24L01中
        NRF24L01_Read_Buf(READ_REG+TX_ADDR, check_out_buf, 5); //把数据从NRF24L01当中读出

        if((check_out_buf[0] == 0x11)&&\
           (check_out_buf[1] == 0x22)&&\
           (check_out_buf[2] == 0x33)&&\
           (check_out_buf[3] == 0x44)&&\
           (check_out_buf[4] == 0x55))return 0;
        else return 1;
}       

//**********************************************************
//函数功能:24L01 模块初始化      
//输入参数: RF通道,收发地址,收发数据宽度,功率            
//
//输出参数:                  
//**********************************************************
void NRF24L01_RT_Init(void)
{       
        NRF_CE=0;        //NRF24L01-处于待机模式
        NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,5);//写TX节点地址
        NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,RX_ADDRESS,5); //设置TX节点地址,主要为了使能ACK                     
        NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);     //使能通道0的自动应答   
        NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址  
        NRF24L01_Write_Reg(WRITE_REG+RF_CH,0);        //设置RF通道为0
        NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x07);  //0db增益,1Mbps
    NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,TX_PLOAD_WIDTH);    //选择通道0的有效数据宽度 32
        NRF_CE=1;        // NRF24L01-为接收模式
}


void KeyeScan(void)
{   
        if(!P2_7)                          // 10011
        {   KeyVal|=0x01;
            return;                        // Yes key press       
        }        else KeyVal&=~0x01;            //
       
    if(!P2_6)                          // 10011
        {   KeyVal|=0x02;
            return;                        // Yes key press       
        }        else KeyVal&=~0x02;            //
       
    if(!P2_4)                          // 10011
        {   KeyVal|=0x03;
            return;                        // Yes key press       
        }        else KeyVal&=~0x03;            //
       
    if(!P2_3)                          // 10011
        {   KeyVal|=0x04;
            return;                        // Yes key press       
        }        else KeyVal&=~0x04;            //
       
}

void KeyeDeal(void)
{
        //-------------------------------------------------------------
        if(XiaoDouCnt>25)                  //
        {   XiaoDouCnt=0;                       //
            //------------------------------------------------------------
                 KeyeScan();                                   //         
                //----EKY WARM------------------------------------------------
                if(KeyVal == KeyRecord)        //
                {   if(KeyVal==0)              //
                        {   Key_bz=0;              // 松开清0
                                KeyRecord=KeyVal;           //                                             
                    }                          
                        else                       
                        {   if(Key_bz) KeyRecord = KeyVal;                                                                                             
                                else                   //
                                {   Key_bz=1;          //                                                                        
                                        KeyPress();        //
                                }                      //
                        }                               //
                }else KeyRecord=KeyVal;        //
        }else         XiaoDouCnt++;              //        
}

void KeyPress(void)
{  
    if(KeyVal==0x02)
        {        r_buz_cnt=1;
                if(RX_TX_Roll_bz)
                {    RX_TX_Roll_bz=0;
                         NRF_CE=0;
                     NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0f);    //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
             NRF_CE=1;                                   //接收模式
            }
        else
                {    RX_TX_Roll_bz=1;
                     NRF_CE=0;
                     NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e);  //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
             NRF_CE=1;                                //发送模式
                }                       
        }
        else if(KeyVal==0x01)
        {   r_buz_cnt=1;
                TimeData++;
                 if(TimeData>99)TimeData=0;               
        }
        else if(KeyVal==0x03)
        {    r_buz_cnt=1;
                 if(TimeData==0)TimeData=0;
                 else TimeData--;
        }
        else if(KeyVal==0x04)
        {        r_buz_cnt=1;
        }
}


void OuteDeal(void)
{
        //---- BUZZ Ctrol --------------------------------------------
        if(r_buz_cnt!=0)                               //
        {   if(r_buz_time==0)                          //
                {   if(B_Count==0)                         // 稍停顿
                        {   B_Count=25;                        // 短响延时
                            r_buz_cnt--;                       // 响几声  
                            if(!SDian_bz) r_buz_time=C_long;   // 上电长鸣一声 全屏点亮                                       
                            else r_buz_time=C_short;           //
                    }else B_Count--;                       //
                }                                          //
        }                                              //  
               
}
//********************************************
//---< Main Program >----------------------
//********************************************
void main(void)              //                  
{   
        uchar Tx_Buf[4]={1,2,3,4};
        uchar Rx_Buf[4]={5,6,7,8};
        InitSys();               // Sys initial
        SPI_Init();              // 初始化SPI口(采用IO模拟SPI通信)
        while(NRF24L01_Check()); // 等待检测到NRF24L01,程序才会向下执行
        NRF24L01_RT_Init();      // 配置NRF24L01为收收模式[0f=接收模式  0e=发送模式]
        while(1)                             //
        {   _clrwdt();                       // Clear dog
               
        KeyeDeal();               
                DispDeal();                      // 显示处理
                OuteDeal();
               
                //NRF24L01_TxPacket(Tx_Buf);     // 无线发送数据(部分)
                NRF24L01_RxPacket(Rx_Buf);//无线接收数据(部分)
        TimeData=Rx_Buf[0];                //接收数据并显示
        }                                    //  
}                                        //
 楼主 | 2016-8-13 00:38 | 显示全部楼层
各位前辈:
    以上是我写的NRF24L01的通信程序,能否帮我看看是那里出了问题,两个板不能互相通信.
     一个板负责发送数据,另一个板负责接收数据并显示出来.
    现在的问题是,不知道是发送端还接收端有问题。
    能否帮我分板一下,多谢!

使用特权

评论回复
 楼主 | 2016-8-13 00:40 | 显示全部楼层
头文件部分
#ifndef __NRF24L01_H__
#define __NRF24L01_H__

/**********  NRF24L01寄存器操作命令  ***********************/
#define READ_REG        0x00  //读配置寄存器,低5位为寄存器地址
#define WRITE_REG       0x20  //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD     0x61  //读RX有效数据,1~32字节
#define WR_TX_PLOAD     0xA0  //写TX有效数据,1~32字节
#define FLUSH_TX        0xE1  //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX        0xE2  //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL     0xE3  //重新使用上一包数据,CE为高,数据包被不断发送.
#define NOP             0xFF  //空操作,可以用来读状态寄存器         
/**********  NRF24L01寄存器地址   *************************/
#define CONFIG          0x00  //配置寄存器地址                             
#define EN_AA           0x01  //使能自动应答功能
#define EN_RXADDR       0x02  //接收地址允许
#define SETUP_AW        0x03  //设置地址宽度(所有数据通道)
#define SETUP_RETR      0x04  //建立自动重发
#define RF_CH           0x05  //RF通道
#define RF_SETUP        0x06  //RF寄存器
#define STATUS          0x07  //状态寄存器
#define OBSERVE_TX      0x08  // 发送检测寄存器
#define CD              0x09  // 载波检测寄存器
#define RX_ADDR_P0      0x0A  // 数据通道0接收地址
#define RX_ADDR_P1      0x0B  // 数据通道1接收地址
#define RX_ADDR_P2      0x0C  // 数据通道2接收地址
#define RX_ADDR_P3      0x0D  // 数据通道3接收地址
#define RX_ADDR_P4      0x0E  // 数据通道4接收地址
#define RX_ADDR_P5      0x0F  // 数据通道5接收地址
#define TX_ADDR         0x10  // 发送地址寄存器
#define RX_PW_P0        0x11  // 接收数据通道0有效数据宽度(1~32字节)
#define RX_PW_P1        0x12  // 接收数据通道1有效数据宽度(1~32字节)
#define RX_PW_P2        0x13  // 接收数据通道2有效数据宽度(1~32字节)
#define RX_PW_P3        0x14  // 接收数据通道3有效数据宽度(1~32字节)
#define RX_PW_P4        0x15  // 接收数据通道4有效数据宽度(1~32字节)
#define RX_PW_P5        0x16  // 接收数据通道5有效数据宽度(1~32字节)
#define FIFO_STATUS     0x17  // FIFO状态寄存器

/****** STATUS寄存器bit位定义 ***************************/
#define MAX_RT              0x10  // 达到最大发送次数中断
#define TX_DS               0x20  // TX发送完成中断
#define RX_DR               0x40  // 接收到数据中断

/********* 24L01发送接收数据宽度定义        ********************/
#define TX_ADR_WIDTH    5     // 5字节地址宽度
#define RX_ADR_WIDTH    5     // 5字节地址宽度
#define TX_PLOAD_WIDTH  4    // 1~32字节有效数据宽度
#define RX_PLOAD_WIDTH  4    // 1~32字节有效数据宽度

/****** nRF24L01无线模块通信口定义 ***********************/
sbit    NRF_CE         =P3^0;
sbit    NRF_CSN        =P3^5;
sbit    NRF_MISO       =P2^1;
sbit    NRF_MOSI       =P2^2;
sbit    NRF_CLK        =P2^0;
sbit    NRF_IRQ        =P3^1;
sbit    STA_LED        =P1^5; // 通信指示灯

const uchar TX_ADDRESS[TX_ADR_WIDTH]={0x68,0x86,0x66,0x88,0x28};
const uchar RX_ADDRESS[RX_ADR_WIDTH]={0x68,0x86,0x66,0x88,0x28};
//--------------------------------------------------------------------
#endif

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

关闭

热门推荐上一条 /7 下一条

在线客服 快速回复 返回顶部 返回列表