浚凡小子 发表于 2016-8-13 00:36

求助NRF24L01不能通信

/********** 头文件 *****************************************/
#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)

//1mst=(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_A0X01                      //
#define SMG_B0X02                      //
#define SMG_C0X04                      //
#define SMG_D0X08                      //
#define SMG_E0X10                      //
#define SMG_F0X20                      //
#define SMG_G0X40                      //
#define SMG_H0X80                      //                     
//-----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;

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_long2000   // 长响

//------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=SMG_K_NUM;
        SMG_Data=SMG_K_NUM;
        SMG_Data=SMG_K_NUM;
        //-----------------------------------------
        Clr_K_ALLSMG();
        SMG_Com++;
        if(SMG_Com>3)SMG_Com=0;
        switch(SMG_Com)
        {
                case 0:{Display_A(SMG_Data); com1=0;}break;
                case 1:{Display_A(SMG_Data); com2=0;}break;
                case 2:{Display_A(SMG_Data); com3=0;}break;       
                case 3:{Display_A(SMG_Data); 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=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 数组数据               
//
//输出参数:               
//**********************************************************
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               
//**********************************************************
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={0x11,0x22,0x33,0x44,0x55};
        uchar check_out_buf={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 == 0x11)&&\
           (check_out_buf == 0x22)&&\
           (check_out_buf == 0x33)&&\
           (check_out_buf == 0x44)&&\
           (check_out_buf == 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={1,2,3,4};
        uchar Rx_Buf={5,6,7,8};
        InitSys();               // Sys initial
        SPI_Init();            // 初始化SPI口(采用IO模拟SPI通信)
        while(NRF24L01_Check()); // 等待检测到NRF24L01,程序才会向下执行
        NRF24L01_RT_Init();      // 配置NRF24L01为收收模式
        while(1)                           //
        {   _clrwdt();                     // Clear dog
               
      KeyeDeal();               
                DispDeal();                      // 显示处理
                OuteDeal();
               
                //NRF24L01_TxPacket(Tx_Buf);   // 无线发送数据(部分)
                NRF24L01_RxPacket(Rx_Buf);//无线接收数据(部分)
      TimeData=Rx_Buf;                //接收数据并显示
        }                                    //
}                                        //

浚凡小子 发表于 2016-8-13 00:38

各位前辈:
    以上是我写的NRF24L01的通信程序,能否帮我看看是那里出了问题,两个板不能互相通信.
   一个板负责发送数据,另一个板负责接收数据并显示出来.
    现在的问题是,不知道是发送端还接收端有问题。
    能否帮我分板一下,多谢!
页: [1]
查看完整版本: 求助NRF24L01不能通信