找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2129|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

nRF24L01程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:201073 發(fā)表于 2017-5-15 20:31 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式

#include <reg51.h>
#include <intrins.h>
#include "spi.h"
#include "ds18b20.h"

/***************************************************/
//#define uchar unsigned char
//#define uint unsigned int
#define TX_ADR_WIDTH    5   // 收發(fā)地址5 字節(jié)寬TX(RX)
#define TX_PLOAD_WIDTH  20  // 發(fā)送數(shù)據(jù)包20 字節(jié)

uchar const TX_ADDRESS[TX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01};// 定義發(fā)送地址

uchar rx_buf[TX_PLOAD_WIDTH];//接收緩沖數(shù)組
uchar tx_buf[TX_PLOAD_WIDTH];//發(fā)送緩沖數(shù)組
uchar flag;//中斷標(biāo)志
/**************************************************/
//nRF24L01 SPI口定義//
sbit CE =  P1^7;
sbit CSN=  P1^6;
sbit SCK=  P1^5;
sbit MOSI= P1^4;
sbit MISO= P1^3;
sbit IRQ = P3^2;

sbit S2=   P1^2;//發(fā)送按鈕
sbit LEDG= P3^7;
sbit LEDR= P3^5;

/**************************************************/
uchar         bdata sta;
sbit        RX_DR        =sta^6;
sbit        TX_DS        =sta^5;
sbit        MAX_RT        =sta^4;

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

/**************************************************
函數(shù): init_nRF24L01();
說明:
  nRF24L01待機(jī)模式,
  Spi 不能,Spi 時(shí)鐘線高
/**************************************************/
void init_nRF24L01(void)
{
        CE=0;                        // 片選使能
        CSN=1;                        // Spi 禁止        
        SCK=0;                        // Spi 時(shí)鐘初始化

}

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

/**************************************************
函數(shù): init_int0();
說明:
  開int0中斷;
/**************************************************/
void init_int0(void)
{
        EA=1;
        EX0=1;        //開int0中斷.
}

/**************************************************/
void delay_ms(unsigned int x) //ms延時(shí)
{
    unsigned int i,j;
    i=0;
    for(i=0;i<x;i++)
    {
       j=108;
           ;
       while(j--);
    }
}
/**************************************************/

/**************************************************
函數(shù): SPI_RW();
說明:
  寫單字節(jié)到nRF24L01, 同時(shí)返回從nRF24L01讀出的一字節(jié)
/**************************************************/
uchar SPI_RW(uchar byte)
{
        uchar bit_ctr;
           for(bit_ctr=0;bit_ctr<8;bit_ctr++)   // 輸出 8-bit
           {
                   MOSI = (byte & 0x80);         // 輸出字節(jié)到MOSI, 最高位開始
                   byte = (byte << 1);           // 左移一位
                   SCK = 1;                      // 時(shí)鐘置高
                   byte |= MISO;                         // 由MISO讀入1bit
                   SCK = 0;                              // 時(shí)鐘置低
           }
    return(byte);                             // 返回讀入的字節(jié)
}
/**************************************************/

/**************************************************
函數(shù): SPI_RW_Reg();
說明:
  寫一字節(jié)值'value'到地址為'reg'的寄存器
/**************************************************/
uchar SPI_RW_Reg(BYTE reg, BYTE value)
{
        uchar status;

          CSN = 0;                   // SPI 使能
          status = SPI_RW(reg);      // 選寄存器,并讀狀態(tài)值
          SPI_RW(value);             // 寫該寄存器        
          CSN = 1;                   // SPI禁止

          return(status);            // 返回狀態(tài)值
}
/**************************************************/

/**************************************************
函數(shù): SPI_Read();
說明:
  從 nRF24L01內(nèi)地址為 'reg'的寄存器讀出一字節(jié)數(shù)據(jù)
/**************************************************/
BYTE SPI_Read(BYTE reg)
{
        BYTE reg_val;

          CSN = 0;                // SPI 使能
          SPI_RW(reg);            // 選寄存器
          reg_val = SPI_RW(0);    // 讀寄存器
          CSN = 1;                // SPI 禁止

          return(reg_val);        // 返回寄存器值
}
/**************************************************/

/**************************************************
函數(shù): SPI_Read_Buf();
說明:
  從地址為'reg'的寄存器中讀出若干字節(jié)的數(shù)據(jù)到數(shù)組,例如從
  RX payload 中讀出數(shù)據(jù)包。
/**************************************************/
uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
        uchar status,byte_ctr;

          CSN = 0;                                    // SPI 使能
          status = SPI_RW(reg);                       // 選寄存器,并讀狀態(tài)值

          for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
            pBuf[byte_ctr] = SPI_RW(0);    // 由nRF24L01讀出若干字節(jié)數(shù)據(jù)到數(shù)組

          CSN = 1;                           // SPI 禁止

          return(status);                    // 返回狀態(tài)字
}
/**************************************************/

/**************************************************
函數(shù): SPI_Write_Buf();
說明:
  把緩沖數(shù)組'*pBuf'中的數(shù)據(jù)寫入nRF24L01中的TX payload
/**************************************************/
uchar SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
        uchar status,byte_ctr;

          CSN = 0;                 // SPI 使能
          status = SPI_RW(reg);    // 選寄存器,并讀狀態(tài)值
          for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)// 把buffer(*pBuf)中的字節(jié)寫入
            SPI_RW(*pBuf++);
          CSN = 1;                 // SPI 禁止
          return(status);          // 返回狀態(tài)字節(jié)
}
/**************************************************/

/**************************************************
函數(shù): RX_Mode();
說明:
  初始化nRF24L01 為RX Mode,設(shè)定接收地址、RX payload 長度,
  選擇RF 通道, 數(shù)據(jù)速率和LNA HCURR。然后置CE為高, 等待接收數(shù)據(jù)包
/**************************************************/
void RX_Mode(void)
{
        CE=0;
// 收發(fā)設(shè)置相同的地址
          SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
          SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // 使能自動(dòng)應(yīng)答Pipe0
          SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Pipe0使能
          SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // 選 射頻通道40
// 設(shè)置接收和發(fā)送 payload寬度相同
          SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);
// 發(fā)送功率:0dBm, 數(shù)據(jù)速率:2Mbps, LNA:HCURR
          SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);
// 置位 PWR_UP, 使能CRC(2 bytes) 和主接收Prim:RX. 使能RX_DR
          SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     
          CE = 1; // 接收使能

  //  器件已經(jīng)準(zhǔn)備好由發(fā)送方發(fā)來的16字節(jié)數(shù)據(jù)
  //  自動(dòng)應(yīng)答'3443101001', 重發(fā)次數(shù)為10, 射頻通道為 40,數(shù)據(jù)速率 = 2Mbps.

}
/**************************************************/

/**************************************************
函數(shù): TX_Mode();
說明:
  初始化 nRF24L01 為TX mode, 設(shè)置 TX 地址、接收地址、自動(dòng)應(yīng)答,
  向TX payload寫入數(shù)據(jù), 選擇 RF 通道, 數(shù)據(jù)速率和 TX 發(fā)送功率.
  加電, CRC(2 字節(jié)) 使能, 發(fā)送為PRIM:TX.當(dāng)CE置高(>10us)之后
即發(fā)送數(shù)據(jù)包,然后轉(zhuǎn)入接收模式等待接收方的應(yīng)答。
/**************************************************/
void TX_Mode(void)
{
        CE=0;
        // 寫發(fā)送地址TX_Address 到nRF24L01
          SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
// 自動(dòng)應(yīng)答的接收地址RX_Addr0 和 TX_Adr 相同
          SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
          SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 寫數(shù)據(jù)到 TX payload

          SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // 使能自動(dòng)應(yīng)答到Pipe0
          SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // 使能Pipe0
          SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10次重發(fā)
          SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // 選射頻通道 40
// 發(fā)送功率:0dBm, 數(shù)據(jù)速率:2Mbps, LNA:HCURR
          SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   
// 置位 PWR_UP, 使能CRC(2 bytes) 和主發(fā)送Prim:TX. 使能MAX_RT 和 TX_DS
          SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);     

        CE=1;

}

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

/**************************************************
函數(shù): Send_uart();
說明:
  寫數(shù)據(jù)到串口 SBUF
/**************************************************/
void Send_uart(uchar x)
{
        SBUF=x;// write data x to SBUF
        while(TI==0);
        TI=0;
}

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

/**************************************************
函數(shù): display();
說明:
  在 LED數(shù)碼管上顯示數(shù)據(jù)
/**************************************************/
void display(uchar idata *p)
{
  uchar code table[23]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x8c,0xc1,0x89,0xc7,0x91,0xbf,0xff};
//共陽碼表,前16位是0~F,后面的如下:
//0x8c,0xc1,0x89,0xc7,0x91,0xbf,0xff
//P,   U,   H,   L,   Y,   -,   不顯示
//10H, 11H, 12H, 13H, 14H, 15H, 16H
  uchar adc,i;
  for(i=0;i<4;i++)
  { adc=table[*p];//segement code
        if(i==1)
        {
                adc=adc-0x80;//加小數(shù)點(diǎn)
        }
    Send_uart(adc);
    p++;
  }
}

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

/**************************************************
函數(shù): CheckButtons();
說明:
  檢查按鈕 ,若按鈕按下讀ds18b20溫度值并發(fā)送,綠燈閃亮。
  發(fā)送后清TX_DS中斷標(biāo)志并轉(zhuǎn)入接收模式 RX Mode;
/**************************************************/
void CheckButtons()
{

        if(S2==0)
                {
                        delay_ms(10);
                        if(S2==0)
                        {

                                Do_Temp();//讀溫度數(shù)據(jù)
                                tx_buf[0]=dis_buf[0];        // 存溫度數(shù)據(jù)到顯示緩存
                                tx_buf[1]=dis_buf[1];
                                tx_buf[2]=dis_buf[2];        
                                tx_buf[3]=dis_buf[3];
                                TX_Mode();                        // 發(fā)送模式
                                display(dis_buf);         //在LED顯示溫度數(shù)據(jù)
                                // 清中斷標(biāo)志(TX_DS)
                                SPI_RW_Reg(WRITE_REG+STATUS,SPI_Read(READ_REG+STATUS));
                                RX_Mode();                        // 轉(zhuǎn)入接收模式

                                LEDG=0;        //綠LED:亮
                                delay_ms(200);
                                LEDG=1;        //綠LED:滅        



                        }
                }

}
/**************************************************/

/**************************************************
函數(shù): main();
說明:
  主函數(shù);
/**************************************************/
void main(void)
{

        init_nRF24L01();// 初始化nRF24L01
        init_int0();        // int0 中斷使能
        RX_Mode();                // 接收模式
        while(1)
        {
                CheckButtons(); // 等待發(fā)送按鍵并發(fā)送
                if(flag)                // 是否收到
                {
                        flag=0;                //收到標(biāo)志清零
                        LEDR=0;                //紅LED:亮
                        delay_ms(200);
                        LEDR=1;                //紅LED:滅

                        dis_buf[0]=rx_buf[0];//小數(shù)位
                        dis_buf[1]=rx_buf[1];//個(gè)位
                        dis_buf[2]=rx_buf[2];//十位
                        dis_buf[3]=rx_buf[3];//百位或負(fù)號(hào)
                        display(dis_buf);//在LED顯示收到的溫度值

                }
        }
}
/**************************************************/

/**************************************************
函數(shù): ISR_int0() interrupt 0;
說明:中斷服務(wù)函數(shù)
  若 RX_DR=1,由RX_FIFO 讀數(shù)據(jù)包并置位flag;
/**************************************************/
void ISR_int0(void) interrupt 0
{
        sta=SPI_Read(STATUS);        // 讀狀態(tài) STATUS'值
        if(RX_DR)                                // 如果有接收數(shù)據(jù)中斷(RX_DR)
        {        // 由 RX_FIFO 緩存讀數(shù)據(jù)
                SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);
                flag=1;
        }
        if(MAX_RT) // 如果重發(fā)次數(shù)超過(MAX_RT)
        {
                SPI_RW_Reg(FLUSH_TX,0); //FLUSH_TX清零
        }
// 清零RX_DR 或 TX_DS 或 MAX_RT 中斷標(biāo)志
                SPI_RW_Reg(WRITE_REG+STATUS,sta);
}


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:139761 發(fā)表于 2017-7-1 20:41 | 只看該作者
樓主有頭文件程序嗎
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表