基于stm32f103zet6之NRF905无线模块的学习
又是因为比赛的需要,所以用起了这个无线模块,模块也是因为凑巧在同学那里搞来的,他说他现在不用,所以我就拿来主义,练练手嘛!昨天下午开始研究了,昨晚测试的时候发现有些问题,今天上午有课,没办法,值得下午来调试调试了。所幸调试通过了,谢天谢地~~~~好的,既然这样,那么就总结一下这个无线模块需要注意的地方吧,毕竟以后可是能够拿来做遥控汽车的 嘿嘿。。。。
首先给大家传一份技术参考手册,这是中文的,但是有些地方如果你觉得有问题,那么请对照这英文手册看,我就是这样干的!
地址在这里
一、硬件
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无线模块的学习相关推荐
- NRF905 无线模块实验
---恢复内容开始--- 采用2440开发板,CON4 不仅包含了很多富余的 GPIO 引脚,还包含了一些其他 CPU 引脚, 如 AD0-AIN3, CLKOUT 等.你所看到的图中的 SPI 接口 ...
- 基于STM32F103ZET6 HC_SR04超声波测距模块
这是最后的实验现象,改变不同的角度即可测得距离 板子 PZ6806L 超声波模块 HC_SR04 HC_SR04模块讲解 通过该超声波模块说明书,可明白供电需VCC 5V 还需GND ECHO(回 ...
- NRF905无线通讯小车
记录一下整的无线通讯小车,第一次使用NRF905无线模块,查了一堆资料,做了个采集小车,在此记录,防止忘记. mmexport1648565535394 功能 遥控器部分: 遥控器:遥控器上电时候停留 ...
- 基于51单片机的无线通讯公交报站系统
近些年来,随着经济的飞速发展,人们对出行有了更高要求,公交车行业发展成为一个城市必不可少的交通工具,城市公交系统也开始快速发展,不仅公交车的型号不断更新换代,而且为了公司效益目前已经全部改成无人售票车 ...
- NRF905无线通讯模块的距离到底有多远呢?
NRF905无线通讯模块的距离到底有多远呢? 我们店铺里有NRF905无线模块出售,但是,我遇到很多的客户都弄不清楚,MRF905模块的通讯距离到底有多远? 有些客户,已经买了905模块,但是通讯距离 ...
- 基于wemos D1的无线遥控灯(433m无线模块)
参考:基于wemos D1的无线遥控灯(433m无线模块) 作者:一只小阿大:) 发布时间: 2021-04-16 09:25:53 网址:https://blog.csdn.net/qq_44610 ...
- 无线控制模块c语言编程,基于STM32F103ZET6无线语音控制小车设计与实现.doc
基于STM32F103ZET6无线语音控制小车设计与实现 基于STM32F103ZET6无线语音控制小车设计与实现 摘要:本文以STM32F103ZET6单片机作为控制核心,通过LD3320语音识别模 ...
- 基于python的modbus协议编程_IM5D.6B利用(2.4G)无线模块实现远程控制(基于智能编程任务赛,2019版)...
点击「蓝色微信名」关注更多比赛信息 引 言 在<中国儿童青少年威盛中国芯计算机表演赛>从第十七届活动开始,搭建了一个全新的互联网技术支持平台,实现了网络在线比赛,在全国建立了三十个省级赛 ...
- Arduino开发遥控小车(三)基于nRF24L01无线模块实现舵机转向和直流电机调速
Arduino开发遥控小车(三)基于nRF24L01无线模块实现舵机转向和直流电机调速 前面和大家分享了通过nRF24L01无线模块实现数据发送和接收的基本方法,本次继续和大家分享最终实现遥控小车转向 ...
最新文章
- Vue 组件库 HeyUI@1.19.0 发布,新增 Icon 图标
- oracle中app文件夹下,Oracle Form开发之folder(文件夹)功能开发(一)
- SIFT原理与源码分析:DoG尺度空间构造
- linux c 文件映射,linuxc试题
- 【网络与系统安全】关于SSL/TSL协议的分析
- COVID-19和世界幸福报告数据告诉我们什么?
- 1-3 交换变量(算法竞赛入门经典)
- 推荐10个最好的Javascript和CSS库
- 三星Samsung笔记本电脑开机进入BIOS的方法与BIOS设置全功能菜单(F2)
- SQL 2019——新特征
- 较常用的Math方法及ES6中的扩展
- Flask 下载中文名文件
- VS2012 VS2010 VTK引入设置
- MATLAB矩阵运算
- android表格布局占满整行,Android布局之表格布局TableLayout详解
- 《遥感基础导论》知识图——第五章 微波遥感数据
- 【汇编】DOS系统功能调用(INT 21H)
- iOS Instrument
- essay--网络常用省略语大全(ZT)
- 层层递进!MySQL性能优化步骤演进,一顿饭的时间我就会了