NRF905参考程序参考教程包含多个实例和解释.docx

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

NRF905参考程序参考教程包含多个实例和解释.docx

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

NRF905参考程序参考教程包含多个实例和解释.docx

NRF905参考程序参考教程包含多个实例和解释

NRF905程序参考教程。

本资料主要是将程序中各部分子程序的功能与NRF905的手册相关联,使得各位同仁在每个子程序为什么这么写都在手册中找到具体的体现,特别是寄存器配置。

内涵完整参考程序,是100%可用程序。

硬件的连接方法在参考程序之后,并介绍原理。

本人最后只是为了提供给大家一个入门的资料或是引子罢了,至于如何应用的巧妙那是后期编程巧妙的结果,目前只是给刚进门的人士一个可以快速理解和掌握的浅显易懂的教程罢了。

本人疏忽之处还请见谅。

 

按照惯例先展示作品抛砖引玉:

四路AD采集+温度采集

彩屏显示信息数据GSM手机电话

最近做的,音频功放四路电机控制大功率led控制,不解释。

以前做的,舵机和摄像头,不解释。

更早先的,VGA显示,不解释。

已发送为例子。

1.通过spi接口把寄存器相应的值写到905中

2.把要发的数据写到905中

3.把状态设置成发送

4.数据被发出

那么操作905就主要是前三步的问题,那么请带个这前三个问题深入理解下面的相关解释了。

 

无线通信模块的三个要素:

Nrf905模式的配置

Nrf905通过寄存器配置

Nrf905需要spi通信配置寄存器

先看模式配置:

程序加解释

PWR_UP

TRX_CE

TX_EN

操作模式

0

X

X

断电和SPI编程

1

0

X

待机和SPI编程

1

1

0

射频接收模式

1

1

1

射频发送模式

根据这个图表,我们发觉有四种模式。

捡重点的说实现收发功能有两种模式。

这两种模式在程序段中的实现是:

设置成接受模式,程序中没写PWR_UP,如果他是低电平就变成断电,所以个程序段默认PWR_UP为高电平。

voidSetRxMode(void)

{

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;

Delay

(1);//delayformodechange(>=650us)

}

关于图表中前两种模式中,实例程序所应用的是第二种,即待机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

TRX_CE=0;//SetnRF905instandbymode

TXEN=0;//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

1

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

'0'–工作于433MHz频段

'1'–工作于868or915MHz频段

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

工作频率

HFREQ_PLL

CH_NO

430.0MHz

[0]

[001001100]

433.1MHz

[0]

[001101011]

433.2MHz

[0]

[001101100]

434.7MHz

[0]

[001111011]

862.0MHz

[1]

[001010110]

868.2MHz

[1]

[001110101]

868.4MHz

[1]

[001110110]

869.8MHz

[1]

[001111101]

902.2MHz

[1]

[100011111]

902.4MHz

[1]

[100100000]

927.8MHz

[1]

[110011111]

 

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

这里做下说明:

我们拆分看看这段话。

@输出功率为10db

@不重发

@节电为正常模式

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

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

PA_PWR

2

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

“00”-10dBm

“01”-2dBm

“10”+6dBm

“11”+10dBm

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

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

AUTO_RETRAN

1

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

'0'–不重发'1'–数据包重发

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

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

RX_RED_PWR

1

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

'0'–正常工作'1'–节能模式

那么如下结论:

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

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

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

按顺序写则是:

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

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

如下面两个表:

收地址宽度:

4字节的2进制是100

RX_AFW

3

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

'001'–1byteRX地址

'100'–4byteRX地址

发地址宽度:

4字节的2进制是100

TX_AFW

3

发送地址宽度(default=100)

.'001'–1byteTX地址

'100'–4byteTX地址

于是乎:

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

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

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

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

那么我给出两个寄存器。

RX_PW

6

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

'000001'–1byte接收数据宽度

'000010'–2byte接收数据宽度

'100000'–32byte接收数据宽度

TX_PW

6

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

'000001'–1byte发送数据宽度

'000010'–2byte发送数据宽度.

'100000'–32byte发送数据宽度

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

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

 

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

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

RX_ADDRESS

32

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

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

CRC_EN

1

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

'0'–不可用'1'–可用

CRC_MODE

1

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

'0'–8位'1'–16位

UP_CLK_EN

1

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

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

'1'–外面有可用的时钟信号

XOF

3

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

'000'–4MHz'001'–8MHz'010'–12MHz

'011'–16MHz'100'–20MHz

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

 

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

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

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

字节

位内容[7:

0],最高有效位[7]

初始值

0

CH_NO[7:

0]

0110_1100

1

bit[7:

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

0],HFREQ_PLL,CH_NO[8]

0000_0000

2

bit[7]notused,TX_AFW[2:

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

0]

0100_0100

3

bit[7:

6]notused,RX_PW[5:

0]

0010_0000

4

bit[7:

6]notused,TX_PW[5:

0]

0010_0000

5

RX_ADDRESS(deviceidentity)byte0

E7

6

RX_ADDRESS(deviceidentity)byte1

E7

7

RX_ADDRESS(deviceidentity)byte2

E7

8

RX_ADDRESS(deviceidentity)byte3

E7

9

CRC_MODE,CRC_EN,XOF[2:

0],UP_CLK_EN,UP_CLK_FREQ[1:

0]

1110_0111

 

解释:

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

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

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

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

bit[7]notused,TX_AFW[2:

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

0]

0100_0100

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);

SCK=0;

MOSI=(bit)(b&0x80);

b<<=1;

Delay(10);

SCK=1;

Delay(10);

SCK=0;

}

 

读Spi程序段:

_nop_();_nop_();是延时,延时是一个指令周期的时间。

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

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

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

ddata|=MISO;等同于ddata=ddata|miso;miso是一个引脚的电平。

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

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

ucharSpiRead(void)

{

uchari=8;

ucharddata=0;

while(i--)

{

ddata<<=1;

SCK=0;

_nop_();_nop_();

ddata|=MISO;

SCK=1;

_nop_();_nop_();

}

SCK=0;

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

unsignedcharidataRFConf[11]=

{

0x00,//配置命令//

 

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

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

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

字节

位内容[7:

0],最高有效位[7]

初始值

0

CH_NO[7:

0]

0110_1100

写之后的操作就是开始写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

for(i=0;i<4;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;

SpiWrite(WTP);//Writepayloadcommand

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

{

SpiWrite(TxRxBuf[i]);//Write32bytesTxdata

}//Spienableforwriteaspicommand

CSN=1;

Delay

(1);//Spidisable

CSN=0;//Spienableforwriteaspicommand

SpiWrite(WTA);//Writeaddresscommand

for(i=0;i<4;i++)//Write4bytesaddress

{

SpiWrite(TxAddress[i]);

}

CSN=1;//Spidisable

TRX_CE=1;//SetTRX_CEhigh,startTxdatatransmission

Delay

(1);//while(DR!

=1);

TRX_CE=0;//SetTRX_CElow

}

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

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

当前位置:首页 > 表格模板 > 表格类模板

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

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