新聞中心

        PIC16f1937 nRF24L01

        作者: 時(shí)間:2016-11-18 來(lái)源:網(wǎng)絡(luò) 收藏
        以下是NRF24L01的測(cè)試程序

        功能:主機(jī)按一下按鍵,發(fā)送一次數(shù)據(jù),對(duì)應(yīng)的LED指示燈會(huì)閃一下;從機(jī)接收到信號(hào)后對(duì)應(yīng)的LED指示燈會(huì)閃一下;

        本文引用地址:http://www.104case.com/article/201611/315600.htm

        HOST:

        //#include
        #include
        //const rom unsigned intCONFIG=0x0101;
        #define uint8 unsigned char
        #define uint16 unsigned int


        __CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_OFF&MCLRE_ON&CP_OFF
        &BOREN_OFF&CLKOUTEN_OFF&IESO_OFF&FCMEN_OFF);
        __CONFIG(WRT_OFF&VCAPEN_OFF&PLLEN_OFF&STVREN_OFF&BORV_19&LVP_OFF);
        #define CSN RE1
        #define IRQ RE0
        #define CE RE2
        #define MOSI RC4
        #define MISO RC5
        #define SCK RC3
        #define BACK_LED RC1
        #define KEY RB7


        #define TX_ADR_WIDTH 5
        #define RX_ADR_WIDTH 5
        #define RX_PLOAD_WIDTH 32
        #define TX_PLOAD_WIDTH 32
        uint8 TX_ADDRESS[TX_ADR_WIDTH]={0X34,0X43,0X10,0X10,0X01};
        uint8 RX_ADDRESS[RX_ADR_WIDTH]={0X34,0X43,0X10,0X10,0X01};
        uint8 Tx_Buf[TX_PLOAD_WIDTH]={0xff,0xee,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,
        0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb
        ,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xee,0xff};

        uint8 sta=0;//NRF24L01狀態(tài)

        /***********************寄存器指令***********************/
        #define READ_REG 0X00 //讀寄存器指令
        #define WRITE_REG 0X20 //寫寄存器指令
        #define RD_RX_PLOAD 0X61 //讀取接收數(shù)據(jù)指令
        #define WR_TX_PLOAD 0XA0 //寫待發(fā)數(shù)據(jù)指令
        #define FLUSH_TX 0XE1 //清除發(fā)送FIFO指令
        #define FLUSH_RX 0XE2 //清除接收FIFO指令
        #define REUSE_TX_PL 0XE3 //定義重復(fù)裝載數(shù)據(jù)指令
        //#define NOP 0XFF //保留
        /***********************寄存器地址***********************/
        #define CONFIG 0X00 //配置收發(fā)狀態(tài),CRC校驗(yàn)及收發(fā)響應(yīng)方式
        #define EN_AA 0X01 //自動(dòng)應(yīng)答功能設(shè)置
        #define EN_RXADDR 0X02 //可用信道設(shè)置
        #define SETUP_AW 0X03 //收發(fā)地址寬度設(shè)置
        #define SETUP_RETR 0X04 //自動(dòng)重發(fā)功能設(shè)置
        #define RF_CH 0X05 //工作頻率設(shè)置
        #define RF_SETUP 0X06 //發(fā)送速率,功耗功能設(shè)置
        #define STATUS 0X07 //狀態(tài)寄存器
        #define OBSERVE_TX 0X08 //發(fā)送監(jiān)測(cè)功能
        #define CD 0X09 //地址檢測(cè)
        #define RX_ADDR_P0 0X0A //頻道0接收數(shù)據(jù)地址
        #define RX_ADDR_P1 0X0B //頻道1接收數(shù)據(jù)地址
        #define RX_ADDR_P2 0X0C //頻道2接收數(shù)據(jù)地址
        #define RX_ADDR_P3 0X0D //頻道3接收數(shù)據(jù)地址
        #define RX_ADDR_P4 0X0E //頻道4接收數(shù)據(jù)地址
        #define RX_ADDR_P5 0X0F //頻道5接收數(shù)據(jù)地址
        #define TX_ADDR 0X10 //發(fā)送地址寄存器
        #define RX_PW_P0 0x11 // 接收頻道0接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define RX_PW_P1 0x12 // 接收頻道1接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define RX_PW_P2 0x13 // 接收頻道2接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define RX_PW_P3 0x14 // 接收頻道3接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define RX_PW_P4 0x15 // 接收頻道4接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define RX_PW_P5 0x16 // 接收頻道5接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define FIFO_STATUS 0X17 //FIFO棧入棧出狀態(tài)寄存器設(shè)置
        #define MAX_RT 0X10 //MAX_RTD在第5位|
        #define TX_DS 0X20 //TX_DS在第6位 | 在讀回STATUS時(shí)與其相與,就知道該位是否為1
        #define RX_DR 0X40 //RX_DR在第7位 |

        void delay(uint16 us)
        {
        while(us--);
        }

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

        void SpiInit()
        {
        TRISC=0X20;//設(shè)置RC3/SCK,RC5/SDO為輸出
        ANSELE=0X00;
        TRISE=0X01;//IRQ為輸入,CE,CSN為輸出
        //SSPSTAT=0XC0;
        //SSPCON3=0X00;
        //SSPCON1=0X20; //CKE=1,CKP=0;主模式,時(shí)鐘為FOSC/4
        //GIE=1;
        //PEIE=1;
        CSN=1;
        }
        /*uint8 SPI_RW(uint8 data)//通過(guò)SPI寫一個(gè)字節(jié)
        { uint8 status;
        CSN=0;
        SSPBUF=data;
        while(!BF);//當(dāng)SSPBUF被讀取后BF清0
        status=SSPBUF;
        SSPIF=0;
        CSN=1;
        return(status);
        }*/
        uint8 SPI_RW(uint8 byte)
        {
        uint8 bit_ctr;
        //DI();
        for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
        {
        if(byte & 0x80)
        MOSI = 1;
        else
        MOSI = 0;
        byte = (byte << 1); // shift next bit into MSB..
        SCK = 1; // Set nRF24L01_SCK high..
        if(MISO) byte |= 1;
        NOP();NOP();NOP();NOP();
        SCK = 0; // ..then set nRF24L01_SCK low again
        NOP();NOP();NOP();NOP();
        }
        //EI();
        return(byte); // return read byte
        }
        /*uint8 SPI_Read() //通過(guò)SPI讀一個(gè)字節(jié)
        {
        CSN=0;
        SSPBUF=0X00;//讀一個(gè)字節(jié)前必需先寫入一個(gè)字節(jié)
        while(!BF);
        CSN=1;
        return(SSPBUF);
        }*/
        uint8 SPI_Read(uint8 reg)
        {
        uint8 reg_val;
        CSN=0;
        SPI_RW(reg);
        reg_val=SPI_RW(0);
        CSN=1;
        return(reg_val);
        }
        uint8 SPI_RW_Reg(uint8 reg,uint8 value)//向寄存器寫一個(gè)字節(jié),同時(shí)返回狀態(tài)字
        {
        uint8 status;
        CSN=0;
        status=SPI_RW(reg);
        SPI_RW(value);
        CSN=1;
        return(status);
        }
        uint8 SPI_Write_Buf(uint8 reg,uint8 *pBuf,uint8 bytes)//向寄存器寫入一個(gè)字符串
        {
        uint8 status,byte_ctr;
        CSN=0;
        status=SPI_RW(reg);
        for(byte_ctr=0;byte_ctr {
        SPI_RW(*pBuf++);
        }
        CSN=1;
        return(status);
        }
        /***************************以上為SPI通訊程序**********************************/
        /******************************************************************************/
        //發(fā)送模式代碼
        void TX_MODE(void)
        {
        CE=0;
        SPI_RW_Reg(FLUSH_TX,0X00);
        SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
        SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
        SPI_RW_Reg(WRITE_REG+EN_AA,0X01);
        SPI_RW_Reg(WRITE_REG+EN_RXADDR,0X01);
        SPI_RW_Reg(WRITE_REG+SETUP_RETR,0X00);//禁止重發(fā)
        SPI_RW_Reg(WRITE_REG+RF_CH,40);
        SPI_RW_Reg(WRITE_REG+RF_SETUP,0X07);
        SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);
        SPI_RW_Reg(WRITE_REG+CONFIG,0X0e);
        CE=1;
        delay(50000);
        }
        void Transmit(uint8 *tx_buf)
        {
        CE=0;
        SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
        SPI_RW_Reg(FLUSH_TX,0X00);
        SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);
        SPI_RW_Reg(WRITE_REG+CONFIG,0X0E);
        CE=1;
        delay(100);
        }
        void main()
        {
        uint8 back=100;
        OSCCON=0X60;
        delay(100);
        //TRISA=0X00;
        SpiInit();
        TRISB=0X80;
        KEY=1;
        CE=0;
        CSN=1;
        SCK=0;
        IRQ=1;
        BACK_LED=0;
        //delay(50000);
        /* while(1)
        { //back=0x02;
        CE=0;
        SPI_RW_Reg(WRITE_REG+EN_AA,0X03);
        back=SPI_Read(EN_AA);
        if(back==0x03)
        {
        BACK_LED=1;
        }
        else
        {
        BACK_LED=0;
        }
        delay(50000);
        }*/
        TX_MODE();
        Transmit(Tx_Buf);
        delay(50000);
        sta=SPI_Read(READ_REG+STATUS);
        SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
        CE=0;
        while(1)
        {
        if(KEY==0)
        {
        delay(1000);
        if(KEY==0)
        {
        while(KEY==0);
        BACK_LED=1;
        delay(50000);
        BACK_LED=0;
        //TX_MODE();
        Transmit(Tx_Buf);
        delay(50000);
        sta=SPI_Read(READ_REG+STATUS);
        SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
        CE=0;
        }
        }
        }
        /*{

        delay(100);
        sta=SPI_Read(READ_REG+STATUS);
        if(sta&TX_DS)
        {
        BACK_LED=1;
        delay(1000);
        SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
        }
        if(sta&MAX_RT)
        {
        BACK_LED=0;
        delay(1000);
        SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
        }
        delay(50000);
        BACK_LED=0;
        delay(50000);

        }*/
        }

        SLAVE:

        //#include
        #include
        #define uint8 unsigned char
        #define uint16 unsigned int

        __CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_OFF&MCLRE_ON&CP_OFF
        &BOREN_OFF&CLKOUTEN_OFF&IESO_OFF&FCMEN_OFF);
        __CONFIG(WRT_OFF&VCAPEN_OFF&PLLEN_OFF&STVREN_OFF&BORV_19&LVP_OFF);
        #define CSN RE1
        #define IRQ RE0
        #define CE RE2
        #define MOSI RC4
        #define MISO RC5
        #define SCK RC3
        #define BACK_LED RC1


        #define TX_ADR_WIDTH 5
        #define RX_ADR_WIDTH 5
        #define RX_PLOAD_WIDTH 32
        #define TX_PLOAD_WIDTH 32
        uint8 TX_ADDRESS[TX_ADR_WIDTH]={0X34,0X43,0X10,0X10,0X01};
        uint8 RX_ADDRESS[RX_ADR_WIDTH]={0X34,0X43,0X10,0X10,0X01};
        uint8 Tx_Buf[TX_PLOAD_WIDTH]={0xff,0xee,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,
        0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb
        ,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xee,0xff};
        uint8 Rx_Buf[RX_PLOAD_WIDTH];

        uint8 sta=0;//NRF24L01狀態(tài)

        /***********************寄存器指令***********************/
        #define READ_REG 0X00 //讀寄存器指令
        #define WRITE_REG 0X20 //寫寄存器指令
        #define RD_RX_PLOAD 0X61 //讀取接收數(shù)據(jù)指令
        #define WR_TX_PLOAD 0XA0 //寫待發(fā)數(shù)據(jù)指令
        #define FLUSH_TX 0XE1 //清除發(fā)送FIFO指令
        #define FLUSH_RX 0XE2 //清除接收FIFO指令
        #define REUSE_TX_PL 0XE3 //定義重復(fù)裝載數(shù)據(jù)指令
        //#define NOP 0XFF //保留
        /***********************寄存器地址***********************/
        #define CONFIG 0X00 //配置收發(fā)狀態(tài),CRC校驗(yàn)及收發(fā)響應(yīng)方式
        #define EN_AA 0X01 //自動(dòng)應(yīng)答功能設(shè)置
        #define EN_RXADDR 0X02 //可用信道設(shè)置
        #define SETUP_AW 0X03 //收發(fā)地址寬度設(shè)置
        #define SETUP_RETR 0X04 //自動(dòng)重發(fā)功能設(shè)置
        #define RF_CH 0X05 //工作頻率設(shè)置
        #define RF_SETUP 0X06 //發(fā)送速率,功耗功能設(shè)置
        #define STATUS 0X07 //狀態(tài)寄存器
        #define OBSERVE_TX 0X08 //發(fā)送監(jiān)測(cè)功能
        #define CD 0X09 //地址檢測(cè)
        #define RX_ADDR_P0 0X0A //頻道0接收數(shù)據(jù)地址
        #define RX_ADDR_P1 0X0B //頻道1接收數(shù)據(jù)地址
        #define RX_ADDR_P2 0X0C //頻道2接收數(shù)據(jù)地址
        #define RX_ADDR_P3 0X0D //頻道3接收數(shù)據(jù)地址
        #define RX_ADDR_P4 0X0E //頻道4接收數(shù)據(jù)地址
        #define RX_ADDR_P5 0X0F //頻道5接收數(shù)據(jù)地址
        #define TX_ADDR 0X10 //發(fā)送地址寄存器
        #define RX_PW_P0 0x11 // 接收頻道0接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define RX_PW_P1 0x12 // 接收頻道1接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define RX_PW_P2 0x13 // 接收頻道2接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define RX_PW_P3 0x14 // 接收頻道3接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define RX_PW_P4 0x15 // 接收頻道4接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define RX_PW_P5 0x16 // 接收頻道5接收數(shù)據(jù)有效數(shù)據(jù)長(zhǎng)度
        #define FIFO_STATUS 0X17 //FIFO棧入棧出狀態(tài)寄存器設(shè)置
        #define MAX_RT 0X10 //MAX_RTD在第5位|
        #define TX_DS 0X20 //TX_DS在第6位 | 在讀回STATUS時(shí)與其相與,就知道該位是否為1
        #define RX_DR 0X40 //RX_DR在第7位 |

        void delay(uint16 us)//延時(shí)函數(shù)
        {
        while(us--);
        }

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

        /*void SpiInit()
        {
        TRISC=0XD7;//設(shè)置RC3/SCK,RC5/SDO為輸出
        TRISE=0X01;//IRQ為輸入,CE,CSN為輸出
        SSPSTAT=0XC0;
        SSPCON3=0X00;
        SSPCON1=0X20; //CKE=1,CKP=0;主模式,時(shí)鐘為FOSC/4
        GIE=1;
        PEIE=1;
        CSN=1;
        }
        uint8 SPI_RW(uint8 data)//通過(guò)SPI寫一個(gè)字節(jié)
        { uint8 status;
        CSN=0;
        SSPBUF=data;
        while(!BF);//當(dāng)SSPBUF被讀取后BF清0
        status=SSPBUF;
        SSPIF=0;
        CSN=1;
        return(status);
        }*/
        void SpiInit()
        {
        TRISC=0X20;//設(shè)置RC3/SCK,RC5/SDO為輸出
        ANSELE=0X00;
        TRISE=0X01;//IRQ為輸入,CE,CSN為輸出
        //SSPSTAT=0XC0;
        //SSPCON3=0X00;
        //SSPCON1=0X20; //CKE=1,CKP=0;主模式,時(shí)鐘為FOSC/4
        //GIE=1;
        //PEIE=1;
        CSN=1;
        }

        uint8 SPI_RW(uint8 byte)
        {
        uint8 bit_ctr;
        //DI();
        for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
        {
        if(byte & 0x80)
        MOSI = 1;
        else
        MOSI = 0;
        byte = (byte << 1); // shift next bit into MSB..
        SCK = 1; // Set nRF24L01_SCK high..
        if(MISO) byte |= 1;
        NOP();NOP();NOP();NOP();
        SCK = 0; // ..then set nRF24L01_SCK low again
        NOP();NOP();NOP();NOP();
        }
        //EI();
        return(byte);
        }
        /*uint8 SPI_Read() //通過(guò)SPI讀一個(gè)字節(jié)
        {
        CSN=0;
        SSPBUF=0X00;//讀一個(gè)字節(jié)前必需先寫入一個(gè)字節(jié)
        while(!BF);
        CSN=1;
        return(SSPBUF);
        }*/
        uint8 SPI_Read(uint8 reg)
        {
        uint8 reg_val;
        CSN=0;
        SPI_RW(reg);
        reg_val=SPI_RW(0);
        CSN=1;
        return(reg_val);
        }
        uint8 SPI_RW_Reg(uint8 reg,uint8 value)//向寄存器寫一個(gè)字節(jié),同時(shí)返回狀態(tài)字
        {
        uint8 status;
        CSN=0;
        status=SPI_RW(reg);
        SPI_RW(value);
        CSN=1;
        return(status);
        }
        uint8 SPI_Write_Buf(uint8 reg,uint8 *pBuf,uint8 bytes)//向寄存器寫入一個(gè)字符串
        {
        uint8 status,byte_ctr;
        CSN=0;
        status=SPI_RW(reg);
        for(byte_ctr=0;byte_ctr {
        SPI_RW(*pBuf++);
        }
        CSN=1;
        return(status);
        }
        /***************************以上為SPI通訊程序**********************************/
        /******************************************************************************/
        //接收模式代碼
        void RX_MODE(void)
        {
        CE=0;
        SPI_RW_Reg(FLUSH_TX,0X00);
        //SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
        SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
        SPI_RW_Reg(WRITE_REG+EN_AA,0X01);
        SPI_RW_Reg(WRITE_REG+EN_RXADDR,0X01);
        //SPI_RW_Reg(WRITE_REG+SETUP_RETR,0X1a);
        SPI_RW_Reg(WRITE_REG+RF_CH,40);
        SPI_RW_Reg(WRITE_REG+RF_SETUP,0X07);
        SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);
        SPI_RW_Reg(WRITE_REG+CONFIG,0X0f);
        CE=1;
        delay(50000);
        }
        uint8 SPI_Read_Buf(uint8 reg,uint8 *pBuf,uint8 uchars)
        {
        uint8 status,uchar_ctr;
        CSN=0;
        status=SPI_RW(reg);
        for(uchar_ctr=0;uchar_ctr {
        pBuf[uchar_ctr]=SPI_RW(0);
        }
        CSN=1;
        return(status);
        }
        uint8 nRF24l01_RxPacket(uint8 *rx_buf)
        {
        uint8 revale=0;
        sta=SPI_Read(STATUS);
        if(sta&RX_DR)
        {
        SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);
        revale=1;
        }
        SPI_RW_Reg(WRITE_REG+STATUS,sta);
        return(revale);
        }
        void main()
        {
        uint8 recv=0;
        //delay(1);
        //TRISA=0X00;
        OSCCON=0X60;//set clock
        delay(100);
        SpiInit();
        CE=0;
        CSN=1;
        SCK=0;
        IRQ=1;
        BACK_LED=0;
        RX_MODE();
        while(1)
        {
        if(nRF24l01_RxPacket(Rx_Buf))
        {
        //PORTA=0XFE;
        BACK_LED=1;
        delay(50000);
        BACK_LED=0;
        delay(30);
        }
        }
        }



        關(guān)鍵詞: PIC16f1937nRF24L0

        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 浮山县| 视频| 昭平县| 武汉市| 思茅市| 米林县| 民和| 祥云县| 伊金霍洛旗| 应城市| 沙洋县| 政和县| 高邮市| 汝阳县| 厦门市| 枣阳市| 长泰县| 广昌县| 阜新市| 温州市| 廊坊市| 台东县| 澄江县| 铜陵市| 北川| 荔波县| 江西省| 普洱| 江口县| 海安县| 大厂| 明水县| 宁强县| 上杭县| 化州市| 公主岭市| 榆林市| 锡林浩特市| 谷城县| 平舆县| 金堂县|