
/************************發送部分*********************/
#include <c8051f310.h>
#include <stdio.h>
#include <math.h>
#include <Intrins.h>
#include <absacc.h>
#define uint unsigned int
#define uchar unsigned char
//nRF24L01的數據寬度,地址寬度,以及數據定義
#define TX_ADR_WIDTH 4 //地址數據
#define RX_PLOAD_WIDTH 4 //接收的有效數據寬度
#define TX_PLOAD_WIDTH 4 //發送的有效數據寬度
#define BUSY SPI0CFG&0x80
uchar TX_ADDRESS[]={0xe7,0xe7,0xe7,0xe7}; //傳送接收端地址
uchar shuzu[4]={0x99,0x99,0xc7,0x99}; //要發送的有效數據
uchar rx_buf[4]={0x00,0x00,0x00,0x00}; //接收的數據緩存
uchar a,b,i;
uchar sta;
//引腳定義2274
#define CSN_HIGH CSN=1
#define CSN_LOW CSN=0
#define CE_HIGH CE=1
#define CE_LOW CE=0
sbit CE=P0^5;
sbit CSN=P0^6;
sbit IRQ=P0^4;
sbit c=P0^7;
//24L01寄存器地址
#define CONFIG 0X00//配置寄存器地址
#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
#define RX_ADDR_P2 0X0C
#define RX_ADDR_P3 0X0D
#define RX_ADDR_P4 0X0E
#define RX_ADDR_P5 0X0F
#define TX_ADDR 0X10//發送地址寄存器地址
#define RX_PW_P0 0X11//接收地址通道0有效數據寬度
#define RX_PW_P1 0X12
#define RX_PW_P2 0X13
#define RX_PW_P3 0X14
#define RX_PW_P4 0X15
#define RX_PW_P5 0X16
#define FIFO_STATUS 0X17//FIFO狀態寄存器
//SPI命令字
#define READ_REG 0X00//讀寄存器命令
#define WRITE_REG 0X20//寫寄存器命令
#define RD_RX_PLOAD 0X61//讀有效數據命令
#define WR_TX_PLOAD 0XA0//寫有效數據命令
#define FLUSH_TX 0XE1//清除TX_FIFO應用于發射模式
#define FLUSH_RX 0XE2//清除RX_FIFO應用于接收模式
#define REUSE_TX_PL 0XE3//重新使用上一包有效數據
#define NOP 0XFF//空操作指令
void dat_int(void)
{
CSN_HIGH;
CE_LOW;
a=0;
c=0;
}
void sysclk(void) //內部晶振
{
OSCICL=0xb3; // 0x83
OSCICN=0xc2; //二分頻
CLKSEL=0x00;
}
//延時子函數us
void delay(uint i)
{
while(i--)
;
}
uchar SPI_RW(uchar byte) //用SPI讀寫一字節的數據
{
uchar rbyte;
SPI0DAT=byte;
while(!SPIF);
rbyte=SPI0DAT;
SPIF=0;
delay(15);
return rbyte;
}
uchar SPI_RW_Reg(uchar reg,uchar value) //向寄存器寫一字節的數據,同時返回狀態字
{
uchar status;
CSN_LOW;
SPI0DAT=reg;
while(!SPIF);
delay(20);
status=SPI0DAT;
SPIF=0;
SPI0DAT=value;
while(!SPIF);
SPIF=0;
CSN_HIGH;
return(status);
}
uchar SPI_Read(uchar reg) //從寄存器讀出一字節的數據
{
uchar byte;
CSN_LOW;
SPI0DAT=reg;
while(!SPIF);
delay(20);
SPI0DAT=0x00;
SPIF=0;
while(!SPIF);
byte=SPI0DAT;
SPIF=0;
CSN_HIGH;
return byte;
}
uchar SPI_Read_Buf(uchar reg,uchar *pBuf,uchar bytes) //從reg讀出bytes字節的數據
{
uchar status,byte_ctr;
CSN_LOW;
status=SPI_RW(reg);
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
pBuf[byte_ctr]=SPI_RW(0);
CSN_HIGH;
return status;
}
uchar SPI_RW_Buf(uchar reg,uchar *pBuf,uchar bytes) //向reg寫入bytes字節的數據
{
uchar status,byte_ctr;
CSN_LOW;
status=SPI_RW(reg);
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
SPI_RW(pBuf[byte_ctr]);
CSN_HIGH;
return status;
}
//接收函數,接收返回1表示有數據收到
uchar nRF24L01_RxPacket(uchar *rx_buf)
{
uchar sta;
uchar revale=0;
SPI_RW_Reg(WRITE_REG+CONFIG,0X0F);
SPI_RW_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//定義接收通道號
CE_HIGH; //開始接收數據
delay(130);
sta=SPI_Read(READ_REG+STATUS);//接收狀態寄存器,用于判斷是否收到數據
if(sta&0x40)
{
CE_LOW; //結束接收數據
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);
revale=0xff;
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收復位
return revale;
}
void nRF24L01_TxPacket(uchar *tx_buf) //發送函數
{
CE_LOW;
SPI_RW_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //給發送寄存器寫入地址,寬度為TX_ADR_WIDTH
SPI_RW_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//給接收寄存器寫入地址,寬度也為TX_ADR_WIDTH
SPI_Read_Buf(RX_ADDR_P0,rx_buf,TX_ADR_WIDTH);
SPI_RW_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH); //向發送寄存器寫入TX_PLOAD_WIDTH寬度的數據,
SPI_RW_Reg(WRITE_REG+CONFIG,0X0E); //配置為PWR_UP位,使能CRC,16位校驗,發送模式
CE_HIGH;
delay(100);
CE_LOW;
}
void nRF24L01_Config() //nRF24L01的配置函數
{
CE_LOW;//芯片使能
CSN_HIGH;//SPI復位
SPI_RW_Reg(WRITE_REG+CONFIG,0X0F); //使能發送模式
SPI_Read(CONFIG);
SPI_RW_Reg(WRITE_REG+EN_AA,0X01);//數據通道0自動應答
SPI_Read(EN_AA);
SPI_RW_Reg(WRITE_REG+EN_RXADDR,0X01); //通道0允許
SPI_RW_Reg(WRITE_REG+SETUP_AW,0X02); //設置地址寬度為4字節
SPI_RW_Reg(WRITE_REG+SETUP_RETR,0X1A);//建立自動重發,500+86us,10次重發
SPI_RW_Reg(WRITE_REG+RF_CH,0x02);//設置工作通道頻率
SPI_RW_Reg(WRITE_REG+RF_SETUP,0X07);//設置工作通道傳輸速率為1Mbps,發射功率為0dBm
SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); //設置通道0有效數據寬度RX_PLOAD_WIDTH
}
void SPI(void) //SPI初始化
{
SPI0CFG=0x40;
SPI0CN=0x01; //0000 0001最后一位是SPI使能位 SPI工作在三線主方式
SPI0CKR=0x2f; //SPI 時鐘頻率設置為150kHz 0x6f 0x2f
}
void Interrupt_int(void) //中斷設定
{
IE=0x40; //允許SPI中斷請求
IP=0x00; //SPI為低優先級
}
void pio(void) // 端口配置
{
P0MDIN=0xff; //禁止模擬輸入,0為模擬,1為數字
P0MDOUT=0xff; //0為開漏,1為推挽(ff)
P0SKIP=0x00;
P1MDIN=0xff;
P1MDOUT=0xff; //低四位用于138
P2MDIN=0xff; //禁止模擬輸入,0為模擬,1為數字
P2MDOUT=0xff; //0為開漏,1為推挽(ff)
P3MDIN=0xff;
P3MDOUT=0xff; //低四位用于138
XBR0=0x02;
XBR1=0x40;
//P0=0xff;
}
void sysclk(void);
void pio(void);
void SPI(void);
void Interrupt_int(void);
void delay(uint i);
void dat_int(void);
void main(void) //主程序
{
PCA0MD &= ~0x40;// 關閉看門狗
pio();
sysclk();
SPI(); //SPI0DAT是SPI的數據寄存器
Interrupt_int();
EA=0;
dat_int();
nRF24L01_Config(); // nRF24L01的配置函數
while(1)
{
//nRF24L01_RxPacket(rx_buf);
nRF24L01_TxPacket(shuzu); //發送函數
sta=SPI_Read(READ_REG+STATUS); //發送程序復位
if(sta&0x20)
{
c=1;
SPI_RW_Reg(WRITE_REG+STATUS,sta);
CSN_LOW; //清除發送寄存器的值
SPI_RW(FLUSH_TX);
CSN_HIGH;
}
delay(10000);
break;
}
while(1)
{nRF24L01_RxPacket(rx_buf);
P1=rx_buf[3];
delay(10000);
}
}
與發送部分差不多
****************接收部分*******************
#include <c8051f310.h>
#include <stdio.h>
#include <math.h>
#include <Intrins.h>
#include <absacc.h>
#define uint unsigned int
#define uchar unsigned char
//nRF24L01的數據寬度,地址寬度,以及數據定義
#define TX_ADR_WIDTH 4 //地址數據
#define RX_PLOAD_WIDTH 4 //接收的有效數據寬度
#define TX_PLOAD_WIDTH 4 //發送的有效數據寬度
#define BUSY SPI0CFG&0x80
uchar TX_ADDRESS[]={0xe7,0xe7,0xe7,0xe7}; //傳送接收端地址
uchar tx_buf[4]={0x99,0x99,0x88,0x88}; //要發送的有效數據
uchar rx_buf[4]={0x00,0x00,0x00,0x00}; //接收的數據緩存
uchar a,b,i;
uchar sta;
//引腳定義2274
#define CSN_HIGH CSN=1
#define CSN_LOW CSN=0
#define CE_HIGH CE=1
#define CE_LOW CE=0
sbit CE=P0^5;
sbit CSN=P0^6;
sbit IRQ=P0^4;
sbit c=P0^7;
//24L01寄存器地址
#define CONFIG 0X00//配置寄存器地址
#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
#define RX_ADDR_P2 0X0C
#define RX_ADDR_P3 0X0D
#define RX_ADDR_P4 0X0E
#define RX_ADDR_P5 0X0F
#define TX_ADDR 0X10//發送地址寄存器地址
#define RX_PW_P0 0X11//接收地址通道0有效數據寬度
#define RX_PW_P1 0X12
#define RX_PW_P2 0X13
#define RX_PW_P3 0X14
#define RX_PW_P4 0X15
#define RX_PW_P5 0X16
#define FIFO_STATUS 0X17//FIFO狀態寄存器
//SPI命令字
#define READ_REG 0X00//讀寄存器命令
#define WRITE_REG 0X20//寫寄存器命令
#define RD_RX_PLOAD 0X61//讀有效數據命令
#define WR_TX_PLOAD 0XA0//寫有效數據命令
#define FLUSH_TX 0XE1//清除TX_FIFO應用于發射模式
#define FLUSH_RX 0XE2//清除RX_FIFO應用于接收模式
#define REUSE_TX_PL 0XE3//重新使用上一包有效數據
#define NOP 0XFF//空操作指令
void dat_int(void)
{
CSN_HIGH;
CE_LOW;
a=0;
c=0;
}
void sysclk(void) //內部晶振
{
OSCICL=0xb3; // 0x83
OSCICN=0xc2; //二分頻
CLKSEL=0x00;
}
//延時子函數us
void delay(uint i)
{
while(i--)
;
}
uchar SPI_RW(uchar byte) //用SPI讀寫一字節的數據
{
uchar rbyte;
SPI0DAT=byte;
while(!SPIF);
rbyte=SPI0DAT;
SPIF=0;
delay(15);
return rbyte;
}
uchar SPI_RW_Reg(uchar reg,uchar value) //向寄存器寫一字節的數據,同時返回狀態字
{
uchar status;
CSN_LOW;
SPI0DAT=reg;
while(!SPIF);
delay(20);
status=SPI0DAT;
SPIF=0;
SPI0DAT=value;
while(!SPIF);
SPIF=0;
CSN_HIGH;
return(status);
}
uchar SPI_Read(uchar reg) //從寄存器讀出一字節的數據
{
uchar byte;
CSN_LOW;
SPI0DAT=reg;
while(!SPIF);
delay(20);
SPI0DAT=0x00;
SPIF=0;
while(!SPIF);
byte=SPI0DAT;
SPIF=0;
CSN_HIGH;
return byte;
}
uchar SPI_Read_Buf(uchar reg,uchar *pBuf,uchar bytes) //從reg讀出bytes字節的數據
{
uchar status,byte_ctr;
CSN_LOW;
status=SPI_RW(reg);
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
pBuf[byte_ctr]=SPI_RW(0);
CSN_HIGH;
return status;
}
uchar SPI_RW_Buf(uchar reg,uchar *pBuf,uchar bytes) //向reg寫入bytes字節的數據
{
uchar status,byte_ctr;
CSN_LOW;
status=SPI_RW(reg);
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
SPI_RW(*pBuf++);
CSN_HIGH;
return(status);
}
//接收函數,接收返回1表示有數據收到
uchar nRF24L01_RxPacket(uchar *rx_buf)
{
uchar sta;
uchar revale=0;
SPI_RW_Reg(WRITE_REG+CONFIG,0X0F);
SPI_RW_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//定義接收通道號
CE_HIGH; //開始接收數據
delay(130);
sta=SPI_Read(READ_REG+STATUS);//接收狀態寄存器,用于判斷是否收到數據
if(sta&0x40)
{
CE_LOW; //結束接收數據
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);
revale=0xff;
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收復位
return revale;
}
void nRF24L01_TxPacket(uchar *tx_buf) //發送函數
{
CE_LOW;
SPI_RW_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //給發送寄存器寫入地址,寬度為TX_ADR_WIDTH
SPI_RW_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//給接收寄存器寫入地址,寬度也為TX_ADR_WIDTH
SPI_Read_Buf(RX_ADDR_P0,rx_buf,TX_ADR_WIDTH);
SPI_RW_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH); //向發送寄存器寫入TX_PLOAD_WIDTH寬度的數據,
SPI_RW_Reg(WRITE_REG+CONFIG,0X0E); //配置為PWR_UP位,使能CRC,16位校驗,發送模式
CE_HIGH;
delay(100);
CE_LOW;
}
void nRF24L01_Config() //nRF24L01的配置函數
{
CE_LOW;//芯片使能
CSN_HIGH;//SPI復位
SPI_RW_Reg(WRITE_REG+CONFIG,0X0F); //使能接收模式
SPI_Read(CONFIG);
SPI_RW_Reg(WRITE_REG+EN_AA,0X01);//數據通道0自動應答
SPI_Read(EN_AA);
SPI_RW_Reg(WRITE_REG+EN_RXADDR,0X01); //通道0允許
SPI_RW_Reg(WRITE_REG+SETUP_AW,0X02); //設置地址寬度為4字節
SPI_RW_Reg(WRITE_REG+SETUP_RETR,0X1A);//建立自動重發,500+86us,10次重發
SPI_RW_Reg(WRITE_REG+RF_CH,0x02);//設置工作通道頻率
SPI_RW_Reg(WRITE_REG+RF_SETUP,0X07);//設置工作通道傳輸速率為1Mbps,發射功率為0dBm
SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//設置通道0有效數據寬度RX_PLOAD_WIDTH
}
void SPI(void) //SPI初始化
{
SPI0CFG=0x40;
SPI0CN=0x01; //0000 0001最后一位是SPI使能位 SPI工作在三線主方式
SPI0CKR=0x2f; //SPI 時鐘頻率設置為150kHz 0x6f 0x2f
}
void Interrupt_int(void) //中斷設定
{
IE=0x40; //允許SPI中斷請求
IP=0x00; //SPI為低優先級
}
void pio(void) // 端口配置
{
P0MDIN=0xff; //禁止模擬輸入,0為模擬,1為數字
P0MDOUT=0xff; //0為開漏,1為推挽(ff)
P0SKIP=0x00;
P1MDIN=0xff;
P1MDOUT=0xff; //低四位用于138
P2MDIN=0xff; //禁止模擬輸入,0為模擬,1為數字
P2MDOUT=0xff; //0為開漏,1為推挽(ff)
P3MDIN=0xff;
P3MDOUT=0xff; //低四位用于138
XBR0=0x02;
XBR1=0x40;
//P0=0xff;
}
void sysclk(void);
void pio(void);
void SPI(void);
void Interrupt_int(void);
void delay(uint i);
void dat_int(void);
void main(void) //主程序
{
PCA0MD &= ~0x40;// 關閉看門狗
pio();
sysclk();
SPI(); //SPI0DAT是SPI的數據寄存器
Interrupt_int();
EA=0;
dat_int();
nRF24L01_Config(); //nRF24L01的配置函數
while(1)
{
//nRF24L01_TxPacket(tx_buf);
nRF24L01_RxPacket(rx_buf);
sta=SPI_Read(READ_REG+FIFO_STATUS);
P1=rx_buf[2];
delay(10000);
if(rx_buf[2]==0xc7)break;
}
while(1)
{
nRF24L01_TxPacket(tx_buf); //發送函數
sta=SPI_Read(READ_REG+STATUS); //發送程序復位
if(sta&0x20)
{
c=1;
SPI_RW_Reg(WRITE_REG+STATUS,sta);
CSN_LOW; //清除發送寄存器的值
SPI_RW(FLUSH_TX);
CSN_HIGH;
}
delay(10000);
}
}
|