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

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

地址在这里

一、硬件

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. STM32 基础系列教程 41 – SDMMC
  2. 如何成立一家私募基金公司
  3. 使用FuncT, TResult 委托实现API日志的记录
  4. 岗位理解_如何正确理解策划岗位
  5. c语言p1-melepeo,C语言做个学生选课系统 -电脑资料
  6. php 数组排序以及按照某个字段排序
  7. MoguBlog(蘑菇博客)v5.3发布,前后端分离博客系统
  8. HDU6072 Logical Chain
  9. NC63重写导入功能
  10. 用计算机三角函数公式,电脑是通过什么公式计算出三角函数的?
  11. 如何快速剪辑多个视频,将视频分段保存导出播放
  12. 图像技术_基础技术(0001)_RGB与CMYK的定义和详细区别
  13. 【node.js】识别图片中的文字
  14. android layout_gravity gravity
  15. st7920驱动OCMJ2X8C屏使用CGRAM自定义图标
  16. Ubuntu16.04 安装ROS Kinetic 究级详细教程
  17. 大学英语听说教程4听力原文及答案
  18. 关于催款程序的构思与实现
  19. 1核1g1m服务器相当于什么性能,1核1g1m的云服务器能干嘛
  20. 用python编写累加_python中累加怎么做

热门文章

  1. 为什么投了很多简历,却总是没有答复呢
  2. 如何低成本高效率自学Java
  3. 欧拉数 e=2.71828...(Eulers_Number)
  4. select 标签自定义样式
  5. ibm服务器安装2008系统蓝屏,ibm x3550m3 serverguide_8.42 引导安装server 2003 蓝屏 错误代码 0x000007b...
  6. 显示人社服务器异常,居住证办理时提示人社在线接口异常无法获取社保信息该怎么办...
  7. 面试篇之计算机网络基础
  8. Java自学资料!996页阿里Java面试真题解析火爆全网,实战案例
  9. 选好一个springboot计算机毕业设计选题目,让导师对你刮目相看
  10. 如何在一分钟内吸引投资者