奋斗STM32V3版 2.4G无线通信例程
2.4GHz 无线传输接收器系统用户手册说明书
Poor reception
Causes and remedies
Camera
Receiver
- No camera (or other video - AC adapter not plugged in
device) connected to
- Power switch not turned on
- Adjust antenna direction
- Adjust antenna direction
FOR MORE INFORMATION
Because our products are subject to continuous improvement, SVC Reserves the right to modify product design and specifications without Notice and without incurring any obligation. E & OE.
CAUTION
!
RISK OF ELECTRIC SHOCK. DO NOT OPEN.
CAUTION:TO REDUCE THE RISK OF ELECTRIC SHOCK, DO NOT REMOVE COVER (OR BACK). NO USER-SERVICEABLE PARTS INSIDE. REFER SERVICING TO QUALIFIED SERVICE PERSONNEL.
SPI方式STM32F103与2.4G模块NRF24L01收发通讯
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的无线通信系统设计课程设计
课程设计说明书题目:基于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无线通信使用教程
2
1.3.1 NRF24L01 驱动程序
打开 nrf24l01.c 文件,代码如下: #include "nrf24l01.h" #include "spi.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; //使能 PB,F,D 端口时钟 //PF8-CE PF9-CSN PD3-IRQ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPI OF|RCC_APB2Periph_GPIOD, ENABLE);
1.2 硬件设计
本实验功能简介:开机时系统先检测 NRF24L01 模块是否存在,在检测到 NRF24L01 模块之后,根据 K_UP 和 K_DOWN 按键来决定模块的工作模式,在设 定好工作模式之后,就会开发发送/接收数据,同样用 D1 指示灯来指示程序正 在运行。 开发板上并没有集成 NRF24L01 无线模块,而是预留了一个模块接口, 所以我 们需要知道模块接口与开发板对应的管脚原理图,如图 1.2.1 所示:
5
} //在指定位置写指定长度的数据 //reg:寄存器(位置) //*pBuf:数据指针 //len:数据长度 //返回值,此次读到的状态寄存器值 u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len) { u8 status,u8_ctr; NRF24L01_CSN = 0; //使能 SPI 传输 status = SPI2_ReadWriteByte(reg);//发送寄存器值(位置),并读取状 态值 for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPI2_ReadWriteByte(*pBuf++); //写入数据 NRF24L01_CSN = 1; //关闭 SPI 传输 return status; //返回读到的状态值 } //启动 NRF24L01 发送一次数据 //txbuf:待发送数据首地址 //返回值:发送完成状况 u8 NRF24L01_TxPacket(u8 *txbuf) { u8 sta; SPI2_SetSpeed(SPI_BaudRatePrescaler_4);//spi 速度为 9Mhz(24L01 的最大 SPI 时钟为 10Mhz) NRF24L01_CE=0; NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);// 写 数 据 到 TX BUF 32 个字节 NRF24L01_CE=1;//启动发送 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; }
15.27、 2.4G无线模块收发实验
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的无线通信子程序
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后启动发送}。
整理精简的2.4G无线通讯应用程序
reg_val = SPI_RW(0); // ..then read registervalue
CSN = 1; // CSN high, terminate SPI communication
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
for(i=0;i<count;i++)
for(j=0;j<450;j++);
}
//功能:NRF24L01的SPI读写时序
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++) // output 8-bit
{
if((byte & 0x80)==0){MOSI=0;}else{MOSI=1;}// MOSI = (byte & 0x80);output 'uchar', MSB to MOSI
{
uchar status,i;
CSN = 0; // Set CSN low, init SPI tranaction
void UART2_SendData8(unsigned char Data)
{
while((UART2_SR&0x80)==0);
奋斗STM32开发板光盘资料指南
奋斗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的无线通信(基本测试通过)续
单片机基于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}将接收子程序中接收模式程序屏蔽即可。
基于单片机的2.4G近距离无线通信系统设计
口方式 和简 单的操 作指 令 ,可构 成 全中 文人机 交 互 图形界 面 ,在单
片机应 用 中得到 j r’泛使 用 。
3 系 统硬 件设 计 原 理 图
主 机 以 单 片 机 f1 为控 制 核 心 , AMS1 I1 7 5V转 化 为 3.3V, 给 nRF24L0l+模块 和 SHT20模 块 供 电 , I】r渊电 『j}iR2用 来 调 箝液 晶 l2864的对 比度 机 卡¨从 机 的硬 件 原 图几 ‘投 ,仅 足 主机 ,f 需要 连接 SHT20传 感器 。 系统工 作 时 , 1 同的 从机通 过 地址 进 行 f 分 。 F 足用Altium Designer 09Lm ̄的原理 :
境 温 湿 度 的 功 能 【关键 词 】温 湿度检 测 ;无线收 发 ;液 晶显 示
1 系 统 设 计 方 案
动应 答等 功能 ,lI_『通 过软件 设置 2Mbps,1Mbps,250Kbps二 种 数据 波 特率 ,足 目前近 离 线 通信 的理 想选 择 该芯片 仃2O个 引脚 ,体 枞 小 , 容 易焊 接 ,, ”成本 和模 块 l 彩, 所 以小 系统 直接使 用
系统 的设 汁方案 如图 l所 示 , 系统 自’2个 监洲 点 , 分 别为 从机 l 和 从机 2, I:作 时 ,从 机 放置 于被 洲环 境 l{ (如 蔬菜 大棚 ) ,
NRF24L01模块 ,如 卜 所示 :
机将 传感 器 采集 到 的数据 通 过无 线模 块发 送 出去 ; l丰机 安装 作 人 员处 ,通 过 尢线模 块接 收 从机 1卡【J从机 2芨来 的数据 ,经过 单片机 处 理 后 液 品 JJfl2864 I ,J÷
I c总线 协议 与单 片机通 信 ,工 作 电压2.1—3.6V。
基于2.4GHz射频的无线串口通信设计
基于2.4GHz射频的无线串口通信设计本文介绍了一套基于2.4GHz,结合nRF24L01无线通信模块的无线数据传输系统。
nRF24L01无线通信系统是基于nRF24L01无线收发芯片,以STM32F103单片机为核心的半双工无线通信系统,文中详细阐述了该无线通信系统的硬件和软件设计。
该系统主要由一个nRF24L01无线通信模块组成,在硬件基础上,结合nRF24L01的特点,实现了两个nRF24L01无线通信模块之间的通信。
目录摘要.......................................................................................................... 错误!未定义书签。
Abstract ...................................................................................................... 错误!未定义书签。
1 引言 (2)2 nRF2401无线通信系统设计方案与论证 (3)2.1 CPU的选择 (3)2.2 无线通信模块的选择 (3)2.3 显示模块的选择 (3)2.4 系统整体的最终方案 (3)2.5 系统工作流程图 (4)2.6 关键技术 (5)3 nRF2401无线通信系统的硬件设计 (5)3.1 nRF24L01 引脚介绍 (5)3.2.nRF24L01与STM32的接口设计 (6)4 nRF2401无线通信系统的软件设计 (7)4.1 nRF24L01无线通信分系统的软件结构 (7)4.1.1 nRF24L01无线通信模块软件 (8)4.1.2.nRF24L01无线通信模块数据发送与接收 (8)4.2初始化程序的设计 (9)4.2.1 RCC时钟初始化配置 (10)4.2.2nRF24L01初始化配置 (11)4.3 nRF24L01无线通信软件设计 (11)4.3.1 nRF24L01射频芯片特性 (11)4.3.2 SPI的读写程序 (15)4.3.3 nRF24L01发送程序设计 (16)4.3.4 nRF24L01接收程序设计 (17)5 nRF24L01无线通信系统的调试与实现 (19)5.1 nRF24L01无线通信系统调试 (19)5.1.1 硬件调试 (19)5.1.2软件调试 (19)5.2 nRF2401无线通信系统总体调试 (19)6 总结 (20)6.1 nRF2401无线通信系统的功能实现 (20)6.2 nRF2401无线通信系统功能展示 (20)6.2.1 发送数据 (20)6.2.2 接受数据 (21)6.2.3 最远有效通信距离 (22)6.3结论 (22)1 引言伴随信息技术的快速发展,人们对通信技术的需求越来越多,摆脱有线网络从而实现无线通信一直是大家关心的问题,当今世界无线通信越来越热,应用非常广泛,使人与人之间的通信更加方便快捷,具有巨大发展前景。
stm32串口通信标准库例程
文章标题:深度探究STM32串口通信标准库例程随着现代科技的发展和物联网的兴起,嵌入式系统的应用越来越广泛,而STM32作为一款性能强劲、功能丰富的微控制器,被广泛应用于各种嵌入式系统中。
在嵌入式系统的开发中,串口通信是一项非常基础且重要的功能。
本文将就如何使用STM32串口通信标准库例程进行深度探究,帮助您更好地理解和应用串口通信功能。
一、了解STM32串口通信标准库例程在嵌入式系统开发中,串口通信是一种常用的通信方式,它通过串行连接来进行数据的传输。
对于STM32微控制器,官方提供了丰富的标准库例程,其中包括了串口通信的相关函数和使用方法。
通过使用这些标准库例程,可以方便快捷地实现串口通信功能,为嵌入式系统的开发提供了极大的便利性。
二、STM32串口通信标准库例程的基本操作1. 初始化串口在使用串口通信之前,首先需要进行串口的初始化操作。
通过调用标准库例程中的相应函数,可以设置串口的波特率、数据位、停止位等参数,从而使串口处于可用状态,准备好接收和发送数据。
2. 发送数据一旦串口初始化完成,就可以通过调用相应的发送函数来向外部设备发送数据。
无论是单片机之间的通信,还是与外部传感器或模块的通信,都可以通过串口发送数据来实现信息的传递。
3. 接收数据接收数据是串口通信中同样重要的一部分。
通过调用标准库例程中的接收函数,可以实现对外部设备发送的数据进行接收和处理,从而实现双向通信的功能。
三、深入理解串口通信的应用场景串口通信在各种嵌入式系统中都有着广泛的应用,比如智能家居系统、工业控制系统、智能农业领域等。
以智能家居系统为例,通过串口通信,可以实现各种传感器与主控设备的连接,从而实现对环境数据的采集和控制。
在工业控制系统中,串口通信可以实现设备之间的信息交互和控制指令的传输,从而提高生产效率和自动化程度。
在智能农业领域,串口通信也被广泛应用于农业环境监测和智能农机的控制。
四、个人观点和理解作为一项重要的通信方式,串口通信在嵌入式系统开发中具有不可替代的地位。
2.4G超远距离无线传输方案随笔
超低成本的2.4G 超远距离超远距离无线遥控无线遥控无线遥控、、无线传输传输方案方案方案随笔随笔在2.4G 的领域里面。
大家比较熟悉的就是蓝牙和wifi 。
物联网用的比较多的就是zigbee 。
而在专业的领域用的比较多的就是nrf2401,cc2500等低成本芯片。
就距离而言,相同的功率下100mw ,17Dbm 的增益下。
蓝牙只有10米,wifi 大概20米。
Zigbee 也不超过50米。
nrf2401,CC2500不会超过100米。
其实目前2.4G 的传输距离为什么近,其最本质的原因是1:该公共频道带宽不足,手机,蓝牙,wifi 都占用这个频道。
2:功率必须符合100mw ,增益在17dbm 以下,不然过不了FCC 、国家标准。
也因此意味着你无法通过加大功率的办法来增加距离。
有人会反问我:网络上有看过人家wifi 能传300km 的呢。
是的,我也相信这是真的。
只是这根本没有可比性,也没有实用价值。
这好比你硬要在自行车上实现飞机那样的速度,你说可以吗?我的答案是完全可以。
我需要增加最先进的动力设备,加最轻的机壳材料,加最好的传感器,把飞机上得所有东西放在自行车上。
相信最后做出来的自行车飞机,那完全就不叫自行车了,也许最后我们连自行车的轮子都看不到了。
更可悲的是这个产品的造价也许够人家飞机厂做几台这样的飞机出来了。
如果你得产品要获得出口到美国,中欧一些国家的话。
使用2.4G 的公共频道是不需要申请的。
但是辐射功率必须在100mv 以下。
甚至有些国家还要求RF 发送的时间间隙要在3ms 以上。
否则你的产品没办法在这些国家销售。
中国的话没有强制的要求,但2016年之后中国也会出台相关的强制标准。
那是不是除了上面两个条件,就没有其他办法来增加传输的距离了呢?答案当然是可以。
本文就针对该问题提出了一整套的解决方案。
至于你能不能领悟到其中的奥秘,那就看你的造化了。
废话少说,我们转入正题。
方案好不好,首先我们得要选一个好的硬件平台,就好像做饭一样,巧妇难为无米之炊,我们要做一个上好的牛扒,选对牛肉是关键。
基于STM32和2.4G无线通信技术的环境监测与控制系统设计
基于STM32和2.4G无线通信技术的环境监测与控制系统设计熊中刚【期刊名称】《《桂林航天工业学院学报》》【年(卷),期】2019(024)003【总页数】5页(P336-340)【关键词】STM32; 2.4G通信; 环境监测; 控制系统【作者】熊中刚【作者单位】桂林航天工业学院机械工程学院广西桂林 541004【正文语种】中文【中图分类】TN92; TP274.5随着时代步伐和我国社会经济的快速发展,人们的生活水平越来越好,生活要求也越来越高,特别是当今社会智能化、高科技化和人性化等智能系统的不断发展,正好能够满足人们生活需求,不断改变人们的生活质量和生活习惯,并带来了全新的体验和感受。
然而专门针对厨房的智能安全系统存在主人个性化不足、智能水平较低、操作过于复杂以及通信可靠性差等缺点。
为了解决目前市场上该套系统存在的问题,本文提出了一种基于STM32和2.4G无线通信技术的厨房环境监测与控制系统设计。
1 系统整体设计本文设计的系统主要包括下位机传感器节点、环境监测节点和智能终端三部分构成。
下位机传感器节点将检测到的温度、湿度、煤气浓度和烟雾浓度等信息经由具有低功耗和高传输速率的2.4G无线通信模块传送给环境监测节点,进而由环境监测节点处的中央控制单元处理后,将处理后的各检测数据经由GSM网络通过无线传输到智能监控终端。
系统框图如图1所示。
图1 系统框图2 系统硬件设计2.1 主控模块STM32的电路设计本系统采用ST公司生产的STM32F10增强型系列STM32F103ZET6 作为中央控制单元的主控芯片。
该芯片的主要特点是能够支持SRAM、NAND、NOR和CF卡等存储器,而且能提供并行接口给LCD显示部分,具备8080/6800的兼容模式,基本定时器4个,高级定时器2个,驱动定时器2个,看门狗定时器2个,系统定时器1个;12位模数转换器3个,USART接口5个,CAN接口1个,I2C接口2个,SPI接口3个,SDIO接口1个,USB2.0全速接口1个,同时支持Cortex-M3内嵌跟踪模块、串行单线调试以及JTAG接口。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
奋斗版 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的发和 收,数据格式配置以下函数所设置的式样。