求一份nrf24l01模块与stc89c52单片机连接通信的C程序(收,发)

另外你知道STC 51内核 40pin的哪种有硬件spi的
80249815@qq.com

第1个回答  推荐于2016-02-07
/*********************************发送程序*****************************************************/
#include <reg52.h>
#include <intrins.h>
typedef unsigned int uint;
typedef unsigned char uchar;
#define TX_ADDR_WITDH 5//发送地址宽度设置为5个字节
#define RX_ADDR_WITDH 5//接收地址宽度设置为5个字节
#define TX_DATA_WITDH 8//
#define RX_DATA_WITDH 8
/******************************************************************
// nRF24L01指令格式:
*******************************************************************/
#define R_REGISTER 0x00 // 读寄存器
#define W_REGISTER 0x20 // 写寄存器
#define R_RX_PLOAD 0x61 // 读RX FIFO有效数据,1-32字节,当读数据完成后,数据被清除,应用于接收模式
#define W_TX_PLOAD 0xA0 // 写TX FIFO有效数据,1-32字节,写操作从字节0开始,应用于发射模式
#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,应用于发射模式
#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,应用于接收模式
#define REUSE_TX_PL 0xE3 // 重新使用上一包有效数据,当CE为高过程中,数据包被不断的重新发射
#define NOP 0xFF // 空操作,可以用来读状态寄存器
/******************************************************************
// nRF24L01寄存器地址
*******************************************************************/
#define CONFIG 0x00 // 配置寄存器
#define EN_AA 0x01 // “自动应答”功能寄存
#define EN_RX_ADDR 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 // 数据通道1有效数据宽度设置寄存器
#define RX_PW_P2 0x13 // 数据通道2有效数据宽度设置寄存器
#define RX_PW_P3 0x14 // 数据通道3有效数据宽度设置寄存器
#define RX_PW_P4 0x15 // 数据通道4有效数据宽度设置寄存器
#define RX_PW_P5 0x16 // 数据通道5有效数据宽度设置寄存器
#define FIFO_STATUS 0x17 // FIFO状态寄存器
//*********************************************************************************
uchar sta; // 状态变量
#define RX_DR (sta & 0x40) // 接收成功中断标志
#define TX_DS (sta & 0x20) // 发射成功中断标志
#define MAX_RT (sta & 0x10) // 重发溢出中断标志
sbit CE=P2^0;
sbit IRQ=P1^0;
sbit CSN=P2^1;
sbit MOSI=P2^3;
sbit MISO=P2^4;
sbit SCK=P2^2;
//sbit LED=P0^0;
sbit Key=P3^2;
uchar code TX_Addr[]={0x34,0x43,0x10,0x10,0x01};
uchar code TX_Buffer[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x00};
uchar RX_Buffer[RX_DATA_WITDH];
void _delay_us(uint x)
{
uint i,j;
for (j=0;j<x;j++)
for (i=0;i<12;i++);
}
void _delay_ms(uint x)
{
uint i,j;
for (j=0;j<x;j++)
for (i=0;i<120;i++);
}
/*nRF24L01初始化*/
void nRF24L01_Init(void)
{
CE=0;//待机模式Ⅰ
CSN=1;
SCK=0;
IRQ=1;
}
/*SPI时序函数*/
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++)//一字节8位循环8次写入
{
if(byte&0x80)//如果数据最高位是1
MOSI=1;//向NRF24L01写1
else //否则写0
MOSI=0;
byte<<=1;//低一位移到最高位
SCK=1;//SCK拉高,写入一位数据,同时读取一位数据
if(MISO)
byte|=0x01;
SCK=0;//SCK拉低
}
return byte;//返回读取一字节
}
/*SPI写寄存器一字节函数*/
/*reg:寄存器地址*/
/*value:一字节(值)*/
uchar SPI_W_Reg(uchar reg,uchar value)
{
uchar status;//返回状态
CSN=0;//SPI片选
status=SPI_RW(reg);//写入寄存器地址,同时读取状态
SPI_RW(value);//写入一字节
CSN=1;//
return status;//返回状态
}
/*SPI读一字节*/
uchar SPI_R_byte(uchar reg)
{
uchar reg_value;
CSN=0;//SPI片选
SPI_RW(reg);//写入地址
reg_value=SPI_RW(0);//读取寄存器的值
CSN=1;
return reg_value;//返回读取的值
}
/*SPI读取RXFIFO寄存器数据*/
/*reg:寄存器地址*/
/*Dat_Buffer:用来存读取的数据*/
/*DLen:数据长度*/
uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)
{
uchar status,i;
CSN=0;//SPI片选
status=SPI_RW(reg);//写入寄存器地址,同时状态
for(i=0;i<Dlen;i++)
{
Dat_Buffer[i]=SPI_RW(0);//存储数据
}
CSN=1;
return status;
}
/*SPI向TXFIFO寄存器写入数据*/
/*reg:写入寄存器地址*/
/*TX_Dat_Buffer:存放需要发送的数据*/
/*Dlen:数据长度*/
uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)
{
uchar status,i;
CSN=0;//SPI片选,启动时序
status=SPI_RW(reg);
for(i=0;i<Dlen;i++)
{
SPI_RW(TX_Dat_Buffer[i]);//发送数据
}
CSN=1;
return status;
}
/*设置发送模式*/
void nRF24L01_Set_TX_Mode(uchar *TX_Data)
{
CE=0;//待机(写寄存器之前一定要进入待机模式或掉电模式)
SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);/*写寄存器指令+接收节点地址+地址宽度*/
SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);/*为了接收设备应答信号,接收通道0地址与发送地址相同*/
SPI_W_DBuffer(W_TX_PLOAD,TX_Data,TX_DATA_WITDH);/*写有效数据地址+有效数据+有效数据宽度*/
SPI_W_Reg(W_REGISTER+EN_AA,0x01);/*接收通道0自动应答*/
SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);/*使能接收通道0*/
SPI_W_Reg(W_REGISTER+SETUP_RETR,0x0a);/*自动重发延时250US+86US,重发10次*/
SPI_W_Reg(W_REGISTER+RF_CH,0);/*(2400+40)MHZ选择射频通道0X40*/
SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);/*1Mbps速率,发射功率:0DBM,低噪声放大器增益*/
SPI_W_Reg(W_REGISTER+CONFIG,0x0e);/*发送模式,上电,16位CRC校验,CRC使能*/
CE=1;//启动发射
_delay_ms(5);/*CE高电平持续时间最少10US以上*/
}
uchar Check_Rec(void)
{
uchar status;
sta=SPI_R_byte(R_REGISTER+STATUS);
if(RX_DR)
{
CE=0;
SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);
status=1;
}
SPI_W_Reg(W_REGISTER+STATUS,0xff);
return status;
}
/*检测应答信号*/
uchar Check_Ack(void)
{
sta=SPI_R_byte(R_REGISTER+STATUS);/*读取寄存状态*/
if(TX_DS||MAX_RT)/*如果TX_DS或MAX_RT为1,则清除中断和清除TX_FIFO寄存器的值*/
{
SPI_W_Reg(W_REGISTER+STATUS,0xff);
CSN=0;
SPI_RW(FLUSH_TX);/*如果没有这一句只能发一次数据,大家要注意*/
CSN=1;
return 0;
}
else
return 1;
}
void main(void)
{
uchar i;
P0=0xff;//初始化IO口
P1=0xff;
P2=0xff;
P3=0xff;
_delay_us(100);
nRF24L01_Init();//NRF24L01初始化
while(1)
{
if(Key==0)
{
_delay_ms(10);
if(Key==0)
{
for(i=0;i<TX_DATA_WITDH;i++)//发送7次数据
{
nRF24L01_Set_TX_Mode(&TX_Buffer[i]);//发送数据
while(Check_Ack());//等待发送完成
//LED=~LED;
}
}
}
}
}
/----------------------------------------------接收程序--------------------------------------------/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define TX_ADDR_WITDH 5//发送地址宽度设置为5个字节
#define RX_ADDR_WITDH 5
#define TX_DATA_WITDH 8
#define RX_DATA_WITDH 8
/******************************************************************
// nRF24L01指令格式:
*******************************************************************/
#define R_REGISTER 0x00 // 读寄存器
#define W_REGISTER 0x20 // 写寄存器
#define R_RX_PLOAD 0x61 // 读RX FIFO有效数据,1-32字节,当读数据完成后,数据被清除,应用于接收模式
#define W_TX_PLOAD 0xA0 // 写TX FIFO有效数据,1-32字节,写操作从字节0开始,应用于发射模式
#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,应用于发射模式
#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,应用于接收模式
#define REUSE_TX_PL 0xE3 // 重新使用上一包有效数据,当CE为高过程中,数据包被不断的重新发射
#define NOP 0xFF // 空操作,可以用来读状态寄存器
/******************************************************************
// nRF24L01寄存器地址
*******************************************************************/
#define CONFIG 0x00 // 配置寄存器
#define EN_AA 0x01 // “自动应答”功能寄存器
#define EN_RX_ADDR 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 // 数据通道1有效数据宽度设置寄存器
#define RX_PW_P2 0x13 // 数据通道2有效数据宽度设置寄存器
#define RX_PW_P3 0x14 // 数据通道3有效数据宽度设置寄存器
#define RX_PW_P4 0x15 // 数据通道4有效数据宽度设置寄存器
#define RX_PW_P5 0x16 // 数据通道5有效数据宽度设置寄存器
#define FIFO_STATUS 0x17 // FIFO状态寄存器
//*********************************************************************************
uchar sta; // 状态变量
#define RX_DR (sta & 0x40) // 接收成功中断标志
#define TX_DS (sta & 0x20) // 发射成功中断标志
#define MAX_RT (sta & 0x10) // 重发溢出中断标志

sbit CE=P2^0;
sbit IRQ=P2^5;
sbit CSN=P2^1;
sbit MOSI=P2^3;
sbit MISO=P2^4;
sbit SCK=P2^2;
sbit LED=P3^2;
uchar code TX_Addr[]={0x34,0x43,0x10,0x10,0x01};
uchar code TX_Buffer[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar RX_Buffer[RX_DATA_WITDH];
void _delay_us(uint x)
{
uint i,j;
for (j=0;j<x;j++)
for (i=0;i<12;i++);
}
void _delay_ms(uint x)
{
uint i,j;
for (j=0;j<x;j++)
for (i=0;i<120;i++);
}
void nRF24L01_Init(void)
{
_delay_us(2000);
CE=0;
CSN=1;
SCK=0;
IRQ=1;
}
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
if(byte&0x80)
MOSI=1;
else
MOSI=0;
byte<<=1;
SCK=1;
if(MISO)
byte|=0x01;
SCK=0;
}
return byte;
}
uchar SPI_W_Reg(uchar reg,uchar value)
{
uchar status;
CSN=0;
status=SPI_RW(reg);
SPI_RW(value);
CSN=1;
return status;
}
uchar SPI_R_byte(uchar reg)
{
uchar status;
CSN=0;
SPI_RW(reg);
status=SPI_RW(0);
CSN=1;
return status;
}
uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)
{
uchar reg_value,i;
CSN=0;
reg_value=SPI_RW(reg);
for(i=0;i<Dlen;i++)
{
Dat_Buffer[i]=SPI_RW(0);
}
CSN=1;
return reg_value;
}
uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)
{
uchar reg_value,i;
CSN=0;
reg_value=SPI_RW(reg);
for(i=0;i<Dlen;i++)
{
SPI_RW(TX_Dat_Buffer[i]);
}
CSN=1;
return reg_value;
}
void nRF24L01_Set_RX_Mode(void)
{
CE=0;//待机
SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);
SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);
SPI_W_Reg(W_REGISTER+EN_AA,0x01);//auot ack
SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);
SPI_W_Reg(W_REGISTER+SETUP_RETR,0x0a);
SPI_W_Reg(W_REGISTER+RX_PW_P0,RX_DATA_WITDH);
SPI_W_Reg(W_REGISTER+RF_CH,0);
SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);//0db,lna
SPI_W_Reg(W_REGISTER+CONFIG,0x0f);
CE=1;
_delay_ms(5);
}
uchar nRF24L01_RX_Data(void)
{
//uchar i,status;
sta=SPI_R_byte(R_REGISTER+STATUS);
if(RX_DR)
{
CE=0;
SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);
//P3=RX_Buffer[0];
SPI_W_Reg(W_REGISTER+STATUS,0xff);
CSN=0;
SPI_RW(FLUSH_RX);
CSN=1;
return 1;
}
else
return 0;
}
void main(void)
{
uchar i;
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
_delay_us(1000);
nRF24L01_Init();
while(1)
{
nRF24L01_Set_RX_Mode();
_delay_ms(100);
if(nRF24L01_RX_Data())
{
LED=0;
//delay_ms(300);
}
else
LED=1;
}
}

希望对您有所帮助,谢谢!本回答被提问者采纳

STC89C52与nrf24l01连接电路
你好:电路设计的可以,STC89C52的P0.0-P0.7为开漏极输出,也就是单片机内部没有上拉电阻,输出高电平时为高阻态,外部上拉电阻上端接在3.6V,通过这些上拉电阻为NRF24L01引脚提供3.6V高电平。输出低电平时,直接将上拉电阻下端连接到地,NRF24L01变为0V低电平,所以说你设计的原理图是对的,但是...

你好,我想问一下24L01能不能和51单片机除P0口以外的其他口直接相连?
不可以直接相连,个人建议数据口拉10K下拉电阻到地,我以前也是看到网上说只要串接电阻就可以,结果测试数据口,电压达到4.几伏,最后还是倒导致芯片被烧坏。最后听了一位工程师说是电压倒灌,数据口需要接10K下拉电阻才可以,听了他的话才慢慢调通了。连接图:程序可以参考:http:\/\/zhidao.baidu.com\/q...

求AD中可以直接使用的STC89C52和nRF24L01元件!
单片机与51是兼容的库里就有,nrf24L01可以搜一下,如果没有只能上网找找了。

单片机开发板怎么用?
7. AD模块:主芯片为ADC0804,采集模拟信号(1路输入),并转化为数字信号,内置8位转换器(分辨率为8位)。 8. DA模块:主芯片为DAC0832, 把数字信号转化为模拟信号,分辨率为8位。 9. 串口通信模块:主芯片我们使用了MAX232的升级版MAX3232,通信性能更好。MAX3232把TTL电平转换为RS232电平。 10. 1602液晶显示模块:...

相似回答