找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3554|回复: 1
打印 上一主题 下一主题
收起左侧

C8051F的nRF24L01 PTR6000无线收发

[复制链接]
跳转到指定楼层
楼主
ID:75926 发表于 2015-4-4 02:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


/************************发送部分*********************/
#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);
}
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:76142 发表于 2015-4-4 23:26 | 只看该作者
谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表