NRF905参考程序参考教程包含多个实例和解释Word文件下载.docx

上传人:b****6 文档编号:19043797 上传时间:2023-01-03 格式:DOCX 页数:33 大小:3.77MB
下载 相关 举报
NRF905参考程序参考教程包含多个实例和解释Word文件下载.docx_第1页
第1页 / 共33页
NRF905参考程序参考教程包含多个实例和解释Word文件下载.docx_第2页
第2页 / 共33页
NRF905参考程序参考教程包含多个实例和解释Word文件下载.docx_第3页
第3页 / 共33页
NRF905参考程序参考教程包含多个实例和解释Word文件下载.docx_第4页
第4页 / 共33页
NRF905参考程序参考教程包含多个实例和解释Word文件下载.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

NRF905参考程序参考教程包含多个实例和解释Word文件下载.docx

《NRF905参考程序参考教程包含多个实例和解释Word文件下载.docx》由会员分享,可在线阅读,更多相关《NRF905参考程序参考教程包含多个实例和解释Word文件下载.docx(33页珍藏版)》请在冰豆网上搜索。

NRF905参考程序参考教程包含多个实例和解释Word文件下载.docx

TXEN=0;

TRX_CE=1;

Delay

(1);

//delayformodechange(>

=650us)

}

设置发送模式,这里会有疑问,在于TRX_CE=0;

这里给出的解释是,如果我们直接写TRX_CE=1;

这样模块立即将其内部所写好的数据发送出去。

而对于编程的人员来说编出的程序五花八门,就比如说这条,改程序员的意图并不想让设置发送模式时,数据就被立即发出,所以写了TRX_CE=0;

如果看后面的完整程序,你会发现在发送时,有TRX_CE=1;

这一步。

所以说,刚才那个图表没有问题。

这里可以认为是准备发送模式,而不是发送模式,一旦TRX_CE=1;

那么数据立即被发送。

voidSetTxMode(void)

TRX_CE=0;

TXEN=1;

关于图表中前两种模式中,实例程序所应用的是第二种,即待机spi编程模式。

不管应用两种的哪一种,都是为了spi编程(通过spi通信配置905寄存器)。

那么给出这个模式的应用程序段:

有这么做引脚赋予各种电平先不用管他,我们看到PWR=1;

TRX_CE=0;

TXEN=0;

这三个,在待机spi模式中TXEN=x;

即可以为任何值。

说明现在是待机且spi编程模式。

程序段中其他引脚功能罗列下:

Csn:

spi的有效与否的引脚,低电平有效。

如果只是单纯的设置模式,该引脚并没用处,只是后期程序的编写,所以做下配置。

Sck:

spi的时钟,现在只是设置模式,还没开始spi通信,所以付个低电平。

DR:

数据是否准备好,现在没有什么可准备的。

AD,CD也是一样,等到spi通信的时候才需关系。

这里做个引子吧。

voidnRF905Init(void)

CSN=1;

//Spidisable

SCK=0;

//Spiclocklineinitlow

DR=0;

//InitDRforinput

AM=0;

//InitAMforinput

CD=0;

//InitCDforinput

PWR=1;

//nRF905poweron

//SetnRF905instandbymode

//setradioinRxmode

Nrf905寄存器的配置

配置905寄存器的意思是,通过spi传输一个值,放入905的寄存器中,这个值可以让905传输数据时,产生各种你想要的效果,类似于你用手调节耳机音量,你的手就相当于配置耳机的寄存器。

那么我先给出主要需配置的寄存器然后再解释.

如下面这个程序段:

unsignedcharidataRFConf[11]=

0x00,//配置命令//

0x4c,//CH_NO,配置频段在430MHZ

0x0c,//输出功率为10db,不重发,节电为正常模式

0x44,//地址宽度设置,为4字节

0x04,0x04,//接收发送有效数据长度为32字节

0xCC,0xCC,0xCC,0xCC,//接收地址

0x58,//CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振

};

0x00,//配置命令//后面的讲解中会说,所以大家从第二个开始看。

CH_NO的意思如下,通过以下解释设置不同的值,可以让905工作在不同频段,这个需要的话再做详解,不需要,可以照搬默认值,或者程序。

CH_NO

9

和HFREQ_PLL一起进行平率设置(默认值=001101100b=108d).fRF=(422.4+CH_NOd/10)*(1+HFREQ_PLLd)MHz

于是乎相关的就引出以下这个寄存器

HFREQ_PLL

使PLL工作于433或868/915MHz模式(默认值=0).

'

0'

–工作于433MHz频段

1'

–工作于868or915MHz频段

在这里给出个表格,如需更改该值可以参照:

工作频率

HFREQ_PLL

430.0MHz

[0]

[001001100]

433.1MHz

[001101011]

433.2MHz

[001101100]

434.7MHz

[001111011]

862.0MHz

[1]

[001010110]

868.2MHz

[001110101]

868.4MHz

[001110110]

869.8MHz

[001111101]

902.2MHz

[100011111]

902.4MHz

[100100000]

927.8MHz

[110011111]

这里做下说明:

我们拆分看看这段话。

@输出功率为10db

@不重发

@节电为正常模式

输出功率为10db,这个对于的寄存器是:

如下表,二进制10db应该是11

PA_PWR

2

输出功率(默认值=00).

“00”-10dBm

“01”-2dBm

“10”+6dBm

“11”+10dBm

不重发,针对的寄存器是:

不管怎么说,部分都不自动重发(一般情况),故二进制是0

AUTO_RETRAN

如果TRX_CE和TXEN为高时,自动重发(默认值=0).

–不重发'

–数据包重发

节电为正常模式,针对的寄存器是:

如下表,要是正常模式则二进制是0

RX_RED_PWR

接收方式节能,工作电流1.6mA.灵敏度降低(默认值=0).

–正常工作'

–节能模式

那么如下结论:

输出功率为10db--------------------11

不重发-----------------------------0

节电为正常模式---------------------0

按顺序写则是:

1100---》00001100———》0x0C

0x44,//地址宽度设置,为4字节

如下面两个表:

收地址宽度:

4字节的2进制是100

RX_AFW

3

接收地址宽度(默认值=100).

001'

–1byteRX地址

100'

–4byteRX地址

发地址宽度:

TX_AFW

发送地址宽度(default=100)

.'

–1byteTX地址

–4byteTX地址

于是乎:

100并上100,可认为是0100并上0100,可认为是4并上4,则可认为是0x44.

这条命令是我擅自更改的,更改前是2字节,如是0x04这是32字节。

这样可以使905在一个数据包内传输更多信息。

那么我给出两个寄存器。

RX_PW

6

接收数据宽度(默认=100000).

000001'

–1byte接收数据宽度

000010'

–2byte接收数据宽度

100000'

–32byte接收数据宽度

TX_PW

发送数据宽度(默认=100000).

–1byte发送数据宽度

–2byte发送数据宽度.

–32byte发送数据宽度

这里要把码补全,100000——》00100000——0x40这里实际是0x40一点没错但是程序中写的是0x04,仔细想想,也没什么特别的问题。

这里我水平有限,不做说明了。

0xCC,0xCC,0xCC,0xCC,//接收地址

一看就知道,地址被从新改了下,默认地址是E7这种。

RX_ADDRESS

32

发送地址标识,使用字节取决于RX_AFW(默认值=E7E7E7E7h).

0x58,//CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振

CRC_EN

CRC校验可用(默认值=1).

–不可用'

–可用

CRC_MODE

CRC模式选择端(默认值=1).

–8位'

–16位

UP_CLK_EN

输出时钟可用(默认值=1)

–外面没有可用的时钟信号

–外面有可用的时钟信号

XOF

晶振频率端,必须与外部的晶振频率相对应(默认值=100).

000'

–4MHz'

–8MHz'

010'

–12MHz

011'

–16MHz'

–20MHz

这块看着有点乱的话,请继续往后看。

我们既然把相关寄存器的配置解释了一边,但是如果对于一个编程序的人,或者程序开发来说,这样的罗列虽然我们能弄懂每个寄存器是咋回事,但是实际编程并自己配置寄存器的话,难度是很大的。

幸好,开发手册解决一切问题,下面是一个表,表的后面我有解释。

寄存器内容射频器配置寄存器(R/W)

字节

位内容[7:

0],最高有效位[7]

初始值

CH_NO[7:

0]

0110_1100

bit[7:

6]notused,AUTO_RETRAN,RX_RED_PWR,PA_PWR[1:

0],HFREQ_PLL,CH_NO[8]

0000_0000

bit[7]notused,TX_AFW[2:

0],bit[3]notused,RX_AFW[2:

0100_0100

6]notused,RX_PW[5:

0010_0000

4

6]notused,TX_PW[5:

5

RX_ADDRESS(deviceidentity)byte0

E7

RX_ADDRESS(deviceidentity)byte1

7

RX_ADDRESS(deviceidentity)byte2

8

RX_ADDRESS(deviceidentity)byte3

CRC_MODE,CRC_EN,XOF[2:

0],UP_CLK_EN,UP_CLK_FREQ[1:

1110_0111

解释:

这是手册中的一张表,假设寄存器的配置值是如图给的这些。

那么他的传输是从0字节开始到9字节截止,按顺序把16进制码传进去,你的工作就完成了。

而你需要对那个寄存器进行微小的改动,只需找到手册相关寄存器的说明进行改动就可以了。

我们从上表中摘出一个小表看,小表如下:

bit[7]就是该值得第七位,第七位没用上。

TX—AFW【2:

0】意思是有三位被这个寄存器用了。

等等。

通过这种字节的划分,将寄存器的配置变成了传多个2位十六进制数,使得寄存器的配置变得博大精深,新手上手困难。

不过对于驱动其他芯片也一样,配置寄存器就是这样配置的。

像是某些器件如saa7113等芯片,配置寄存器时,前面还有地址,弄得更加复杂。

所以大家要通过学习nrf905了解芯片的驱动方法这才是关键。

spi通信:

如何实现spi通信,在这个问题上,如果说正常学习应该是,先知晓spi的协议,spi的时序,spi写和读的时序和协议。

但是如果将其看成程序的话就比较方便。

咱们用程序谈这件事情。

该程序段式spi的写程序:

从MOSI=(bit)(b&

0x80);

我们分析下。

假设b=abcdefgh

那b&

0x80就是abcdefgh&

10000000可以想象a被提取了出来。

至于bit,其实可以没有,这里可以参考c51语言关于‘与‘有两个做法,一个是&

,另一个是&

&

,即位与和整个值得与。

之后我们观察sck的变化,sck是spi的时钟,我们发现从0到1然后回到0,这是sck的变化。

在sck变到1之前,mosi已经有了一个值,那么当sck=1;

的时候,也就是所谓的上升沿,mosi被写入,这里可以认为是写入905的内部了。

b<

<

=1;

这个语句等同于b=b《1;

意思是b左移一位的新值付给b,

比如b=abcdefgh左移一位,那么b=bcdefgh0,再左移一位,那么b=cdefgh00,以此类推左移8次之后b=00000000.

因为每移出一位,就代表着移进一位,移进的是0。

那么观察一下0x80——》10000000

这个数10000000与上abcdefgh之后会提取出a

左移之后,再次进行与运算,就会提取出b,循环往复abcdefgh就都提取出来了。

并在每一次都把这个值付给了mosi。

我想通过梳理,大家应该能看懂了,至于spi的通信协议,大家可以参考下网上资料,我想看懂了程序,再看看资料应该能彻底明白了。

voidSpiWrite(ucharb)

uchari=8;

while(i--)

{

Delay(10);

MOSI=(bit)(b&

SCK=1;

}

读Spi程序段:

_nop_();

是延时,延时是一个指令周期的时间。

说白了,就是延时一段时间。

ucharddata=0;

这条语句意味着ddata是完全为0的。

且注意一个事情ddata的定义是uchar,那么他的值最大能到0xff。

ddata|=MISO;

等同于ddata=ddata|miso;

miso是一个引脚的电平。

经过这条语句后ddata的最低位就是miso当时的电平了,这时左移再次提取新的miso电平,当八个电平都提取之后,ddata的值就提取完成了。

同样sck是spi时钟,想提取下一个miso的值必须让时钟波动一次。

ucharSpiRead(void)

ucharddata=0;

ddata<

_nop_();

returnddata;

到此为止,905的基本问题讲完了。

那么我们把它串联在一起。

我们先宏观的看下。

以发送流程为例

905现处于待机spi编程状态——》向905中传送寄存器值

————》@——》将905的状态设置为发送状态————》成功发出-----》待机状态

如果想再发个数据,那么他的流程将变成

@——》将905的状态设置为发送状态————》成功发出————》待机状态

由此看来对同一个对象进行发送,如果大家的设置都没改的话,寄存器的值只需设置一次。

剩下的就是重复发送到待机这个环节了。

那么在@之前的问题,大家都了解了,剩下的就是@到把数据发送这一块了。

这里我分为三个部分说这件事情。

向905传输一个命令

向905装入待发送的数据、

把数据发出去

向905传输命令:

这里定义了这些命令,先在语法上说下#defineWC0x00的意思等价于wc=0x00;

那么我们先解释下这几个命令,大家理解下。

#defineWC0x00

#defineRC0x10

#defineWTP0x20

#defineRTP0x21

#defineWTA0x22

#defineRTA0x23

#defineRRP0x24

如下是wc的解释:

在讲解配置寄存器是有个值我没有讲解先在我告诉大家

指令名称

指令格式

操作

W_CONFIG

(WC)

0000AAAA

写配置寄存器AAAA指明哪个字节。

写操作从哪个字节开始取决于地址AAAA

0x00,//配置命令//这就意味着wc=0x00,意思就是从0字节开始进行写操作。

举个例子看下,0字节代表的是哪个寄存器,

写之后的操作就是开始写1字节,这点上没什么问题最后写到第九字节。

前面有这个表的完整版,大家可以翻着看。

#defineRC0x10的解释如下:

这个看表就知道不做解释了跟wc意思差不多。

R_CONFIG

(RC)

0001AAAA

读配置寄存器AAAA指明哪个字节。

读操作从哪个字节开始取决于地址AAAA

后几个命令都好理解我就都列出来大家自己吸收下:

那么到此,命令部分就说完了,能用的就这几个命令。

向905装入待发送数据:

向905装入数据这件事情和刚才的命令结合着说。

先看以下程序段:

SpiWrite(WTP);

//Writepayloadcommand

for(i=0;

i<

4;

i++)

SpiWrite(TxRxBuf[i]);

//Write32bytesTxdata

先传了wtp命令,之后把txrxbuf数组中的前4字节传了进去。

那么执行外这条之后,数据就被传到905中了(还没有进行发送)。

观察此函数,发现调用了spiwrite这个函数,说明装入命令和装入数据都是通过spi通信进行传输的。

观察以下程序段:

SpiWrite(WTA);

//Writeaddresscommand

i++)//Write4bytesaddress

SpiWrite(TxAddress[i]);

TxAddress[i]和SpiWrite(WTA);

是其中的要素,wta是写地址命令,那么TxAddress[i]就是地址咯,地址前面说过了,程序中除了那个config数组中有地址的说法,另外在程序段中被单独列出的地方是codeTxAddress[4]={0xcc,0xcc,0xcc,0xcc};

那么通过这个程序段,功能就是把地址写进去。

以上的两个程序段完成了数据和地址的写入,这时只要设置成发送状态,数据就可以被发出了。

那么从现在开始是重点部分,就是以上两段程序的组合,并加以延伸。

仔细看下面这段程序,主要关注红字部分。

程序之后有我的相关解释。

voidTxPacket(uchar*TxRxBuf)

uchari;

//Config905();

CSN=0;

}//Spienableforwriteaspicommand

//Spidisable

//Spienableforwriteaspicommand

//SetTRX_CEhigh,startTxdatatransmission

//while(DR!

=1);

//SetTRX_CElow

上面这段程序,如果被main调用了之后,出现的效果是将txrxbuf数组中的

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

当前位置:首页 > 经管营销 > 销售营销

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

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