stc實例無線雙向通訊代碼
nRF24L01雙向通訊實驗步驟:
1:將TXRX程序下載到兩塊EasySTC15開發(fā)板(開發(fā)板A和開發(fā)板B)中。
2:按下開發(fā)板A上的按鍵S3,可以看到開發(fā)板B上的RGB指示燈中的紅燈狀態(tài)翻轉。
2:按下開發(fā)板B上的按鍵S3,可以看到開發(fā)板A上的RGB指示燈中的紅燈狀態(tài)翻轉。
單片機源程序如下:
- /****************************************Copyright (c)****************************************************
- **
- **
- **
- **--------------File Info---------------------------------------------------------------------------------
- ** File name:
- ** Last modified Date:
- ** Last Version:
- ** Descriptions:
- **--------------------------------------------------------------------------------------------------------
- ** Created by: FiYu
- ** Created date: 2016-3-5
- ** Version: 1.0
- ** Descriptions: nRF24L01無線雙向通訊(硬件SPI)
- **--------------------------------------------------------------------------------------------------------
- ** Modified by: FiYu
- ** Modified date:
- ** Version:
- ** Descriptions:
- ** Rechecked by:
- **********************************************************************************************************/
- /****-----參考:宏晶科技的有關資料及程序-------***********/
- #include <STC15F2K60S2.h>
- #define uint unsigned int
- #define uchar unsigned char
- //無線收發(fā)地址寬度(字節(jié)數(shù))
- #define TX_ADDR_WIDTH 5
- #define RX_ADDR_WIDTH 5
- //無線收發(fā)數(shù)據(jù)長度(字節(jié)數(shù))
- #define TX_PLOAD_WIDTH 1
- #define RX_PLOAD_WIDTH 1
- #define SPIF 0x80 //SPSTAT.7
- #define WCOL 0x40 //SPSTAT.6
- #define SSIG 0x80 //SPCTL.7
- #define SPEN 0x40 //SPCTL.6
- #define DORD 0x20 //SPCTL.5
- #define MSTR 0x10 //SPCTL.4
- #define CPOL 0x08 //SPCTL.3
- #define CPHA 0x04 //SPCTL.2
- #define SPDHH 0x00 //CPU_CLK/4
- #define SPDH 0x01 //CPU_CLK/8
- #define SPDL 0x02 //CPU_CLK/16
- #define SPDLL 0x03 //CPU_CLK/32
- /****************************************************************************************************/
- //NRF24L01寄存器操作命令
- #define SPI_READ_REG 0x00 //讀配置寄存器,低5位為寄存器地址
- #define SPI_WRITE_REG 0x20 //寫配置寄存器,低5位為寄存器地址
- #define RD_RX_PLOAD 0x61 //讀RX有效數(shù)據(jù),1~32字節(jié)
- #define WR_TX_PLOAD 0xA0 //寫TX有效數(shù)據(jù),1~32字節(jié)
- #define FLUSH_TX 0xE1 //清除TX FIFO寄存器.發(fā)射模式下用
- #define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用
- #define REUSE_TX_PL 0xE3 //重新使用上一包數(shù)據(jù),CE為高,數(shù)據(jù)包被不斷發(fā)送.
- #define NOP 0xFF //空操作,可以用來讀狀態(tài)寄存器
- //SPI(NRF24L01)寄存器地址
- #define CONFIG 0x00 //配置寄存器地址;bit0:1接收模式,0發(fā)射模式;bit1:電選擇;bit2:CRC模式;bit3:CRC使能;
- //bit4:中斷MAX_RT(達到最大重發(fā)次數(shù)中斷)使能;bit5:中斷TX_DS使能;bit6:中斷RX_DR使能
- #define EN_AA 0x01 //使能自動應答功能 bit0~5,對應通道0~5
- #define EN_RXADDR 0x02 //接收地址允許,bit0~5,對應通道0~5
- #define SETUP_AW 0x03 //設置地址寬度(所有數(shù)據(jù)通道):bit1,0:00,3字節(jié);01,4字節(jié);02,5字節(jié);
- #define SETUP_RETR 0x04 //建立自動重發(fā);bit3:0,自動重發(fā)計數(shù)器;bit7:4,自動重發(fā)延時 250*x+86us
- #define RF_CH 0x05 //RF通道,bit6:0,工作通道頻率;
- #define RF_SETUP 0x06 //RF寄存器;bit3:傳輸速率(0:1Mbps,1:2Mbps);bit2:1,發(fā)射功率;bit0:低噪聲放大器增益
- #define STATUS 0x07 //狀態(tài)寄存器;bit0:TX FIFO滿標志;bit3:1,接收數(shù)據(jù)通道號(最大:6);bit4,達到最多次重發(fā)
- //bit5:數(shù)據(jù)發(fā)送完成中斷;bit6:接收數(shù)據(jù)中斷;
- #define MAX_TX 0x10 //達到最大發(fā)送次數(shù)中斷
- #define TX_OK 0x20 //TX發(fā)送完成中斷
- #define RX_OK 0x40 //接收到數(shù)據(jù)中斷
- #define OBSERVE_TX 0x08 //發(fā)送檢測寄存器,bit7:4,數(shù)據(jù)包丟失計數(shù)器;bit3:0,重發(fā)計數(shù)器
- #define CD 0x09 //載波檢測寄存器,bit0,載波檢測;
- #define RX_ADDR_P0 0x0A //數(shù)據(jù)通道0接收地址,最大長度5個字節(jié),低字節(jié)在前
- #define RX_ADDR_P1 0x0B //數(shù)據(jù)通道1接收地址,最大長度5個字節(jié),低字節(jié)在前
- #define RX_ADDR_P2 0x0C //數(shù)據(jù)通道2接收地址,最低字節(jié)可設置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;
- #define RX_ADDR_P3 0x0D //數(shù)據(jù)通道3接收地址,最低字節(jié)可設置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;
- #define RX_ADDR_P4 0x0E //數(shù)據(jù)通道4接收地址,最低字節(jié)可設置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;
- #define RX_ADDR_P5 0x0F //數(shù)據(jù)通道5接收地址,最低字節(jié)可設置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;
- #define TX_ADDR 0x10 //發(fā)送地址(低字節(jié)在前),ShockBurstTM模式下,RX_ADDR_P0與此地址相等
- #define RX_PW_P0 0x11 //接收數(shù)據(jù)通道0有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
- #define RX_PW_P1 0x12 //接收數(shù)據(jù)通道1有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
- #define RX_PW_P2 0x13 //接收數(shù)據(jù)通道2有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
- #define RX_PW_P3 0x14 //接收數(shù)據(jù)通道3有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
- #define RX_PW_P4 0x15 //接收數(shù)據(jù)通道4有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
- #define RX_PW_P5 0x16 //接收數(shù)據(jù)通道5有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
- #define FIFO_STATUS 0x17 //FIFO狀態(tài)寄存器;bit0,RX FIFO寄存器空標志;bit1,RX FIFO滿標志;bit2,3,保留
- //bit4,TX FIFO空標志;bit5,TX FIFO滿標志;bit6,1,循環(huán)發(fā)送上一數(shù)據(jù)包.0,不循環(huán);
-
- #define CE_LOW en=0
- #define CE_HIGH en=1
- #define CS_LOW SPI_CS=0
- #define CS_HIGH SPI_CS=1
-
- const uchar TX_ADDRESS[TX_ADDR_WIDTH]={0xE1,0xE2,0xE3,0xE4,0xE5}; //發(fā)送地址
- const uchar RX_ADDRESS[RX_ADDR_WIDTH]={0xE1,0xE2,0xE3,0xE4,0xE5}; //接收地址
- uchar RxPayload[32]; //無線接收緩存
- uchar TxPayload[32]; //無線發(fā)送緩存
- /**********************
- 引腳別名定義
- ***********************/
- sbit IRQ=P3^3; //中斷
- sbit en=P3^2; //使能控制
- sbit SPI_CS=P1^2; //片選
- sbit KEY=P0^4; //用戶按鍵S3用IO口P04
- sbit LED_B=P0^5; //三色指示燈之藍色LED用IO口P05
- sbit LED_R=P0^6; //三色指示燈之紅色LED用IO口P06
- /**************************************
- 功能描述:延時函數(shù)
- 入口參數(shù):uint x ,該值為1時,延時1ms
- 返回值:無
- ***************************************/
- void delay_ms(uint x)
- {
- uint j,i;
- for(j=0;j<x;j++)
- {
- for(i=0;i<1100;i++);
- }
- }
- /***************************************************************************
- * 描 述 : 初始化SPI
- * 入 參 : 無
- * 返回值 : 無
- **************************************************************************/
- void InitSPI(void)
- {
- SPDAT = 0; //初始化SPI數(shù)據(jù)
- SPSTAT = SPIF | WCOL; //清除SPI狀態(tài)位
- SPCTL = SPEN | MSTR | SSIG; //主機模式
- }
- /***************************************************************************
- * 描 述 : 模擬SPI讀寫數(shù)據(jù)函數(shù),讀寫一個字節(jié)
- * 入 參 : 寫入的數(shù)據(jù)
- * 返回值 : 讀取的數(shù)據(jù)
- **************************************************************************/
- uchar SPI_RW(uchar byte)
- {
- SPDAT = byte; //觸發(fā)SPI發(fā)送數(shù)據(jù)
- while (!(SPSTAT & SPIF)); //等待發(fā)送完成
- SPSTAT = SPIF | WCOL; //清除SPI狀態(tài)位
- return SPDAT; //返回SPI數(shù)據(jù)
- }
- /***************************************************************************
- * 描 述 : NRF24L01寄存器寫函數(shù)
- * 入 參 : regaddr:要寫的寄存器地址;data:寫入到寄存器的數(shù)據(jù)
- * 返回值 : 讀取的狀態(tài)值
- **************************************************************************/
- uchar NRF24L01_Write_Reg(uchar regaddr,uchar dat)
- {
- uchar status;
-
- CS_LOW;
- status =SPI_RW(regaddr);
- SPI_RW(dat); //寫入寄存器的值
- CS_HIGH; //禁止SPI傳輸
- return(status); //返回狀態(tài)值
- }
- /***************************************************************************
- * 描 述 : NRF24L01寄存器讀函數(shù)
- * 入 參 : regaddr:要讀取的寄存器地址
- * 返回值 : 讀取的寄存器的值
- **************************************************************************/
- uchar NRF24L01_Read_Reg(uchar regaddr)
- {
- uchar reg_val;
-
- CS_LOW; //使能SPI傳輸
- SPI_RW(regaddr);
- reg_val=SPI_RW(0XFF);
- CS_HIGH; //禁止SPI傳輸
- return(reg_val); //返回讀取的值
- }
- /***************************************************************************
- * 描 述 : 從指定地址讀出指定長度的數(shù)據(jù)
- * 入 參 : pBuf:讀出數(shù)據(jù)的存放地址;datlen:讀出的數(shù)據(jù)字節(jié)數(shù)
- * 返回值 : 讀取的寄存器的值
- **************************************************************************/
- uchar NRF24L01_Read_Buf(uchar regaddr,uchar *pBuf,uchar datlen)
- {
- uchar status,u8_ctr;
- CS_LOW; //使能SPI傳輸
- status=SPI_RW(regaddr);
- for(u8_ctr=0;u8_ctr<datlen;u8_ctr++)
- {
- pBuf[u8_ctr]=SPI_RW(0XFF);//讀出數(shù)據(jù)
- }
- CS_HIGH; //關閉SPI傳輸
- return status; //返回讀到的狀態(tài)值
- }
- /***************************************************************************
- * 描 述 : 向指定地址寫入指定長度的數(shù)據(jù)
- * 入 參 : pBuf:讀出數(shù)據(jù)的存放地址;datlen:讀出的數(shù)據(jù)字節(jié)數(shù)
- * 返回值 : 讀取的狀態(tài)寄存器值
- **************************************************************************/
- uchar NRF24L01_Write_Buf(uchar regaddr, uchar *pBuf, uchar datalen)
- {
- uchar status,u8_ctr;
- CS_LOW; //使能SPI傳輸
- status = SPI_RW(regaddr);
- for(u8_ctr=0; u8_ctr<datalen; u8_ctr++)
- {
- SPI_RW(*pBuf++); //寫入數(shù)據(jù)
- }
- CS_HIGH; //關閉SPI傳輸
- return status; //返回讀到的狀態(tài)值
- }
- /***************************************************************************
- * 描 述 : NRF24L01初始化函數(shù),初始化連接NRF24L01模塊的管腳,調用SPI初始化函數(shù)
- * 完成和NRF24L01模塊通訊的SPI總線的初始化
- * 入 參 : 無
- * 返回值 : 無
- **************************************************************************/
- void Init_NRF24L01(void)
- {
- delay_ms(2);
- LED_B=1;
- CE_LOW; //使能NRF24L01
- CS_HIGH; //SPI片選取消
- InitSPI();
- }
- /***************************************************************************
- * 描 述 : 啟動NRF24L01發(fā)送一次數(shù)據(jù)
- * 入 參 : buf:待發(fā)送數(shù)據(jù)首地址
- * 返回值 : 發(fā)送完成狀況
- **************************************************************************/
- uchar NRF24L01_TxPacket(uchar *buf)
- {
- uchar state,retVal = 0xff;
-
- CE_LOW;
- //寫TX節(jié)點地址
- NRF24L01_Write_Reg(SPI_WRITE_REG+CONFIG,0x0e);
- NRF24L01_Write_Buf(SPI_WRITE_REG+TX_ADDR,(uchar*)TX_ADDRESS,TX_ADDR_WIDTH);
- NRF24L01_Write_Buf(WR_TX_PLOAD,buf,TX_PLOAD_WIDTH); //寫數(shù)據(jù)到TX BUF
- CE_HIGH; //啟動發(fā)送
- while(IRQ!=0); //等待發(fā)送完成
- state=NRF24L01_Read_Reg(STATUS); //讀取狀態(tài)寄存器的值
- NRF24L01_Write_Reg(SPI_WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中斷標志
- if(state&MAX_TX) //達到最大重發(fā)次數(shù)
- {
- NRF24L01_Write_Reg(FLUSH_TX,0xff); //清除TX FIFO寄存器
- retVal = MAX_TX;
- }
- if(state&TX_OK) //發(fā)送完成
- {
- retVal = TX_OK;
- }
- CE_LOW;
- NRF24L01_Write_Reg(SPI_WRITE_REG+CONFIG, 0x0f);
- CE_HIGH;
- return retVal; //其他原因發(fā)送失敗
- }
- /***************************************************************************
- * 描 述 : 啟動NRF24L01讀取一次數(shù)據(jù)
- * 入 參 : buf:待發(fā)送數(shù)據(jù)首地址
- * 返回值 : RX_OK:接收到數(shù)據(jù);0:未接收到數(shù)據(jù)
- **************************************************************************/
- uchar NRF24L01_RxPacket(uchar *buf)
- {
- uchar state;
-
- state=NRF24L01_Read_Reg(STATUS); //讀取狀態(tài)寄存器的值
- NRF24L01_Write_Reg(SPI_WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中斷標志
- if(state&RX_OK) //接收到數(shù)據(jù)
- {
- NRF24L01_Read_Buf(RD_RX_PLOAD,buf,RX_PLOAD_WIDTH);//讀取數(shù)據(jù)
- NRF24L01_Write_Reg(FLUSH_RX,0xff); //清除RX FIFO寄存器
- return RX_OK;
- }
- return 0; //沒收到任何數(shù)據(jù)
- }
- /***************************************************************************
- * 描 述 : 初始化NRF24L01到RX模式,配置相關參數(shù),CE變高后,即進入RX模式
- * 入 參 : 無
- * 返回值 : 無
- **************************************************************************/
- void Set_RxMode(void)
- {
- CE_LOW;
- // Delay_1ms(20);
- //寫RX節(jié)點地址
- NRF24L01_Write_Buf(SPI_WRITE_REG+RX_ADDR_P0,(uchar*)RX_ADDRESS,RX_ADDR_WIDTH);
- //關閉通道0的自動應答
- NRF24L01_Write_Reg(SPI_WRITE_REG+EN_AA,0x00);
- //使能通道0的接收地址
- NRF24L01_Write_Reg(SPI_WRITE_REG+EN_RXADDR,0x01);
- //設置RF通信頻率
- NRF24L01_Write_Reg(SPI_WRITE_REG+RF_CH,55);
- //選擇通道0的有效數(shù)據(jù)寬度
- NRF24L01_Write_Reg(SPI_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);
- //設置TX發(fā)射參數(shù),0db增益,2Mbps,低噪聲增益開啟
- NRF24L01_Write_Reg(SPI_WRITE_REG+RF_SETUP,0x26);
- //配置基本工作模式的參數(shù);PWR_UP,EN_CRC,16BIT_CRC,PRIM_RX接收模式
- NRF24L01_Write_Reg(SPI_WRITE_REG+CONFIG, 0x0f);
- //CE為高,進入接收模式
- CE_HIGH;
- }
- /***************************************************************************
- * 描 述 : 主函數(shù)
- * 入 參 : 無
- * 返回值 : 無
- **************************************************************************/
- int main() //主函數(shù)
- {
- /////////////////////////////////////////////////
- //注意: STC15W4K32S4系列的芯片,上電后所有與PWM相關的IO口均為
- // 高阻態(tài),需將這些口設置為準雙向口或強推挽模式方可正常使用
- //相關IO: P0.6/P0.7/P1.6/P1.7/P2.1/P2.2
- // P2.3/P2.7/P3.7/P4.2/P4.4/P4.5
- /////////////////////////////////////////////////
- P0M1 = 0; P0M0 = 0; //設置P0.0~P0.7為準雙向口
- P2M1 = 0; P2M0 = 0; //設置P2.0~P2.7為準雙向口
- P3M1 = 0; P3M0 = 0; //設置P3.0~P3.7為準雙向口
- P4M1 = 0; P4M0 = 0; //設置P4.0~P4.7為準雙向口
- P5M1 = 0; P5M0 = 0; //設置P5.0~P5.7為準雙向口
-
- Init_NRF24L01(); //初始化
- Set_RxMode(); //配置nRF24L01為發(fā)送模式
-
- while(1)
- {
- if(KEY == 0)//按鍵按下
- {
- delay_ms(10);
- if(KEY== 0) //延時去抖動
- {
- LED_B=0;
- while(KEY == 0); //等待按鍵釋放
-
- TxPayload[0] = 0x5A;
- LED_B=1;
- if(NRF24L01_TxPacket(TxPayload) == TX_OK) //如果發(fā)送成功
- {
- //無線發(fā)射成功
- }
- else
- {
- //添加錯誤處理代碼
- }
- }
- }
- if(NRF24L01_RxPacket(RxPayload) == RX_OK) //如果接收成功
- {
- if(RxPayload[0] == 0x5A)
- {
- LED_R=~LED_R;//NRF24L01模塊狀態(tài)指示燈翻轉
- RxPayload[0] = 0;
- }
- }
- }
- }
復制代碼
所有資料51hei提供下載:
nRF24L01_TxRx(硬件SPI).zip
(48.89 KB, 下載次數(shù): 109)
2019-1-10 21:57 上傳
點擊文件名下載附件
nRF24L01雙向通訊 下載積分: 黑幣 -5
|