资讯详情

C8051F的nRF24L01 PTR6000无线收发

/************************发送部分*********************/

#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_WH 4 //地址数据 #define RX_PLOAD_WIDTH 4 //接收的有效数据宽度 #define TX_PLOAD_WIDTH 4 //发送的有效数据宽度 #define BUSY I0CFG&0x80

uchar TX_AESS[]={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 Q=P0^4; sbit c=P0^7;

//24L01寄存器地址 #define CFIG 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 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_ATUS 0X17//FIFO状态寄存器 //SPI命令字 #define READ_REG 0X00//读寄存器命令 #define WRI_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//配置寄存器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台