奋斗STM32V3版 2.4G无线通信例程
- 格式:pdf
- 大小:1.58 MB
- 文档页数:22
1.简介通过SPI方式与NRF24L01模块进行通讯,接收到的数据通过串口1打印出来,实时监测是否收到数据,发送的数据是“2.4G TEST”,当收不到数据时打印“no data”。
一块STM32F103ZET6开发板接收数据,另一块STM32F103RBT6开发板发送数据,两个淘宝买的2.4G NRF24L01模块。
还用到一块USB转TTL模块用来电平转换传送数据,串口调试助手接收串口发送数据。
2.代码部分---------nrf24l01.h-----------#ifndef __24L01_H#define __24L01_H#include "sys.h"/////////////////////////////////////////////////////////////////////////////// /////////////////////////////NRF24L01寄存器操作命令#define NRF_READ_REG 0x00 //读配置寄存器,低5位为寄存器地址#define NRF_WRITE_REG 0x20 //写配置寄存器,低5位为寄存器地址#define RD_RX_PLOAD 0x61 //读RX有效数据,1~32字节#define WR_TX_PLOAD 0xA0 //写TX有效数据,1~32字节#define FLUSH_TX 0xE1 //清除TX FIFO寄存器.发射模式下用#define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用#define REUSE_TX_PL 0xE3 //重新使用上一包数据,CE为高,数据包被不断发送.#define NOP 0xFF //空操作,可以用来读状态寄存器//SPI(NRF24L01)寄存器地址#define CONFIG 0x00 //配置寄存器地址;bit0:1接收模式,0发射模式;bit1:电选择;bit2:CRC模式;bit3:CRC使能;//bit4:中断MAX_RT(达到最大重发次数中断)使能;bit5:中断TX_DS使能;bit6:中断RX_DR使能#define EN_AA 0x01 //使能自动应答功能 bit0~5,对应通道0~5#define EN_RXADDR 0x02 //接收地址允许,bit0~5,对应通道0~5#define SETUP_AW 0x03 //设置地址宽度(所有数据通道):bit1,0:00,3字节;01,4字节;02,5字节;#define SETUP_RETR 0x04 //建立自动重发;bit3:0,自动重发计数器;bit7:4,自动重发延时 250*x+86us#define RF_CH 0x05 //RF通道,bit6:0,工作通道频率;#define RF_SETUP 0x06 //RF寄存器;bit3:传输速率(0:1Mbps,1:2Mbps);bit2:1,发射功率;bit0:低噪声放大器增益#define STATUS 0x07 //状态寄存器;bit0:TX FIFO满标志;bit3:1,接收数据通道号(最大:6);bit4,达到最多次重发//bit5:数据发送完成中断;bit6:接收数据中断;#define MAX_TX 0x10 //达到最大发送次数中断#define TX_OK 0x20 //TX发送完成中断#define RX_OK 0x40 //接收到数据中断#define OBSERVE_TX 0x08 //发送检测寄存器,bit7:4,数据包丢失计数器;bit3:0,重发计数器#define CD 0x09 //载波检测寄存器,bit0,载波检测;#define RX_ADDR_P0 0x0A //数据通道0接收地址,最大长度5个字节,低字节在前#define RX_ADDR_P1 0x0B //数据通道1接收地址,最大长度5个字节,低字节在前#define RX_ADDR_P2 0x0C //数据通道2接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;#define RX_ADDR_P3 0x0D //数据通道3接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;#define RX_ADDR_P4 0x0E //数据通道4接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;#define RX_ADDR_P5 0x0F //数据通道5接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;#define TX_ADDR 0x10 //发送地址(低字节在前),ShockBurstTM模式下,RX_ADDR_P0与此地址相等#define RX_PW_P0 0x11 //接收数据通道0有效数据宽度(1~32字节),设置为0则非法#define RX_PW_P1 0x12 //接收数据通道1有效数据宽度(1~32字节),设置为0则非法#define RX_PW_P2 0x13 //接收数据通道2有效数据宽度(1~32字节),设置为0则非法#define RX_PW_P3 0x14 //接收数据通道3有效数据宽度(1~32字节),设置为0则非法#define RX_PW_P4 0x15 //接收数据通道4有效数据宽度(1~32字节),设置为0则非法#define RX_PW_P5 0x16 //接收数据通道5有效数据宽度(1~32字节),设置为0则非法#define NRF_FIFO_STATUS 0x17 //FIFO状态寄存器;bit0,RX FIFO寄存器空标志;bit1,RXFIFO满标志;bit2,3,保留//bit4,TX FIFO空标志;bit5,TX FIFO满标志;bit6,1,循环发送上一数据包.0,不循环;////////////////////////////////////////////////////////////////////////////////////////////////////////////24L01操作线#define NRF24L01_CE_High GPIO_SetBits(GPIOB,GPIO_Pin_4) //24l01片选#define NRF24L01_CE_Low GPIO_ResetBits(GPIOB,GPIO_Pin_4) //24L01片选信号#define NRF24L01_CSN_High GPIO_SetBits(GPIOB,GPIO_Pin_5) //SPI片选信号#define NRF24L01_CSN_Low GPIO_ResetBits(GPIOB,GPIO_Pin_5)#define NRF24L01_IRQ GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6) //IRQ主机数据输入//24L01发送接收数据宽度定义#define TX_ADR_WIDTH 5 //5字节的地址宽度#define RX_ADR_WIDTH 5 //5字节的地址宽度#define TX_PLOAD_WIDTH 32 //32字节的用户数据宽度#define RX_PLOAD_WIDTH 32 //32字节的用户数据宽度void NRF24L01_Init(void); //初始化void NRF24L01_RX_Mode(void); //配置为接收模式void NRF24L01_TX_Mode(void); //配置为发送模式u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 u8s);//写数据区u8 NRF24L01_Read_Buf(u8 reg, u8 *pBuf, u8 u8s); //读数据区u8 NRF24L01_Read_Reg(u8 reg); //读寄存器u8 NRF24L01_Write_Reg(u8 reg, u8 value); //写寄存器u8 NRF24L01_Check(void); //检查24L01是否存在u8 NRF24L01_TxPacket(u8 *txbuf); //发送一个包的数据u8 NRF24L01_RxPacket(u8 *rxbuf); //接收一个包的数据#endif-----------nrf24l01.c----------------#include "24l01.h"#include "delay.h"#include "usart.h"///////////////////////////////////////////////////////////////////////////////const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//初始化24L01的IO口void NRF24L01_Init(void){GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );//SPI2时钟使能GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOBGPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //PB13/14/15上拉SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI 单向或者双向的数据模式:SPI设置为双线双向全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步时钟的空闲状态为高电平SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式SPI_Init(SPI2, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器//使能SPI外设GPIO_InitStructure.GPIO_Pin =GPIO_Pin_4|GPIO_Pin_5; //PB12上拉防止W25X的干扰GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PG6 输入GPIO_Init(GPIOB, &GPIO_InitStructure);//使能SPI外设SPI_Cmd(SPI2, ENABLE);NRF24L01_CE_Low; //使能24L01NRF24L01_CSN_High; //SPI片选取消}//SPIx 读写一个字节//TxData:要写入的字节//返回值:读取到的字节u8 SPI2_ReadWriteByte(u8 TxData){while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); //检查指定的SPI标志位设置与否:发送缓存空标志位SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据delay_us(2);while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);//检查指定的SPI标志位设置与否:接受缓存非空标志位return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据delay_us(2);}//检测24L01是否存在//返回值:0,成功;1,失败u8 NRF24L01_Check(void){u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};u8 i;//SPI2_SetSpeed(SPI_BaudRatePrescaler_4); //spi速度为9Mhz(24L01的最大SPI 时钟为10Mhz)NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址for(i=0;i<5;i++)if(buf[i]!=0XA5)break;if(i!=5)return 1;//检测24L01错误return 0; //检测到24L01}//SPI写寄存器//reg:指定寄存器地址//value:写入的值u8 NRF24L01_Write_Reg(u8 reg,u8 value){u8 status;NRF24L01_CSN_Low; //使能SPI传输status =SPI2_ReadWriteByte(reg);//发送寄存器号SPI2_ReadWriteByte(value); //写入寄存器的值NRF24L01_CSN_High; //禁止SPI传输return(status); //返回状态值}//读取SPI寄存器值//reg:要读的寄存器u8 NRF24L01_Read_Reg(u8 reg){u8 reg_val;NRF24L01_CSN_Low; //使能SPI传输SPI2_ReadWriteByte(reg); //发送寄存器号reg_val=SPI2_ReadWriteByte(0XFF);//读取寄存器内容NRF24L01_CSN_High; //禁止SPI传输return(reg_val); //返回状态值}//在指定位置读出指定长度的数据//reg:寄存器(位置)//*pBuf:数据指针//len:数据长度//返回值,此次读到的状态寄存器值u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len){u8 status,u8_ctr;NRF24L01_CSN_Low; //使能SPI传输status=SPI2_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SPI2_ReadWriteByte(0XFF);//读出数据NRF24L01_CSN_High; //关闭SPI传输return status; //返回读到的状态值}//在指定位置写指定长度的数据//reg:寄存器(位置)//*pBuf:数据指针//len:数据长度//返回值,此次读到的状态寄存器值u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len){u8 status,u8_ctr;NRF24L01_CSN_Low; //使能SPI传输status = SPI2_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPI2_ReadWriteByte(*pBuf++); //写入数据NRF24L01_CSN_High; //关闭SPI传输return status; //返回读到的状态值}//启动NRF24L01发送一次数据//txbuf:待发送数据首地址//返回值:发送完成状况u8 NRF24L01_TxPacket(u8 *txbuf){u8 sta;// SPI2_SetSpeed(SPI_BaudRatePrescaler_8);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)NRF24L01_CE_Low;NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节NRF24L01_CE_High;//启动发送//while(NRF24L01_IRQ!=0);//等待发送完成sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志if(sta&MAX_TX)//达到最大重发次数{NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器return MAX_TX;}if(sta&TX_OK)//发送完成{return TX_OK;}return 0xff;//其他原因发送失败}//启动NRF24L01发送一次数据//txbuf:待发送数据首地址//返回值:0,接收完成;其他,错误代码u8 NRF24L01_RxPacket(u8 *rxbuf){u8 sta;//SPI2_SetSpeed(SPI_BaudRatePrescaler_8); //spi速度为9Mhz(24L01的最大SPI 时钟为10Mhz)sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志if(sta&RX_OK)//接收到数据{NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器return 0;}return 1;//没收到任何数据}//该函数初始化NRF24L01到RX模式//设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR//当CE变高后,即进入RX模式,并可以接收数据了void NRF24L01_RX_Mode(void){NRF24L01_CE_Low;NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);/ /写RX节点地址NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通信频率NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式NRF24L01_CE_High; //CE为高,进入接收模式}//该函数初始化NRF24L01到TX模式//设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR//PWR_UP,CRC使能//当CE变高后,即进入RX模式,并可以接收数据了//CE为高大于10us,则启动发送.void NRF24L01_TX_Mode(void){NRF24L01_CE_Low;NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACKNRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通道为40NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断NRF24L01_CE_High;//CE为高,10us后启动发送}-------usart.h----------#ifndef __USART_H#define __USART_H#include "stdio.h"#include "sys.h"/////////////////////////////////////////////////////////////////////////////// void uart_init(u32 bound);void usart1_send_string(u8 *BuffToSend);#endif---------usart.c---------------#include "sys.h"#include "usart.h"/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void uart_init(u32 bound){//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);//使能USART1,GPIOA时钟//USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10//Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器//USART 初始化设置USART_ART_BaudRate = bound;//串口波特率USART_ART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_ART_StopBits = USART_StopBits_1;//一个停止位USART_ART_Parity = USART_Parity_No;//无奇偶校验位USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART1, ENABLE); //使能串口1}//打印字符串void usart1_send_string(u8 *BuffToSend){u8 i=0;while(BuffToSend[i]!='\0'){USART_SendData(USART1, BuffToSend[i]);while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);i++;}}收发主函数是分开写的,因为用的不同的芯片。
课程设计说明书题目:基于STM32的无线通信系统设计课程: ARM课程设计院(部):计算机科学与技术学院专业:计算机科学与技术专业班级:学生姓名:学号:指导教师:完成日期:目录课程设计说明书 (I)课程设计任务书 (2)1.课程设计题目 (3)2.课程设计目的 (3)3.课程设计内容 (3)3.1硬件资源 (3)3.2软件资源 (8)3.3调试环境准备与使用 (11)3.4系统设计步骤 (12)3.4.1需求分析 (12)3.4.2概要设计 (12)3.4.3详细设计 (16)3.4.4系统实现及调试 (20)3.4.5功能测试 (40)3.4.6系统评价(结果分析) (41)3.5.结论(体会) (42)3.6.参考文献 (42)课程设计指导教师评语 (43)山东建筑大学计算机科学与技术学院课程设计任务书1.课程设计题目基于STM32的无线通信系统设计2.课程设计目的《ARM课程设计》是计算机科学与技术专业的专业限定选修实践课程,是学习《嵌入式系统设计》课程后必要的实践教学环节。
通过本课程设计使学生加深理解、巩固课堂教学和平时实验内容,使学生初步具备嵌入式应用系统分析、系统设计、系统实现与测试的实际能力,强化学生的实践意识、提高动手能力,发挥学生的想象力和创新能力,从而实现课程教学目标。
提高综合运用所学知识进行系统分析、设计的能力。
加深对嵌入式软件开发流程以及项目开发步逐的认识,进一步熟悉UC/OS-II的一直与使用,进一步熟悉UCGUI的使用,提高嵌入式软件开发所必须的技能。
本课程设计主要培养学生在嵌入式系统设计方面的能力。
通过本课程的学习和实践,学生应能在嵌入式系统组成形式、构造方法、设计流程以及基于集成开发环境调试嵌入式系统的方法等方面得到锻炼,在硬件系统设计(整合)、操作系统移植、应用程序编写等方面得到全面训练。
3. 课程设计内容3.1 硬件资源基于奋斗STM32开发板,完成<基于STM32的无线通信系统设计>的设计及调试。
2.4G无线模块收发实验z意义与作用现实生活中,无线通信到处存在,手机、电视、无线遥控以及卫星等等。
很多爱好者非常期望了解无线通信时如何实现的?从信号的编码,信道传输,信号编码以及传输过程中,根据距离控制发送功率等等?以下我们将通过2.4Gh的无线模块收发实验简单了解这一系列的实现过程。
z实验原理本实验实现的功能是:使用两块带有2.4G无线模块nRF24L01的神舟IV号开发板。
神舟IV号STM32开发板在上电后先检测nRF24L01模式是否在位,如果没有在位,则通过LCD或者串口提示检查nRF24L01无线模块的连接情况直至连接正常;如果在位,初始化nRF24L01模块,提示选择nRF24L01模块的工作模式:发送或接收。
在开发板上KEY1 按键:设置NRF24L01为接收模式,KEY2 按键:设置NRF24L01为发送模式。
发送方周期性的发送变化的数据,并在串口和LCD显示发送内容和是否成功;接收方等待并接收数据,并在串口和LCD显示接收到的内容。
首先我们简单了解nRF24L01无线模块的特点以及工作原理。
nRF24L01无线模块,主要芯片是nRF24L01,其特点如下:2.4Ghz全球开放ISM频段免许可证使用;采用GFSK方式调制,数据传输率为1Mb/s或者2Mb/s;具有自动应答和自动再发射功能;125个频道,可以满足多点通信;具有CRC校验;低电压供电:1.9V~3.6V;模块可软件设地址,只有收到本机地址时才会输出数据(提供中断指示),nRF24L01内置频率合成器、功率放大器、晶体振荡器、调制器等功能模块。
其功耗低,在以-6dBm功率发射时,工作电流只有9mA;而接收时,工作电流只有12.3mA。
接下来,我们一起了解nRF24L01的收发原理。
发送数据时,首先将nRF24L01配置为发送模式;接着把发送地址和发送数据按照时序要求经过SPI总线写入nRF24L01缓存区,发送数据必须在SPI片选CSN为低时,连续写入。
STM32的24l01的子程序#include "24l01.h"#include "lcd.h"#include "delay.h"#include "spi.h"//Mini STM32开发板//NRF24L01 驱动函数//正点原子@ALIENTEK//2010/6/16const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址//初始化24L01的IO口void NRF24L01_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE );GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_SetBits(GPIOC,GPIO_Pin_4);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //上拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);SPIx_Init(); //初始化SPIClr_NRF24L01_CE; //使能24L01 NRF24L01_CESet_NRF24L01_CSN; //SPI片选取消NRF24L01_CSN}//检测24L01是否存在//返回值:0,成功;1,失败u8 NRF24L01_Check(void){u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};u8 i;SPIx_SetSpeed(SPI_BaudRatePrescaler_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)NRF24L01_Write_Buf(NRF24L01_WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址for(i=0;i<5;i++)if(buf[i]!=0XA5)break;if(i!=5)return 1;//检测24L01错误return 0; //检测到24L01}//SPI写寄存器//reg:指定寄存器地址//value:写入的值u8 NRF24L01_Write_Reg(u8 reg,u8 value){u8 status;Clr_NRF24L01_CSN; //使能SPI传输status =SPIx_ReadWriteByte(reg);//发送寄存器号SPIx_ReadWriteByte(value); //写入寄存器的值Set_NRF24L01_CSN; //禁止SPI传输return(status); //返回状态值}//读取SPI寄存器值//reg:要读的寄存器u8 NRF24L01_Read_Reg(u8 reg){u8 reg_val;Clr_NRF24L01_CSN; //使能SPI传输SPIx_ReadWriteByte(reg); //发送寄存器号reg_val=SPIx_ReadWriteByte(0XFF);//读取寄存器内容Set_NRF24L01_CSN; //禁止SPI传输return(reg_val); //返回状态值}//在指定位置读出指定长度的数据//reg:寄存器(位置)//*pBuf:数据指针//len:数据长度//返回值,此次读到的状态寄存器值u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len){u8 status,u8_ctr;Clr_NRF24L01_CSN; //使能SPI传输status=SPIx_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SPIx_ReadWriteByte(0XFF);//读出数据Set_NRF24L01_CSN; //关闭SPI传输return status; //返回读到的状态值}//在指定位置写指定长度的数据//reg:寄存器(位置)//*pBuf:数据指针//len:数据长度//返回值,此次读到的状态寄存器值u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len){u8 status,u8_ctr;Clr_NRF24L01_CSN; //使能SPI传输status = SPIx_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPIx_ReadWriteByte(*pBuf++); //写入数据Set_NRF24L01_CSN; //关闭SPI传输return status; //返回读到的状态值}//启动NRF24L01发送一次数据//txbuf:待发送数据首地址//返回值:发送完成状况u8 NRF24L01_TxPacket(u8 *txbuf){u8 sta;SPIx_SetSpeed(SPI_BaudRatePrescaler_8);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)Clr_NRF24L01_CE;NRF24L01_Write_Buf(NRF24L01_WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节Set_NRF24L01_CE;//启动发送while(NRF24L01_IRQ!=0);//等待发送完成sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值NRF24L01_Write_Reg(NRF24L01_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志if(sta&MAX_TX)//达到最大重发次数{NRF24L01_Write_Reg(NRF24L01_FLUSH_TX,0xff);//清除TX FIFO寄存器return MAX_TX;}if(sta&TX_OK)//发送完成{return TX_OK;}return 0xff;//其他原因发送失败}//启动NRF24L01发送一次数据//txbuf:待发送数据首地址//返回值:0,接收完成;其他,错误代码u8 NRF24L01_RxPacket(u8 *rxbuf){u8 sta;SPIx_SetSpeed(SPI_BaudRatePrescaler_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值NRF24L01_Write_Reg(NRF24L01_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志if(sta&RX_OK)//接收到数据{NRF24L01_Read_Buf(NRF24L01_RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据NRF24L01_Write_Reg(NRF24L01_FLUSH_RX,0xff);//清除RX FIFO寄存器return 0;}return 1;//没收到任何数据}//该函数初始化NRF24L01到RX模式//设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR//当CE变高后,即进入RX模式,并可以接收数据了void RX_Mode(void){Clr_NRF24L01_CE;NRF24L01_Write_Buf(NRF24L01_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WI DTH);//写RX节点地址NRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答NRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_CH,40); //设置RF通信频率NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启NRF24L01_Write_Reg(NRF24L01_WRITE_REG+CONFIG, 0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式Set_NRF24L01_CE; //CE为高,进入接收模式}//该函数初始化NRF24L01到TX模式//设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR//PWR_UP,CRC使能//当CE变高后,即进入RX模式,并可以接收数据了//CE为高大于10us,则启动发送.void TX_Mode(void){Clr_NRF24L01_CE;NRF24L01_Write_Buf(NRF24L01_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH) ;//写TX节点地址NRF24L01_Write_Buf(NRF24L01_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WI DTH); //设置TX节点地址,主要为了使能ACKNRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答NRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址NRF24L01_Write_Reg(NRF24L01_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_CH,40); //设置RF通道为40 NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db 增益,2Mbps,低噪声增益开启NRF24L01_Write_Reg(NRF24L01_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断Set_NRF24L01_CE;//CE为高,10us后启动发送}。
奋斗STM32开发板光盘资料指南 奋斗STM32开发板光盘资料指南奋斗STM32开发板光盘包含了奋斗嵌入式开发工作室在STM32的开发成果、文档以及外围设备的资料。
目录说明如下:JLINK V8目录:包含了适用于STM32以及其他类型ARM的JTAG仿真器JLINK V8的驱动程序以及固件修复指南和固件文件。
奋斗开发板教程目录:包含了奋斗开发板的例程手册、视频教程和入门手册等。
来自网络的STM32教程目录:包含了来自网络的对于MDK开发环境以及STM32外设的视频教学文件。
奋斗STM32开发板例程目录:7寸屏显示例程:包含了基于群创7寸屏方案的奋斗STM32显示例程奋斗STM32开发板MINI+2.4寸屏例程:包含了奋斗STM32开发板MINI的所有基础例程及针对2.4寸屏模块的显示例程(包括基于ucos ucgui的例程) 奋斗STM32开发板V3+2.4寸屏例程:包含了奋斗STM32开发板V3的所有基础例程及针对2.4寸屏模块的显示例程(包括基于ucos ucgui的例程) 奋斗STM32开发板MINI+3寸屏例程:包含了奋斗STM32开发板MINI的所有基础例程及针对3寸屏模块的显示例程(包括基于ucos ucgui的例程) 奋斗STM32开发板V3+3寸屏例程:包含了奋斗STM32开发板V3的所有基础例程及针对3寸屏模块的显示例程(包括基于ucos ucgui的例程)奋斗STM32开发板MINI+4.3寸屏例程:包含了奋斗STM32开发板MINI的所有基础例程及针对4.3寸屏模块的显示例程(包括基于ucos ucgui的例程) 奋斗STM32开发板V3+4.3寸屏例程:包含了奋斗STM32开发板V3的所有基础例程及针对4.3寸屏模块的显示例程(包括基于ucos ucgui的例程) 奋斗TINY开发板例程:包含了奋斗STM32开发板TINY的所有例程奋斗STM32开发板文档目录:包含了所有有关奋斗STM32开发板板及奋斗板模块及外设的文档。
单片机基于2.4G无线收发模块NRF24L01的无线通信(基本测试通过)续二、软件部分1>接收方程序:主函数:#include <reg52.h>#include <stdio.h>#include'NRF24L01.h'#include <intrins.h>void main(){ unsigned char i=0;unsigned char data_RX[32]={1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2, 2,2,3,3,3,3,3,3,3,3,3,3,3,3};//接收到的32字节存放数组设置初值SCON = 0x50; //REN=1允许串行接受状态,串口工作模式1,8位收发,波特率可变TMOD|= 0x20; //定时器工作方式 2 ,自动重载初值PCON&= 0x7f; //波特率不加倍TH1 = 0xFA; //波特率等于4800、数据位8、停止位1。
效验位无,晶振为11.0592MHZTL1 = 0xFA;TR1 = 1; //开启定时器1 ES = 1; //开串口中断EA = 1; // 开总中断NRF24L01_RX();//设置为接收模式while(!((READ_BYTE(READ_REG+STATUS))&0x40)); //判断是否接收好32字节数据READ_BYTES(RD_RX_PLOAD,data_RX,32); //将32字节数据存放在数组中CE=0;CSN=1;_nop_();CSN=0;SPI_WRITE(FLUSH_RX); //清空接收FIFO,否则接收数据不可预知SCK=0;CSN=1;jieshouv=0; //接收成功标志位WRITE_BYTE(WRITE_REG+STATUS,0xFF); //屏蔽中断位for(i=0;i<32;i++){ if(data_RX[i]>=10){SBUF=data_RX[i]/10+48; //将十位转化为ASCII码发送while(!TI);TI=0;SBUF = data_RX[i]%10+48; //将个位转化为ASCII码发送while(!TI); // 等特数据传送(TI发送中断标志)TI = 0; // 清除数据传送标志}else{SBUF = data_RX[i]%10+48; //将无符号数转为ASCII码发送while(!TI); // 等特数据传送(TI发送中断标志)TI = 0; // 清除数据传送标志}}while(1);}*************************************************************** *************************************************详情请咨询: http://shop108408772.taoba /*************************************************************** ***********************************************子函数:#include <reg52.h>#include 'NRF24L01.h'#include <intrins.h>unsigned char ADD_TX[]={0,1,2,3,4}; //通道地址unsigned char data_TX[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; //发送方32字节数据void SPI_WRITE(unsigned char canshu) //写入一个字节{unsigned char i;for(i=0;i<8;i++){SCK=0;MOSI=(canshu&0x80)>>7; //先发高位SCK=1;canshu=canshu<<1;}}unsigned char SPI_READ() //读一个字节{unsigned char canshu=0,i;for(i=0;i<8;i++){canshu=canshu<<1; //先接收的为高位SCK=0;_nop_();SCK=1;canshu=canshu|MISO;}return canshu;}void WRITE_BYTE(unsigned char address,unsigned char value)//写入完整指令,单字节{CSN=1;_nop_();CSN=0;SPI_WRITE(address); //写入寄存器绝对地址_nop_();SPI_WRITE(value); //写入参数SCK=0; //恢复初值CSN=1; //恢复初值}unsigned char READ_BYTE(unsigned char address) //读入完整指令,单字节{unsigned char canshu;CSN=1;_nop_();CSN=0;SPI_WRITE(address); //写入寄存器绝对地址_nop_();canshu=SPI_READ(); //读出数据SCK=0;CSN=1;return canshu;}*************************************************************** *************************************************详情请咨询: http://shop108408772.taoba /*************************************************************** ***********************************************void WRITE_BYTES(unsigned char address,unsigned char *value,unsigned char width)//写入指定字节数据,多字节{unsigned char i;CSN=1;_nop_();CSN=0;SPI_WRITE(address); //写入寄存器绝对地址_nop_();for(i=0;i<width;i++){SPI_WRITE(*value); //将数据依次写入value=value+1;}SCK=0;CSN=1;}void READ_BYTES(unsigned char address,unsigned char *value,unsigned char width)//读入指定字节数据,多字节{unsigned char i;CSN=1;_nop_();CSN=0;SPI_WRITE(address); //写入寄存器绝对地址_nop_();for(i=0;i<width;i++){*value=SPI_READ(); //将数据依次读入value=value+1;}SCK=0;CSN=1;}/************************************************void NRF24L01_TX()//NRF24L01设为发送模式{ //默认NRF24L01为掉电模式unsigned char i;CE=0;WRITE_BYTE(WRITE_REG+SETUP_AW,0x03);//设置地址宽度为5字节WRITE_BYTE(WRITE_REG+RX_PW_P0,0x20);//设置接收通道0数据宽度为32字节WRITE_BYTES(WR_TX_PLOAD,data_TX,32);//写入发送数据WRITE_BYTES(WRITE_REG+TX_ADDR,ADD_TX,5);//设置发送地址WRITE_BYTES(WRITE_REG+RX_ADDR_P0,ADD_TX,5);//设置通道0地址WRITE_BYTE(WRITE_REG+EN_RXADDR,0x01);//使能接收通道0WRITE_BYTE(WRITE_REG+EN_AA,0x01);//使能通道0自动应答WRITE_BYTE(WRITE_REG+SETUP_RETR,0x1a);// 自动重发次数10次WRITE_BYTE(WRITE_REG+RF_CH,0x40); //设置载波频率WRITE_BYTE(WRITE_REG+RF_SETUP,0x0f); //射频参数,如数据传输率,发射功率WRITE_BYTE(WRITE_REG+CONFIG,0x0A);//设置发射,上电,CRC校验8位CE=1;for(i=0;i<10;i++);//延时30us}********************************************************/void NRF24L01_RX()//NRF24L01设为接收模式{unsigned char i; //默认NRF24L01为掉电模式CE=0;WRITE_BYTE(WRITE_REG+SETUP_AW,0x03);//设置地址宽度为5字节WRITE_BYTE(WRITE_REG+RX_PW_P0,0x20);//设置接收通道0数据宽度为32字节WRITE_BYTES(WRITE_REG+RX_ADDR_P0,ADD_TX,5);//设置通道0地址WRITE_BYTE(WRITE_REG+EN_RXADDR,0x01);//使能接收通道0WRITE_BYTE(WRITE_REG+EN_AA,0x01);//使能通道0自动应答WRITE_BYTE(WRITE_REG+RF_CH,0x40); //设置载波频率WRITE_BYTE(WRITE_REG+RF_SETUP,0x0f); //射频参数,如数据传输率,发射功率WRITE_BYTE(WRITE_REG+CONFIG,0x0B);//设置接收,上电,CRC校验8位CE=1;for(i=0;i<20;i++);//延时60us}*************************************************************** *************************************************详情请咨询: http://shop108408772.taoba /*************************************************************** ***********************************************1>发送方程序:主程序://#include <reg52.h>#include 'stc12.h'#include'NRF24L01.h'#include <intrins.h>void main(){CLK_DIV=0x03;NRF24L01_TX(); //发送模式开启while(!((READ_BYTE(READ_REG+STATUS))&0x30));//等待发送完成CE=0;CSN=1;_nop_();CSN=0;SPI_WRITE(FLUSH_RX); //清空接收FIFO,否则数据不可预料SCK=0;CSN=1;if((READ_BYTE(READ_REG+STATUS))&0x20)fasong=0; // 发送成功标志位WRITE_BYTE(WRITE_REG+STATUS,0xFF); //屏蔽中断标志位while(1);}子程序:和接收子程序大部分一致,改动部分:void NRF24L01_TX()//NRF24L01设为发送模式{ //默认NRF24L01为掉电模式unsigned char i;CE=0;WRITE_BYTE(WRITE_REG+SETUP_AW,0x03);//设置地址宽度为5字节WRITE_BYTE(WRITE_REG+RX_PW_P0,0x20);//设置接收通道0数据宽度为32字节WRITE_BYTES(WR_TX_PLOAD,data_TX,32);//写入发送数据WRITE_BYTES(WRITE_REG+TX_ADDR,ADD_TX,5);//设置发送地址WRITE_BYTES(WRITE_REG+RX_ADDR_P0,ADD_TX,5);//设置通道0地址WRITE_BYTE(WRITE_REG+EN_RXADDR,0x01);//使能接收通道0WRITE_BYTE(WRITE_REG+EN_AA,0x01);//使能通道0自动应答WRITE_BYTE(WRITE_REG+SETUP_RETR,0x1a);// 自动重发次数10次WRITE_BYTE(WRITE_REG+RF_CH,0x40); //设置载波频率WRITE_BYTE(WRITE_REG+RF_SETUP,0x0f); //射频参数,如数据传输率,发射功率WRITE_BYTE(WRITE_REG+CONFIG,0x0A);//设置发射,上电,CRC校验8位CE=1;for(i=0;i<30;i++);//延时90us}将接收子程序中接收模式程序屏蔽即可。
奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验NRF24L01+转 USB 虚拟串口实验实验平台:奋斗版STM32开发板V3 实验内容:板子通过USB加电后,先向串口1输出一串测试数据,然后USB被PC识 别出来,虚拟出一个串口号给这个USB设备,此时可以通过在PC端的串口助手类 软件选择该串口号。
进入串口软件界面,可以通过软件无线收发一帧长度最长 为32字节的数据。
该例程可以和V3及MINI板的NRF24L01 UCGUI例程配合使用, 也可以与同样例程的MINI、V3、TINY板配合使用。
预先需要掌握的知识 2.4G通信模块NRF24L01 1. 产品特性2.4GHz 全球开放ISM 频段,最大0dBm 发射功率,免许可证使用 支持六路通道的数据接收 低工作电压:1.9 1.9~3.6V 低电压工作 高速率:2Mbps,由于空中传输时间很短,极大的降低了无线传输中的碰撞现象(软件设置1Mbps或者2Mbps的空中传输速率) 多频点:125 频点,满足多点通信和跳频通信需要 超小型:内置2.4GHz天线,体积小巧,15x29mm(包括天线) 低功耗:当工作在应答模式通信时,快速的空中传输及启动时间,极大的降低了电流消耗。
低应用成本:NRF24L01 集成了所有与RF协议相关的高速信号处理部分,比如:自动重发丢失数据包和自动产生应答信号等, NRF24L01的SPI接口可以利用单片机的硬件SPI口连接或用单片机I/O口进行模拟,内部有FIFO可以与各种高低速微处理器接口, 便于使用低成本单片机。
便于开发:由于链路层完全集成在模块上,非常便于开发。
自动重发功能,自动检测和重发丢失的数据包,重发时间及重发次数可软件控制 自动存储未收到应答信号的数据包 自动应答功能,在收到有效数据后,模块自动发送应答信号,无须另行编程 载波检测—固定频率检测 内置硬件CRC 检错和点对多点通信地址控制 数据包传输错误计数器及载波检测功能可用于跳频设置 可同时设置六路接收通道地址,可有选择性的打开接收通道 标准插针Dip2.54MM 间距接口,便于嵌入式应用2.基本电气特性淘宝店铺:1奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验3. 引脚定义:4.工作方式NRF2401有工作模式有四种: 收发模式 配置模式 空闲模式 关机模式 工作模式由CE 和寄存器内部PWR_UP、PRIM_RX 共同控制,见下表:淘宝店铺:2奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验4.1 收发模式收发模式有Enhanced ShockBurstTM收发模式、ShockBurstTM收发模式和直接收发模式三种,收发模式由器件配置字决定,具体 配置将在器件配置部分详细介绍。
4.1.1 Enhanced ShockBurstTM收发模式Enhanced ShockBurstTM收发模式下,使用片内的先入先出堆栈区,数据低速从微控制 器送入,但高速(1Mbps)发射,这样可以尽量节能,因此,使用低速的微控制器也能得到很高的射频数据发射速率。
与射频协议 相关的所有高速信号处理都在片内进行, 这种做法有三大好处: 尽量节能; 低的系统费用(低速微处理器也能进行高速射频发射); 数据在空中停留时间短,抗干扰性高。
Enhanced ShockBurstTM技术同时也减小了整个系统的平均工作电流。
在Enhanced ShockBurstTM收发模式下, NRF24L01自动处理字头和CRC校验码。
在接收数据时,自动把字头和CRC校验码移去。
在发送数据时, 自动加上字头和CRC校验码,在发送模式下,置CE为高,至少10us,将时发送过程完成后。
4.1.1.1 Enhanced ShockBurstTM发射流程 A. 把接收机的地址和要发送的数据按时序送入NRF24L01; B. 配置CONFIG寄存器,使之进入发送模式。
C. 微控制器把CE置高(至少10us),激发NRF24L01进行Enhanced ShockBurstTM发射; D. N24L01的Enhanced ShockBurstTM发射(1) 给射频前端供电; (2)射频数据打包(加字头、CRC校验码); (3) 高速发射数据 包; (4)发射完成,NRF24L01进入空闲状态。
4.1.1.2 Enhanced ShockBurstTM接收流程 A. 配置本机地址和要接收的数据包大小; B. 配置CONFIG寄存器,使之进入接收模式,把CE置高。
C. 130us后,NRF24L01进入监视状态,等待数据包的到来; D.当接收到正确的数据包(正确的地址和CRC校验码),NRF2401自动把字头、地址和CRC校验位移去; E. NRF24L01通过把STATUS寄存器的RX_DR置位(STATUS一般引起微控制器中断)通知微控制器; F. 微控制器把数据从NewMsg_RF2401 读出; G. 所有数据读取完毕后,可以清除STATUS寄存器。
NRF2401可以进入四种主要的模式之一。
4.1.2 ShockBurstTM收发模式 ShockBurstTM收发模式可以与Nrf2401a,02,E1及E2兼容。
4.2 空闲模式NRF24L01的空闲模式是为了减小平均工作电流而设计,其最大的优点是,实现节能的同时,缩短芯片的起动时间。
在空闲模式 下,部分片内晶振仍在工作,此时的工作电流跟外部晶振的频率有关。
4.3 关机模式在关机模式下,为了得到最小的工作电流,一般此时的工作电流为900nA左右。
关机模式下,配置字的内容也会被保持在NRF2401 片内,这是该模式与断电状态最大的区别。
5、NRF24L01 的SPI 配置 SPI 指令设置用于SPI 接口的常用命令见下表。
当CSN 为低时,SPI 接口开始等待一条指令,任何一条新指令均由CSN 的由高 到低的转换开始多机通信框图淘宝店铺:3奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验串行接口指令设置淘宝店铺:4奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验淘宝店铺:5奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验淘宝店铺:6奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验淘宝店铺:7奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验淘宝店铺:8奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验淘宝店铺:9奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验淘宝店铺:10奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验应用实例设计要求板子通过USB加电后,先向串口1输出一串测试数据,然后USB被PC设别出来, 虚拟出一个串口号给这个USB设备,此时可以通过在PC端的串口助手类软件选择 该串口号。
进入串口软件界面,可以通过软件无线收发一帧长度最长为32字节 的数据。
5.2 硬件电路设计需要将NRF24L01+插入V3Y板上的XS12接口,XS12的接口定义了SPI2的标示, 板子通过USB线插入到PC的USB接口上,第一次 实验的话,需要运行光盘内资料目录下的VCPDriver_V1.1_Setup.exe来安装USB虚拟串口驱动。
V3与NRF24L01+的连接关系 V3-XS12 NRF24L01+ PIN4-PB0: SPI2 CS------PIN4 PIN5-PB13:SPI2 SCK-----PIN5 PIN7-PB14: SPI2 MISO----PIN7 PIN6-PB15: SPI2 MOSI----PIN6 PIN3-PB1 : NRF24L01 CE--PIN3 PIN8-PA0 : NRF24L01 IRQ-PIN8 PIN1-GND : 地 PIN1 PIN2-3V : 3.3V PIN25.3 软件程序设计根据任务要求,程序内容主要包括: 1. 2. 3. 4. 5. 初始化串口 初始化USB 初始化SPI2及NRF24L01接口 中断源配置 各通信函数的编写。
本例程完成了以下功能: (1) 2.4GNRF24L01+与USB虚拟串口互转 (2) 2.4GNRF24L01+转RS-232串口1 (3) USB虚拟串口与RS-232串口1互转 整个工程包含5类源文件:淘宝店铺:11奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验startup--startup_stm32f10x_hd.s由于奋斗板采用的是STM32F103高容量存储器芯片,因此采用STM32标准库自带的中容量存储器芯片启动代码,这个文件已经配置好了初始状态,以及中断向量表。
可以直接在工程里使用,如果你在以后的应用 中采用了中存储器或者小存储器STM32芯片,可以将启动代码换为startup_stm32f10x_md.s startup_stm32f10x_ld.s。
fwlib--stm32f10x_gpio.c ST公司的标准库,包含了关于对通用IO口设置的函数。
stm32f10x_rcc.c 关于对系统时钟设置的函数。
stm32f10x_spi.c ST公司的标准库,包含了关于和SPI相关的函数。
stm32f10x_exti.c ST公司的标准库,包含了和EXTI外部中断相关的函数。
ST公司的标准库,包含了 或者stm32f10x_usart.c ST公司的标准库,包含了关于对USART设置的函数。
Misc.c ST公司的标准库,包含了关于中断设置的函数。
usb-fs-device-组项下的C文件都是和全速USB有关系的库函数。
CMSYS—是关于CORETEX-M3平台的系统函数及定义 USER—main.c NRF24L01.c hw_config.c 例程的主函数。
包含和NRF24L01相关的函数 包含和硬件平台有关系的函数 中断服务程序stm32f10x_it.c5.4程序流程在main()函数里,顺序执行系统时钟配置及各外设的初始化操作。
淘宝店铺:12奋斗版 STM32 开发板例程手册———NRF24L01+转 USB 虚拟串口实验void USART_Init1(USART_TypeDef* USART1)定义了串口1的初始化,将端口PA9、PA10复用为串口1的发和 收,数据格式配置以下函数所设置的式样。