又是因为比赛的需要,所以用起了这个无线模块,模块也是因为凑巧在同学那里搞来的,他说他现在不用,所以我就拿来主义,练练手嘛!昨天下午开始研究了,昨晚测试的时候发现有些问题,今天上午有课,没办法,值得下午来调试调试了。所幸调试通过了,谢天谢地~~~~好的,既然这样,那么就总结一下这个无线模块需要注意的地方吧,毕竟以后可是能够拿来做遥控汽车的 嘿嘿。。。。

首先给大家传一份技术参考手册,这是中文的,但是有些地方如果你觉得有问题,那么请对照这英文手册看,我就是这样干的!

地址在这里

一、硬件

nrf905这个芯片我们就不谈了,涉及到高频、射频是比较复杂,主要针对如何使用这个模块谈一谈

这是涉及到我们编程的引脚图, 其中uclk在这里不用,下面请看管脚图

总结一下这个管脚表的比较重要的信息如下:

1、nrf905和单片机通信使用的是SPI协议,我这里用的是软件模拟spi,硬件spi有其他用途

2、电源3.3V没有问题,IO口电压完全兼容匹配,输出电流也是没有问题的

3、CD是载波检测信号,意思是当我们的模块作为接收的时候,一旦它接收到发射模块同一个频段的信号时,该引脚会被nrf905置高,平常为低!

4、AM是地址匹配的意思,当作为接收模块的时候,当接收地址和发射地址匹配的时候,那么该引脚会被nrf905置高,平常为低!

5、DR表示数据接收或者发送成功!当一个正确的数据包接收完毕, RF905自动移去字校验位,然后把DR引脚置高,平常为低!

注意了:CD、AM、DR3个引脚的状态在我们调试的时候是非常重要的,所以充分利用这几个引脚的功能!

硬件方面需要注意的地方我们已经说完了,接下来分析我的程序!

二、软件

首先是发送流程:

1、当微控制器有数据要发送时,通过SPI协议将地址和要发送的数据送传给RF905,SPI接口的速率在通信协议和器件配置时确定;  
2、微控制器置高TRX_CE和TX_EN,这就设置为了发送数据模式  
3、RF905发送流程:
(1) 射频寄存器自动开启;  
(2) 数据打包(加字头和CRC校验
(3) 发送数据包;  
(4) 当数据发送完成,

(1)(2)俩步自动完成!

4、AUTO_RETRAN被置高,RF905不断重发,直到TRX_
5、当TRX_CE被置低,RF905发送过程完成,自动进入空闲模式。 
注意:ShockBurstTM工作模式保证,一旦发送数据的过程开始,无论
TRX_EN和TX_EN引脚是高或低,发送过程都会被处理完。只有在前一
个数据包被发送完毕,RF905才能接受下一个发送数据包。

然后是接收流程:

1、当 TRX_CE 为高、TX_EN 为低时,RF905 进入 ShockBurstTM 接收模式; 
2、650us 后,RF905 不断监测,等待接收数据;  
3、当 RF905 检测到同一 频段的载波时,载波检测引脚被置高;  
4、当接收到一个相匹配的地址,AM 引脚被置高;  
5、当一个正确的数据包接收完毕, RF905 自动移去字头、地址和 CRC校验位,然后把 DR 引脚置高  
6、微控制器把 TRX_CE 置低,nRF905 进入空闲模式;  
7、 微控制器通过 SPI 口,以一定的速率把数据移到微控制器内;  
8、 当所有的数据接收完毕,nRF905 把 DR 引脚和 AM 引脚置低;  
9、nRF905 此时可以进入 ShockBu rstTM 接收模式、ShockBurstTM 发送模式或关机模式。  当正在接收一个数据包时,TRX_CE 或 TX_EN 引脚的状态发生改变,
RF905 立即把其工作模式改变,数据包则丢失。

需要注意的是:我们设置接收模式的时候,是需要先把数据写入nrf905模块,然后才使能发送引脚的!!!

接下来就是拿具体的程序来分析了

A.首先看我的主函数,很简单

int main(void)
{//初始化系统定时器SysTick_Init();USART1_Config();NRF905_Init();NRF905_Config();SetTxMode();while(1){TxPacket(TxBuf);Delay_ms(2000);}
}

注意这个模式

B.然后就是这个配置NRF905的函数,这个可是关键啊,具体数据的选择,最好是能看一下芯片手册,这里我把代码贴出来

/**************************************************************************************
* 名    称: NRF905_Init
* 功    能: 配置NRF905寄存器
* 参    数: 无
* 调用方式:NRF905_Init();
* 返 回 值:无
**************************************************************************************/
void NRF905_Config(void)
{u8 i;NRF905_CSN_L;                             // Spi enable for write a spi commandNRF905_SPI_Write_Byte(WC);                     // Write config command写放配置命令for (i = 0;i < RxTxConf.n; i++)                      // Write configration words  写放配置字{NRF905_SPI_Write_Byte(RxTxConf.buf[i]);}for(i = 0; i < 10; i ++){printf(" %x \r",RxTxConf.buf[i]);}NRF905_CSN_H;                             // Disable Spi
}

其实简单来说给它发的内容就是:

/**************************************************************************************
* 名    称: 配置寄存器中的内容!
**************************************************************************************/
RFConfig RxTxConf ={10,0x4c,   //CH_NO[7:0] 连同字节 1 的 CH_NO[8]和 HFREQ_PLL 控制 905 的载波频段 433MHZ0x0c, //7,6:no use;5:自动重发=0;4:接收灵敏度降低=0;3,2:发射功率=10dBm;1:433MHz;CH_NO[8]=00x44, //7:no use;6,5,4:发送地址宽度4;3:no use;2,1,0:接收地址宽度40x20, //7,6 no use;5-0:接收数据宽度320x20, //7,6 no use;5-0:发送数据宽度320xcc, //接收地址字节0(设备ID)0xcc, //接收地址字节1(设备ID)0xcc, //接收地址字节2(设备ID)0xcc, //接收地址字节3(设备ID)0x58   //7:CRC模式8位;6:CRC校验许可;5,4,3:011表示16MHz;2:UP_CLK_EN=0没有外部时钟;1,0:外部时钟频率
};

这就是根据寄存器的格式含义来的,其实也没有什么好说的,但是我总是怀疑芯片手册上有些问题,那个应该是433.0MHZ

C.接下来看我们是怎么实现发送数据的吧,我把我的代码贴出来,然后对着分析就好了。

/**************************************************************************************
* 名    称: TxPacket
* 功    能: 发送数据包
* 参    数: 需要发送的内容
* 调用方式:TxPacket();
* 返 回 值: MISO的值
**************************************************************************************/
void TxPacket(u8 *TxBuf)
{u8 i;          NRF905_CSN_L;                       // 使能SPINRF905_SPI_Write_Byte(WTP);             // Write payload commandfor (i=0;i<32;i++){NRF905_SPI_Write_Byte(TxBuf[i]);       // Write 32 bytes Tx data}for(i = 0; i < 32;i ++){printf("%x \r",TxBuf[i]);}NRF905_CSN_H;                       // Spi disable      Delay_us(2);                NRF905_CSN_L;                       // Spi enable for write a spi command   NRF905_SPI_Write_Byte(WTA);             // Write address commandfor (i=0;i<4;i++)                 // Write 4 bytes address{NRF905_SPI_Write_Byte(RxTxConf.buf[i+5]);}for(i = 0; i < 4;i ++){printf("%x \r",RxTxConf.buf[i+5]);}NRF905_CSN_H;                        // Spi disableNRF905_TRX_CE_H;                  // Set TRX_CE high,start Tx data transmission   先写数据然后开启发送Delay_ms(100);                        //记得给反应时间while(!DR_read())      {printf("DATA Send failed!!!\n");}printf("DATA send success !!!\n");NRF905_TRX_CE_L;                    // Set TRX_CE low
}

上述的printf函数都是我加上的打印函数,方便调试的!

大家可能好奇之前的模式设置是不是出问题了,心想,当设置为发送的时候应该是两个都选择为高啊,但是这里要告诉你,传输数据的时候,我是这样理解的,选择模式的时候

先将EN失能。然后当我们通过SPI写入了数据之后才使用这句

 NRF905_TRX_CE_H;            // Set TRX_CE high,start Tx data transmission   先写数据然后开启发送

这样就是为了消除干扰吧,我是这样想的。

D.最后贴上部分驱动函数

/**************************************************************************************
* 名    称: SetTxMode
* 功    能: 设置NRF905发送状态
* 参    数: 无
* 调用方式:SetTxMode();
* 返 回 值:无
**************************************************************************************/
void SetTxMode(void)
{   NRF905_TX_EN_H;NRF905_TRX_CE_L;     //为什么置低,先写数据后发送,所以要后拉高Delay_us(650);
}
/**************************************************************************************
* 名    称: SetRxMode
* 功    能: 设置NRF905发送状态
* 参    数: 无
* 调用方式:SetRxMode();
* 返 回 值:无
**************************************************************************************/
void SetRxMode(void)
{NRF905_TX_EN_L;NRF905_TRX_CE_H;Delay_us(650);
}
/**************************************************************************************
* 名    称: CD_read
* 功    能: 读取CD的值(载波检测)
* 参    数: 无
* 调用方式:CD_read();
* 返 回 值: CD的值
**************************************************************************************/
u8 CD_read(void)
{   u8 ReadValue;ReadValue = NRF905_CD_DATA;return ReadValue;
}
/**************************************************************************************
* 名    称: AM_read
* 功    能: 读取AM的值(地址匹配AM)
* 参    数: 无
* 调用方式:AM_read();
* 返 回 值: AM的值
**************************************************************************************/
u8 AM_read(void)
{   u8 ReadValue;ReadValue = NRF905_AM_DATA;return ReadValue;
}
/**************************************************************************************
* 名    称: DR_read
* 功    能: 读取CD的值(数据就绪DR)
* 参    数: 无
* 调用方式:DR_read();
* 返 回 值: DR的值
**************************************************************************************/
u8 DR_read(void)
{   u8 ReadValue;ReadValue = NRF905_DR_DATA;return ReadValue;
}
/**************************************************************************************
* 名    称: NRF905_SPI_Read_Bit
* 功    能: 读取MISO的值
* 参    数: 无
* 调用方式:NRF905_SPI_Read_Bit();
* 返 回 值: MISO的值,0或者1
**************************************************************************************/
static u8 NRF905_SPI_Read_Bit(void)
{   u8 ReadValue;ReadValue = NRF905_MISO_DATA;return ReadValue;
}
/**************************************************************************************
* 名    称: NRF905_SPI_Read_Byte
* 功    能: 读取MISO的值,字节的形式
* 参    数: 无
* 调用方式:NRF905_SPI_Read_Byte();
* 返 回 值: MISO的值
**************************************************************************************/
u8 NRF905_SPI_Read_Byte(void)
{u8 i;u8 Temp_data; for (i = 0;i < 8;i ++)                // Setup byte circulation bits{ Temp_data = Temp_data << 1;      // Right shift Temp_dataNRF905_SCK_H;               // Set clock line highif (NRF905_SPI_Read_Bit()){Temp_data |= 0x01;        // Read data}                       NRF905_SCK_L;               // Set clock line low}return Temp_data;             // Return function parameter
}
/**************************************************************************************
* 名    称: NRF905_SPI_Write_Byte
* 功    能: NRF905写1字节函数
* 参    数: DATA: 需要写入的字节
* 调用方式:NRF905_SPI_Write_Byte(0xaa);
* 返 回 值:无
**************************************************************************************/
void NRF905_SPI_Write_Byte(u8 DATA)
{u8 i,Temp_data;Temp_data = DATA;for (i=0;i<8;i++){if (Temp_data & 0x80)             //总是发送最高位{NRF905_MOSI_H;}else{NRF905_MOSI_L;}NRF905_SCK_H;Temp_data=Temp_data<<1;NRF905_SCK_L;}
}

需要程序的可以留言.....
代码已经上传至 http://download.csdn.net/detail/king_bingge/5797627

基于stm32f103zet6之NRF905无线模块的学习相关推荐

  1. NRF905 无线模块实验

    ---恢复内容开始--- 采用2440开发板,CON4 不仅包含了很多富余的 GPIO 引脚,还包含了一些其他 CPU 引脚, 如 AD0-AIN3, CLKOUT 等.你所看到的图中的 SPI 接口 ...

  2. 基于STM32F103ZET6 HC_SR04超声波测距模块

    这是最后的实验现象,改变不同的角度即可测得距离 板子 PZ6806L 超声波模块 HC_SR04 HC_SR04模块讲解 通过该超声波模块说明书,可明白供电需VCC 5V  还需GND  ECHO(回 ...

  3. NRF905无线通讯小车

    记录一下整的无线通讯小车,第一次使用NRF905无线模块,查了一堆资料,做了个采集小车,在此记录,防止忘记. mmexport1648565535394 功能 遥控器部分: 遥控器:遥控器上电时候停留 ...

  4. 基于51单片机的无线通讯公交报站系统

    近些年来,随着经济的飞速发展,人们对出行有了更高要求,公交车行业发展成为一个城市必不可少的交通工具,城市公交系统也开始快速发展,不仅公交车的型号不断更新换代,而且为了公司效益目前已经全部改成无人售票车 ...

  5. NRF905无线通讯模块的距离到底有多远呢?

    NRF905无线通讯模块的距离到底有多远呢? 我们店铺里有NRF905无线模块出售,但是,我遇到很多的客户都弄不清楚,MRF905模块的通讯距离到底有多远? 有些客户,已经买了905模块,但是通讯距离 ...

  6. 基于wemos D1的无线遥控灯(433m无线模块)

    参考:基于wemos D1的无线遥控灯(433m无线模块) 作者:一只小阿大:) 发布时间: 2021-04-16 09:25:53 网址:https://blog.csdn.net/qq_44610 ...

  7. 无线控制模块c语言编程,基于STM32F103ZET6无线语音控制小车设计与实现.doc

    基于STM32F103ZET6无线语音控制小车设计与实现 基于STM32F103ZET6无线语音控制小车设计与实现 摘要:本文以STM32F103ZET6单片机作为控制核心,通过LD3320语音识别模 ...

  8. 基于python的modbus协议编程_IM5D.6B利用(2.4G)无线模块实现远程控制(基于智能编程任务赛,2019版)...

    点击「蓝色微信名」关注更多比赛信息 引  言 在<中国儿童青少年威盛中国芯计算机表演赛>从第十七届活动开始,搭建了一个全新的互联网技术支持平台,实现了网络在线比赛,在全国建立了三十个省级赛 ...

  9. Arduino开发遥控小车(三)基于nRF24L01无线模块实现舵机转向和直流电机调速

    Arduino开发遥控小车(三)基于nRF24L01无线模块实现舵机转向和直流电机调速 前面和大家分享了通过nRF24L01无线模块实现数据发送和接收的基本方法,本次继续和大家分享最终实现遥控小车转向 ...

最新文章

  1. Vue 组件库 HeyUI@1.19.0 发布,新增 Icon 图标
  2. oracle中app文件夹下,Oracle Form开发之folder(文件夹)功能开发(一)
  3. SIFT原理与源码分析:DoG尺度空间构造
  4. linux c 文件映射,linuxc试题
  5. 【网络与系统安全】关于SSL/TSL协议的分析
  6. COVID-19和世界幸福报告数据告诉我们什么?
  7. 1-3 交换变量(算法竞赛入门经典)
  8. 推荐10个最好的Javascript和CSS库
  9. 三星Samsung笔记本电脑开机进入BIOS的方法与BIOS设置全功能菜单(F2)
  10. SQL 2019——新特征
  11. 较常用的Math方法及ES6中的扩展
  12. Flask 下载中文名文件
  13. VS2012 VS2010 VTK引入设置
  14. MATLAB矩阵运算
  15. android表格布局占满整行,Android布局之表格布局TableLayout详解
  16. 《遥感基础导论》知识图——第五章 微波遥感数据
  17. 【汇编】DOS系统功能调用(INT 21H)
  18. iOS Instrument
  19. essay--网络常用省略语大全(ZT)
  20. 层层递进!MySQL性能优化步骤演进,一顿饭的时间我就会了

热门文章

  1. Cognitive Behavioral Therapy by Lawrence Wallace
  2. diff文件对比命令
  3. python变量前面加星(*)含义
  4. 如何利用对象存储构建静态网站
  5. 异常检测与误用检测的简单对比
  6. 如何学习编程——来自认知科学的四个建议
  7. php程序员职业规划书范文,计算机专业职业生涯规划书
  8. Ocelot 通过C#代码,添加Header信息给到下游
  9. 第四次工业革命:自主经济的崛起
  10. 测试:视频播放器、视频通话、视频类网站 测试点