51单片机应用之无线通讯模块.docx

上传人:b****5 文档编号:7635729 上传时间:2023-01-25 格式:DOCX 页数:54 大小:8.56MB
下载 相关 举报
51单片机应用之无线通讯模块.docx_第1页
第1页 / 共54页
51单片机应用之无线通讯模块.docx_第2页
第2页 / 共54页
51单片机应用之无线通讯模块.docx_第3页
第3页 / 共54页
51单片机应用之无线通讯模块.docx_第4页
第4页 / 共54页
51单片机应用之无线通讯模块.docx_第5页
第5页 / 共54页
点击查看更多>>
下载资源
资源描述

51单片机应用之无线通讯模块.docx

《51单片机应用之无线通讯模块.docx》由会员分享,可在线阅读,更多相关《51单片机应用之无线通讯模块.docx(54页珍藏版)》请在冰豆网上搜索。

51单片机应用之无线通讯模块.docx

51单片机应用之无线通讯模块

30、51单片机应用之............无线通讯模块NRF24L01+

(一)基础知识篇

 

今天刚调试好,先看图吧!

这张是AT89C2051控制NRF24L01+做发射调试。

看看NRF24L01细节吧!

这是LCD屏显示:

AT89S52做接收测试:

正在接收时的显示:

接收到数据后显示32个数据值:

 

无线模块NRF24L01+应用上篇结束,敬请期待NRF24L01+下篇的调试部分。

31、51单片机应用之............无线通讯模块NRF24L01+

(二)模块调试篇

 

32、51单片机应用之............无线通讯模块NRF24L01+(三)发送与接收模块的联调

33、51单片机应用之............无线通讯模块NRF24L01+(四)举例应用

34、补充NRF24L01+之————LED调试篇

写了前面四篇关于NRF24L01通讯调试的文章,看来大家还是很喜欢,有帮助的。

有很多大学生朋友问我说,我们没有两个LCD来显示调试状态,连一个也没有,能不能用几个LED来显示调试状态呢因此我就写这篇补充调试的文章,就用P0口的8个LED来显示调试NRF24L01到成功进行数据通讯。

先把51单片机的最小系统准备好,还有8个LED的小电路板,如果你的LED就在系统板上那省了这一步。

8个LED的小板子电路很简单,但你焊接要可靠,不然电路本身都不稳定,后面对判断故障会产生很大影响。

NRF24L01+模块电路还是前面说过的那样:

相同的两个模块的板子。

好!

假设我们用P0口来作LED显示、用P1口来作模块接口,下面我们先写一段最简单的程序,来确认LED电路,和P0、P1口的完好!

#include<>

#include<>

#defineuintunsignedint

typedefunsignedcharuchar;

//*********************************

//   延时函数

//在晶振为12MHz时,延时count毫秒

//*********************************

voidDelayms(uintcount)

{

uinti;

while(count--)

{for(i=0;i<80;i++){}

}

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

}

//*********************************

//主函数

//*********************************

voidmain()

{

P0=0x00;//P0口LED点亮

P1=0x00;//P1口LED点亮

P2=0x00;

P3=0x00;

Delayms(2000);//延时2秒

while

(1)

{

P0=~P0;//将P0口数据取反,原来亮的就熄灭

P1=~P1;//将P1口数据取反,原来亮的就熄灭

P2=~P2;

P3=~P3;

Delayms(500);//延时半秒

}

}

这是段极简单的程序,用来检测单片机电路连接的正确性,和IO口的工作状态是否正常,为后面调试NRF24L01做好准备。

它的工作状态如下:

同样的,把LED的接口再接到P1口,看看它是否一样的在全部闪烁。

做好了这步,准备工作就算完成了。

接下来我们把NRF24L01+的模块插上,要注意,接口要对清楚,电源要连接正确:

接下来我们写发送程序:

//**********************************

//NRF24L01+模块发射程序

//用8个LED调试

//Txz001

//**********************************

#include<>

typedefunsignedcharuchar;//将无符号字节类型重定义为uchar

typedefunsignedintuint;//将无符号整数类型重定义为Uint

//*********************NRF24L01函数定义****************************

voiddelayms(uintt);//毫秒延时

voidinit_NRF24L01(void);//模块初始化函数

ucharSPI_RW(ucharreg);//基本SPI读写时序

ucharSPI_Read(ucharreg);//从寄存器reg读一个字节

voidSetRX_Mode(void);//设置接收模式

ucharSPI_RW_Reg(ucharreg,ucharvalue);//向寄存器写一个字节

ucharSPI_Read_Buf(ucharreg,uchar*pBuf,ucharuchars);//从缓冲器读出uchars字节的数据

ucharSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars);//向缓冲器写进uchars字节的数据

voidnRF24L01_TxPacket(uchar*tx_buf);//启动一次发送

ucharnRF24L01_RxPacket(uchar*rx_buf);//读取接收的数据,放入rx_buf数组

//***********NRF24L01模块IO端口定义******************

sbitCE=P1^0;

sbitCSN=P1^1;

sbitSCK=P1^2;

sbitMOSI=P1^3;

sbitMISO=P1^4;

sbitIRQ=P1^5;

//*****************NRF24L01常量**********************

#defineTX_ADR_WIDTH5//发送地址宽度5字节

#defineRX_ADR_WIDTH5//接收地址宽度5字节

#defineTX_PLOAD_WIDTH32//发送数据宽度32字节

#defineRX_PLOAD_WIDTH32//接收数据的宽度32字节

ucharconstTX_ADDRESS[TX_ADR_WIDTH]={0x01,0x02,0x03,0x04,0x05};//本地地址

ucharconstRX_ADDRESS[RX_ADR_WIDTH]={0x01,0x02,0x03,0x04,0x05};//接收地址

//*****************NRF24L01寄存器指令*******************

#defineREAD_REG0x00//读寄存器指令

#defineWRITE_REG0x20//写寄存器指令

#defineRD_RX_PLOAD0x61//读取接收数据指令

#defineWR_TX_PLOAD0xA0//写待发数据指令

#defineFLUSH_TX0xE1//清空发送缓冲区

//**************SPI(nRF24L01)寄存器地址常量*****************

#defineCONFIG0x00//配置收发状态,CRC校验模式以及收发状态响应方式

#defineEN_AA0x01//自动应答功能设置

#defineEN_RXADDR0x02//可用信道设置

#defineSETUP_AW0x03//收发地址宽度设置

#defineSETUP_RETR0x04//自动重发功能设置

#defineRF_CH0x05//工作频率设置

#defineRF_SETUP0x06//发射速率、功耗功能设置

#defineSTATUS0x07//状态寄存器

#defineOBSERVE_TX0x08//发送监测功能

#defineCD0x09//地址检测

#defineRX_ADDR_P00x0A//频道0接收数据地址

#defineRX_ADDR_P10x0B//频道1接收数据地址

#defineRX_ADDR_P20x0C//频道2接收数据地址

#defineRX_ADDR_P30x0D//频道3接收数据地址

#defineRX_ADDR_P40x0E//频道4接收数据地址

#defineRX_ADDR_P50x0F//频道5接收数据地址

#defineTX_ADDR0x10//发送地址寄存器

#defineRX_PW_P00x11//接收频道0接收数据长度

#defineRX_PW_P10x12//接收频道0接收数据长度

#defineRX_PW_P20x13//接收频道0接收数据长度

#defineRX_PW_P30x14//接收频道0接收数据长度

#defineRX_PW_P40x15//接收频道0接收数据长度

#defineRX_PW_P50x16//接收频道0接收数据长度

#defineFIFO_STATUS0x17//FIFO栈入栈出状态寄存器设置

/*****毫秒延时子程序*****/

voiddelayms(uintt)//约延时t毫秒

{

uinti;

while(t--)

{

for(i=0;i<125;i++);

}

}

/**********************************************

/*函数:

uintSPI_RW(uintuchar)

/*功能:

NRF24L01的SPI写时序

/**********************************************/

ucharSPI_RW(ucharuuchar)

{

ucharbit_ctr;

for(bit_ctr=0;bit_ctr<8;bit_ctr++)//输出8个位

{

MOSI=(uuchar&0x80);//输出uuhar的最高位

uuchar=(uuchar<<1);//左移一位

SCK=1;//将时钟线置‘1’

uuchar|=MISO;//同时读取STATUS

SCK=0;//然后再将时钟线置‘0’

}

return(uuchar);//返回读取的值

}

/***********************************************

/*函数:

ucharSPI_Read(ucharreg)

/*功能:

NRF24L01的SPI读取一个字节时序

/***********************************************/

ucharSPI_Read(ucharreg)

{

ucharreg_val;

CSN=0;//CSN置'0',允许指令操作

SPI_RW(reg);//写一条reg指令

reg_val=SPI_RW(0);//读取reg的值到reg_val

CSN=1;//CSN置'1',禁示操作

return(reg_val);//返回读取的值

}

/***********************************************

/*功能:

NRF24L01写一个字节到寄存器函数

/***********************************************/

ucharSPI_RW_Reg(ucharreg,ucharvalue)

{

ucharstatus;

CSN=0;//CSN置'0',允许操作

status=SPI_RW(reg);//这指令,并读STATUS

SPI_RW(value);//写数据值到reg

CSN=1;//CSN置'1',禁止操作

return(status);//returnnRF24L01statusuchar

}

/*****************************************************************

/*函数:

uintSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars)

/*功能:

用于写数据:

reg:

为寄存器地址,

/*pBuf:

为待写入数据地址,

/*uchars:

写入数据的个数

/*****************************************************************/

ucharSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars)

{

ucharstatus,uchar_ctr;

CSN=0;//SPI使能

status=SPI_RW(reg);

for(uchar_ctr=0;uchar_ctr

SPI_RW(*pBuf++);

CSN=1;//关闭SPI

return(status);//

}

//******************************************

/*NRF24L01初始化

//******************************************/

voidinit_NRF24L01(void)

{

delayms

(1);

CE=0;//射频停止工作

CSN=1;//停止寄存器读写

SCK=0;//时种信号停止读写

IRQ=1;//中断复位

SPI_RW_Reg(WRITE_REG+EN_AA,0x00);//频道0自动ACK应答禁止

SPI_RW_Reg(WRITE_REG+SETUP_RETR,0x00);//禁止自动发送

SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x01);//允许接收地址只有频道0,

SPI_RW_Reg(WRITE_REG+RF_CH,1);//设置信道工作为,收发必须一致

SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//设置接收数据长度,本次设置为32字节

SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07);//设置发射速率为2MHZ,发射功率为最大值0dB

}

/******************************************************

/*函数:

voidnRF24L01_TxPacket(unsignedchar*tx_buf)

/*功能:

发送tx_buf中数据

/*******************************************************/

voidnRF24L01_TxPacket(unsignedchar*tx_buf)

{

CE=0;//StandByI模式

SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);//写本地地址

SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//装载接收端地址

SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);//装载数据

SPI_RW_Reg(WRITE_REG+CONFIG,0x0e);//IRQ收发完成中断响应,16位CRC,主发送

CE=1;//置高CE,激发数据发送

delayms

(1);

}

//************************************

//主函数

//************************************

voidmain()

{

ucharTxBuf[32];

ucharstatus;//定义一个变量用来装读取到的STATUS数值

init_NRF24L01();//NRF24L01初始化

SPI_RW_Reg(WRITE_REG+STATUS,0XFF);//清状态寄存器

status=SPI_Read(STATUS);//读取状态

P0=~status;//P0口显示读取的状态

delayms(4000);//显示延时4秒,以便从容看清楚

P0=0xff;//清除显示

delayms(600);

TxBuf[0]=1;//我们设置个初值1在想要发送的数组的第1个里变量里。

while

(1)

{TxBuf[0]=~TxBuf[0];//这句把要发送的第1个变量的值取反,如果原来是1,现再就为0

nRF24L01_TxPacket(TxBuf);//装载数据并进行一次发送操作

status=SPI_Read(STATUS);//发送完后再读取状态

P0=~status;//显示发送完后的状态

delayms(500);//显示发送后的信息停留1秒

P0=0xFF;//清除显示

delayms(500);

}

}

程序看上去挺长,其实大部分都是常量的定义。

主要的几句就在主函数里,要注意的是接口的定义跟你插在板子上接口要一致。

电源不能接错哦!

这个程序很简单,开始对NRF24L01初始化,然后读取它的状态值显示在P0口,正确的状态应为00001110,然后停顿4秒,让我可以从容看清状态。

然后进入循环发送状态,先将要发送的数据取反,就是说,这次发送0,下次就发送1,这样交替进行,以便后面接收时,我们可以看到变化。

接下来就是进行发送,发送完后,再读取状态并显示。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1