1. 程式人生 > >[51]NRF24L01無線通訊模組

[51]NRF24L01無線通訊模組

#ifndef __NRF24L01_H__ #define __NRF24L01_H__ #include <reg52.H> #include <intrins.h> #define uchar unsigned char #define uint  unsigned int #define MODE 1  //MODE=1時 為傳送程式碼   MODE=0時  為接收程式碼 //****************************************IO埠定義*************************************** sbit  MISO = P3 ^ 2; sbit  MOSI = P3 ^ 4; sbit  SCK  = P3 ^ 1; sbit  CE   = P3 ^ 0; sbit  CSN  = P3 ^ 3; sbit  IRQ  = P3 ^ 5; //sbit  MISO = P0 ^ 4; //sbit  MOSI = P0 ^ 3; //sbit  SCK  = P0 ^ 2; //sbit  CE   = P0 ^ 0; //sbit  CSN  = P0 ^ 1; //sbit  IRQ  = P0 ^ 5; //****************************************************************************************** uchar bdata sta;   //狀態標誌 sbit RX_DR  = sta ^ 6; sbit TX_DS  = sta ^ 5; sbit MAX_RT = sta ^ 4; //*********************************************NRF24L01************************************* #define TX_ADR_WIDTH    5    // 5 uints TX address width #define RX_ADR_WIDTH    5    // 5 uints RX address width #define TX_PLOAD_WIDTH  5    // 5 uints TX payload #define RX_PLOAD_WIDTH  5    // 5 uints TX payload uchar const TX_ADDRESS[TX_ADR_WIDTH] = {0x34, 0x43, 0x10, 0x10, 0x01}; //本地地址 uchar const RX_ADDRESS[RX_ADR_WIDTH] = {0x34, 0x43, 0x10, 0x10, 0x01}; //接收地址 uchar data Tx_Buf[TX_PLOAD_WIDTH] = {0xff, 0xee, 0x11, 0x22, 0x33};//傳送資料 uchar Rx_Buf[RX_PLOAD_WIDTH];//接收資料 //***************************************NRF24L01暫存器指令******************************************************* #define READ_REG        0x00   // 讀暫存器指令 #define WRITE_REG       0x20  // 寫暫存器指令 #define RD_RX_PLOAD     0x61   // 讀取接收資料指令 #define WR_TX_PLOAD     0xA0   // 寫待發資料指令 #define FLUSH_TX        0xE1  // 沖洗傳送 FIFO指令 #define FLUSH_RX        0xE2   // 沖洗接收 FIFO指令 #define REUSE_TX_PL     0xE3   // 定義重複裝載資料指令 #define NOP             0xFF   // 保留 //*************************************SPI(nRF24L01)暫存器地址**************************************************** #define CONFIG          0x00  // 配置收發狀態,CRC校驗模式以及收發狀態響應方式 #define EN_AA           0x01  // 自動應答功能設定 #define EN_RXADDR       0x02  // 可用通道設定 #define SETUP_AW        0x03  // 收發地址寬度設定 #define SETUP_RETR      0x04  // 自動重發功能設定 #define RF_CH           0x05  // 工作頻率設定 #define RF_SETUP        0x06  // 發射速率、功耗功能設定 #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接收資料長度 #define RX_PW_P1        0x12  // 接收頻道0接收資料長度 #define RX_PW_P2        0x13  // 接收頻道0接收資料長度 #define RX_PW_P3        0x14  // 接收頻道0接收資料長度 #define RX_PW_P4        0x15  // 接收頻道0接收資料長度 #define RX_PW_P5        0x16  // 接收頻道0接收資料長度 #define FIFO_STATUS     0x17  // FIFO棧入棧出狀態暫存器設定 /******************************************延時函式********************************************************/ //長延時 void Delay(unsigned int s) {     unsigned int i, j;     for(i = 0; i < 1000; i++)for(j = 0; j < s; j++); } //短延時 void delay_ms(unsigned int x) {     unsigned int i, j;     i = 0;     for(i = 0; i < x; i++)     {         j = 108;;         while(j--);     } } /************************************IO 口模擬SPI匯流排 程式碼************************************************/ uchar SPI_RW(uchar byte) {     uchar bit_ctr;     for(bit_ctr = 0; bit_ctr < 8; bit_ctr++)     {         MOSI = (byte & 0x80);         byte = (byte << 1);         SCK = 1;         byte |= MISO;         //led=MISO;Delay(150);         SCK = 0;     }     return(byte); } uchar SPI_RW_Reg  (uchar  reg, uchar value) // 向暫存器REG寫一個位元組,同時返回狀態位元組 {     uchar status;     CSN = 0;     status = SPI_RW(reg);     SPI_RW(value);     CSN = 1;     return(status); } uchar SPI_Read (uchar  reg ) {     uchar reg_val;     CSN = 0;     SPI_RW(reg);     reg_val = SPI_RW(0);     CSN = 1;     return(reg_val); } uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) {     uchar status, byte_ctr;     CSN = 0;                   // Set CSN low, init SPI tranaction     status = SPI_RW(reg);    // Select register to write to and read status byte     for(byte_ctr = 0; byte_ctr < bytes; byte_ctr++) // then write all byte in buffer(*pBuf)         SPI_RW(*pBuf++);     CSN = 1;                 // Set CSN high again     return(status);          // return nRF24L01 status byte } #if MODE /*******************************發*****送*****模*****式*****代*****碼*************************************/ void TX_Mode(void) {     CE = 0;     SPI_RW_Reg(FLUSH_TX, 0x00);     SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // Writes TX_Address to nRF24L01     SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack     SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0     SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0     SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...1a     SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // Select RF channel 40     SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR     SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //設定接收資料長度,本次設定為2位元組     SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);     CE = 1;     delay_ms(100); } void Transmit(unsigned char *tx_buf) {     CE = 0; //StandBy I模式     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);      // IRQ收發完成中斷響應,16位CRC,主傳送     CE = 1; //置高CE,激發資料傳送     delay_ms(150); } #else /*******************************接*****收*****模*****式*****代*****碼*************************************/ uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars) {     uchar status, uchar_ctr;     CSN = 0;                      // Set CSN low, init SPI tranaction     status = SPI_RW(reg);         // Select register to write to and read status uchar     for(uchar_ctr = 0; uchar_ctr < uchars; uchar_ctr++)         pBuf[uchar_ctr] = SPI_RW(0);    //     CSN = 1;     return(status);                    // return nRF24L01 status uchar } /******************************************************************************************************/ /*函式:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf) /*功能:資料讀取後放如rx_buf接收緩衝區中 /******************************************************************************************************/ unsigned char nRF24L01_RxPacket(unsigned char *rx_buf) {     unsigned char revale = 0;     sta = SPI_Read(STATUS); // 讀取狀態寄存其來判斷資料接收狀況     if(RX_DR)    // 判斷是否接收到資料     {         //CE = 0;    //SPI使能         SPI_Read_Buf(RD_RX_PLOAD, rx_buf, RX_PLOAD_WIDTH); // read receive payload from RX_FIFO buffer         revale = 1;  //讀取資料完成標誌         //Delay(100);     }     SPI_RW_Reg(WRITE_REG + STATUS, sta); //接收到資料後RX_DR,TX_DS,MAX_PT都置高為1,通過寫1來清楚中斷標誌     return revale; } /****************************************************************************************************/ /*函式:void RX_Mode(void) /*功能:資料接收配置 /****************************************************************************************************/ void RX_Mode(void) {     CE = 0;     SPI_RW_Reg(FLUSH_RX, 0x00);     SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // Writes TX_Address to nRF24L01     SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack     SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0     SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0     SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...1a     SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // Select RF channel 40     SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //設定接收資料長度,本次設定為2位元組     SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR     SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F);     CE = 1;     delay_ms(130); } //************************************串列埠初始化********************************************************* void StartUART( void ) {     //波特率9600     SCON = 0x50;     TMOD = 0x20;     TH1 = 0xFD;     TL1 = 0xFD;     PCON = 0x00;     TR1 = 1; } //************************************通過串列埠將接收到資料傳送給PC端************************************** void R_S_Byte(uchar R_Byte) {     SBUF = R_Byte;     while( TI == 0 );    //查詢法     TI = 0; } #endif //=========================================================================================// #endif