网上有很多关于水星第七宫,水星由近到远的知识,也有很多人为大家解答关于水星第7?m的问题,今天刺梨占星网(nayona.cn)为大家整理了关于这方面的知识,让我们一起来看下吧!
本文目录一览:
1、水星第7?m
水星第7?m
1)实验平台:正点原子水星 STM32F4/F7 开发板
2)摘自《STM32F7 开发指南(HAL 库版)》关注官方微信号公众号,获取更多资料:正点原子
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-13912-1-1.html
第三十九章 无线通信实验
ALIENTKE 水星 STM32F767 开发板带有一个无线模块(WIRELESS)接口,采用 8 脚插
针方式与开发板连接,可以用来连接 NRF24L01/WIFI 等无线模块。本章我们将以 NRF24L01
模块为例向大家介绍如何在 ALIENTEK 水星 STM32 开发板上实现无线通信。在本章中,我们
将使用两块水星 STM32F767 开发板,一块用于发送收据,另外一块用于接收,从而实现无线
数据传输。本章分为如下几个部分:
39.1 SPI&NRF24L01 无线模块简介
39.2 硬件设计
39.3 软件设计
39.4 下载验证
39.1 SPI&NRF24L01 无线模块简介
本章,我们将通过 STM32F767 的 SPI 接口来驱动 NRF24L01 无线模块,接下来我们将分
别介绍 STM32F7 的 SPI 接口和 NRF24L01 无线模块。
39.1.1 SPI 接口简介
SPI 是英语 Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口。是 Motorola
首先在其 MC68HCXX 系列处理器上定义的。SPI 接口主要应用在 EEPROM,FLASH,实时时
钟,AD 转换器,还有数字信号处理器和数字信号解码器之间。
SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约
了芯片的管脚,同时为 PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,现
在越来越多的芯片集成了这种通信协议,STM32F767 也有 SPI 接口。
SPI 接口一般使用 4 条线通信:
MISO 主设备数据输入,从设备数据输出。
MOSI 主设备数据输出,从设备数据输入。
SCLK 时钟信号,由主设备产生。
CS 从设备片选信号,由主设bèi控制。
SPI 主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可
编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等。
SPI 总线四种工作方式 SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串
行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果
CPOL=0,串行同步时钟的空闲状态为低电平;如果 CPOL=1,串行同步时钟的空闲状态为高电
平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果 CPHA=0,
在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果 CPHA=1,在串行同步时钟
的第二个跳变沿(上升或下降)数据被采样。SPI 主模块和与之通信的外设备时钟相位和极性
应该一致。
不同时钟相位下的总线数据传输时序如图 39.1.1.1 所示:
图 39.1.1.1 不同时钟相位下的总线传输时序(CPHA=0/1)
对于 STM32F7 来说,SPI 的 MSB 和 LSB 是可以配置的,通过 SPI_CR1 的 LSBFIRST 位
进行控制,当该位为 1 时,表示 LSB 在前;当该位为 0 时,表示 MSB 在前;
STM32F7 的 SPI 功能很强大,SPI 时钟最高可以到 54Mhz,支持 DMA,可以配置为 SPI
协议或者 I2S 协议(支持全双工 I2S)。
本章,我们将使用 STM32F767 的 SPI 来驱动 NRF24L01 无线模块。这里对 SPI 我们只简
单介绍一下 SPI 的使用,STM32F767 的 SPI 详细介绍请参考《STM32F7 中文参考手册》第 965
页,32 节。
本章,我们使用 STM32F767 的 SPI2 来驱动 NRF24L01,HAL 库zhōng SPI 相关函数定义分布
在源文件 stm32f7xx_hal_spi.c 和对应的头文件 stm32f7xx_hal_spi.h 中。下面就来看看
STM32F767 的 SPI2 主模式配置步骤:
1)配置相关引脚的复用功能,使能 SPI2 时钟。
我们要用 SPI2,第一步就要使能 SPI2 的时钟,SPI2 的时钟通过 APB1ENR 的第 14 位来设
置。其次要设置 SPI2 的相关引脚为复用(AF5)输出,这样才会连接到 SPI2 上。这里我们使用的
是 PB13、14、15 这 3 个(SCK.、MISO、MOSI,CS 使用软件管理方式),所以设置这三个为
复用 IO,复用功能为 AF5。
HAL 库中,SPI2 时钟使能方法如下:
__HAL_RCC_SPI2_CLK_ENABLE(); //使能 SPI2 时钟
IO 口复用功能设置在前面我们已经多次讲解,这里就不累赘了。和串口等其他外设一样,
HAL 库同样提供了 SPI 的初始化回调函数用来编写与 MCU 相关的配置。
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi);
2)初shǐ化 SPI2,设置 SPI2 工作模式等。
这一步全部是通过 SPI2_CR1 来设置,我们设置 SPI2 为主机模式,设置数据格式为 8 位,
然后通过 CPOL 和 CPHA 位来设置 SCK 时钟极性及采样方式。并设置 SPI2 的时钟频率(最大
54Mhz),以及数据的格式(MSB 在前还是 LSB 在前)。在库函数中初始化 SPI 的函数为:
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi);
该函数只有一个入口参数 hspi,为 SPI_HandleTypeDef 结构体指针类型,该结构体定义如下:
typedef struct __SPI_HandleTypeDef
{ SPI_TypeDef*Instance;//外设寄存器基地址 SPI_InitTypeDef Init;//初始化结构体 uint8_t*pTxBuffPtr;//发送缓存 uint16_t TxXferSize;/发送数据大小 uint16_t TxXferCount;//还剩余多少个数据要发送 uint8_t *pRxBuffPtr;//接收缓存 uint16_t RxXferSize;//接收数据大小 uint16_t RxXferCount;//还剩余多少个数据要接收 DMA_HandleTypeDef*hdmatx;//DMA 发送句柄 DMA_HandleTypeDef*hdmarx;//DMA 接收句柄 void (*RxISR)(struct __SPI_HandleTypeDef * hspi); void (*TxISR)(struct __SPI_HandleTypeDef * hspi); HAL_LockTypeDefLock; __IO HAL_SPI_StateTypeDef State; __IO uint32_tErrorCode;}SPI_HandleTypeDef;
该结构体成员变量较多。成员变量 Instance 用来设置外设寄存器基地址,对于 SPI2,我们
设置为宏定义标识符 SPI2 即可。成员变量 pTxBuffPtr,TxXferSize 和 TxXferCount 用来设置 SPI
发送缓存,发送数据量和发送剩余数据量。成员变量 pRxBuffPtr,RxXferSize 和 RxXferCount
用来设置接收缓存,接收数据量和接收剩余数据量。CRCSize 用来设置 CRC 校验字节数。
hdmatx
和 hdmarx 是 DMA 处理句柄。RxISR 和 TxISR 是函数指针,用来指向 SPI 的接收和发送zhōng断处
理函数。这里我们着重讲解第二个成员变量Init,该成员变量用来初始化SPI时序和工作模式等,
Init 成员变量是 SPI_InitTypeDef 结构体类型,该结构体定义如下:
typedef struct{ uint32_t Mode;// 模式:主(SPI_MODE_MASTER),从(SPI_MODE_SLAVE) uint32_t Direction; //方式: 只接受模式,单线双向通信数据模式,全双工 uint32_t DataSize; //8 位还是 16 位帧格式选择项 uint32_t CLKPolarity; //时钟极性 uint32_t CLKPhase; //时钟相位 uint32_t NSS;//SS 信号由硬件(NSS 管脚)还是软件控制 uint32_t BaudRatePrescaler; //设置 SPI 波特率预分频值uint32_t FirstBit;//起始位是 MSB 还是 LSB uint32_t TIMode;//帧格式 SPI motorola 模式还是 TI 模式 uint32_t CRCCalculation; //硬件 CRC 是否使能 uint32_t CRCPolynomial; //CRC 多项式uint32_t CRCLength;uint32_t NSSPMode;}SPI_InitTypeDef;
结构体成员biàn量比较多,接下来我们简单讲解一下:
参数 Mode 用来设置 SPI 的主从模式,这里我们设置为主机模式 SPI_MODE_MASTER,当然有
需要你也可以选择为从机模式 SPI_MODE_SLAVE。
cān数 Direction 用来设置 SPI 的通信方式,可以选择为半双工,全双工,以及串行发和串行收方
式,这里我们选择全双工模式 SPI_DIRECTION_2LINES。
参数DataSize为8位还是16位帧格式选择项,这里我们shì8位传输,选择SPI_DATASIZE_8BIT。
参数 CLKPolarity 用来设置时钟极性,我们设置串行同步时钟的空闲状态为高电平所以我们选
择 SPI_POLARITY_HIGH。
参数 CLKPhase 用来设置时钟相位,也就是选择在串行同步时钟的第几个跳变沿(上升或下降)
数据被采样,可以为第一个或者第二个条边沿采集,这里我们选择第二个跳变沿,所以选择
SPI_PHASE_2EDGE
参数 NSS 设置 NSS 信号由硬件(NSS 管脚)还是软件控制,这里我们通过软件控制 NSS 关键,
而不是硬件自动控制,所以选择 SPI_NSS_SOFT。
参数 SPI_ BaudRatePrescaler 很关键,就是设置 SPI 波特率预分频值也就是决定 SPI 的时钟的参
数,从 2 分 频 到 256 分 频 8 个 可 选 值 , 初 始 化 的 时 候 我 们 选 择 256 分 频 值
SPI_BAUDRATEPRESCALER_256, 传输速度wèi 108M/256=421.875KHz。
参数 FirstBit 设置数据传输顺序是 MSB 位在前还是 LSB 位在前,,这里我们选择
SPI_FIRSTBIT_MSB 高位在前。
参数 TIMode 用来设置 TI 模式使能还是禁止,这里我们禁止即可。
参数 CRCCalculation, CRCPolynomial 和 CRCLength 分别用来设置使能/禁止 CRC 校验,CRC
校验多项式以及 CRC 校验的长度。
参数 NSSPMode 用来设置在连续传输时,是否允许 SPI 在两个连续数据间产生 NSS 脉冲。
设置好上面参数后,我们就可以初始化 SPI 外设了。初始化的范例格式为:
SPI2_Handler.Instance=SPI2; //SP2SPI2_Handler.Init.Mode=SPI_MODE_MASTER; //设置 SPI 工作模式,设置为主模式SPI2_Handler.Init.Direction=SPI_DIRECTION_2LINES;// SPI 设置为双线mó式SPI2_Handler.Init.DataSize=SPI_DATASIZE_8BIT; // SPI 发送接收 8 位帧结构SPI2_Handler.Init.CLKPolarity=SPI_POLARITY_HIGH; //时钟的空闲状态为高电平SPI2_Handler.Init.CLKPhase=SPI_PHASE_2EDGE; //同步时钟的第二个跳变沿数据采样SPI2_Handler.Init.NSS=SPI_NSS_SOFT; //内部 NSS 信号有 SSI 位控制SPI2_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_256;//波特率 256 分频SPI2_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB; //数据传输从 MSB 位开始SPI2_Handler.Init.TIMode=SPI_TIMODE_DISABLE; //关闭 TI 模式SPI2_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;//关闭 CRC 校验SPI2_Handler.Init.CRCPolynomial=7; //CRC 值计算的多项式HAL_SPI_Init(&SPI2_Handler);//初始化 SPI2
3)使能 SPI1。
这一步通过 SPI1_CR1 的 bit6 来设置,以启动 SPI1,在启动之后,我们就可以开始 SPI 通
讯了。库函数使能 SPI1 的方法为:
__HAL_SPI_ENABLE(&SPI2_Handler); //使能 SPI2
4)SPI 传输数据
通信接口当然需要有发送数据和接受数据的函数,HAL 库提供的发送数据函数原型为:
HAL_statusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
这个函数很好理解,往 SPIx 数据寄存器写入数据 Data,从而实现发送。
HAL 库提供的接受数据函数原型为:
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData,uint16_t Size, uint32_t Timeout);
这个函数也不难理解,从 SPIx 数据寄存器读出接受到的数据。
前面我们讲解了 SPI 通信的原理,因为 SPI 是全双工,发送一个字节的tóng时接受一个字节,
发送和接收同时完成,所以 HAL 也提供了一个发送接收统一函数:
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
该函数发送一个字节的同时负责接收一个字节。
5)SPI 中断处理
SPI1 和 SPI2 中断服务函数分别为 SPI1_IRQHandler 和 SPI2_IRQHandler,和串口中断处理
过程一样,HAL 库同样提供了 SPI 中断通用处理入口函数 HAL_SPI_IRQHandler,同时提供了
多个中断处理回调函数,通信过程各种中断最终都会通过相应的回调函数来处理。SPI 相关回
调函数如下:
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi);//发送完成void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi);//接收完成void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi);//发送接收完成void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi);//发送过半void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi);//接收过半void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi);//发送接收过半void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);//传输错误
SPI2 de使用就介绍到这里,接下来介绍一下 NRF24L01 无线模块。
39.1.2 NRF24L01 无线模块简介
NRF24L01 无线模块,采用的芯片是 NRF24L01,该芯片的主要特点如下:
1)2.4G 全球开放的 ISM 频段,免许可证使用。
2)最高工作速率 2Mbps,高校的 GFSK 调制,抗干扰能力强。
3)125 个可选的频道,满足多点通信和调频通信的需要。
4)内置 CRC 检错和点对多点的通信地址控制。
5)低工作电压(1.9~3.6V)。
6)可设置自动应答,确保数据可靠传输。
该芯片通过 SPI 与外部 MCU 通信,最大的 SPI 速度可以达到 10Mhz。本章我们用到的模
块是深圳云佳科技生产的 NRF24L01,该模块已经被很多公司大量使用,成熟度和稳定性都是
相当不错的。该模块的外形和引脚图如图 39.1.2.1 所示:
图 39.1.2.1 NRF24L01 无线模块外观引脚图
模块 VCC 脚的电压范围为 1.9~3.6V,建议不要超过 3.6V,fǒu则可能烧坏模块,一般用 3.3V
电压比较合适。除了 VCC 和 GND 脚,其他引脚都可以和 5V 单片机的 IO 口直连,正是因为其
兼容 5V 单片机的 IO,故使用上具有很大优势。
关于 NRF24L01 的详细介绍,请参考 NRF24L01 的技术手册。
39.2 硬件设计
本章实验功能简介:开机的时候先检测 NRF24L01 模块是否存在,在检测到 NRF24L01
模块之后,根据 KEY0 和 KEY1 的设置来决定模块的工作模式,在设定好工作模式之后,就会
不停的发送/接收数据,同样用 DS0 来指示程序正在运行。
所要用到的硬件资源如下:
1) 指示灯 DS0
2) KEY0 和 KEY1 按键
3) LCD 模块
4) SPI2
5) NRF24L01 模块
NRF24L01 模块属于外部模块,这里我们仅介绍开发板上 NRF24L01 模块接口和
STM32F767 的连接情况,他们的连接关系如图 39.2.1 所示:
图 39.2.1 NRF24L01 模块接口与 STM32F767 连接原理图
这里NRF24L01使用的是SPI2,连接在PB13/PB14/PB15上。注意:NRF_IRQ和GBC_KEY
共用了PI11,NRF_CE和SPDIF_RX共用PG12,所以,他们不能同时使用,需要分时复用。
由于无线通信实验是双向的,所以至少要有两个模块同时能工作,这里我们使用2套
ALIENTEK水星STM32F767开发板来向大家演示。
39.3 软件设计
打开本章实验工程可以看到,我们在工程中添加了 spi 底层驱动函数,因为 NRF24L01 是
SPI2 通信接口。同时,我们增加了 24l01.c 源文件以及包含le对应的头文件用来编写 NRF24L01
底层驱动函数。打开 spi.c 文件可以看到 spi2 相关的驱动函数,内容如下:
SPI_HandleTypeDef SPI2_Handler; //SPI2 句柄//以下是 SPI 模块的初始化代码,配置成主机模式//SPI 口初始化//这里针是对 SPI2 的初始化void SPI2_Init(void){ SPI2_Handler.Instance=SPI2; //SP2 SPI2_Handler.Init.Mode=SPI_MODE_MASTER; //设置 SPI 工作模式,设置为主模式 SPI2_Handler.Init.Direction=SPI_DIRECTION_2LINES;//SPI 设置为双线模式 SPI2_Handler.Init.DataSize=SPI_DATASIZE_8BIT; // SPI 发送接收 8 位帧结构 SPI2_Handler.Init.CLKPolarity=SPI_POLARITY_HIGH; //同步时钟空闲状态为高电平 SPI2_Handler.Init.CLKPhase=SPI_PHASE_2EDGE; //同步时钟第二个跳变沿采样数据 SPI2_Handler.Init.NSS=SPI_NSS_SOFT; //内部 NSS 信号有 SSI 位控制 SPI2_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_256;//定义波特率预分频的值:波特率预分频值为 256 SPI2_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB; //数据传输从 MSB 位开始 SPI2_Handler.Init.TIMode=SPI_TIMODE_DISABLE; //关闭 TI 模式 SPI2_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;//关闭硬件 CRC 校验 SPI2_Handler.Init.CRCPolynomial=7; //CRC 值计算的多项式 HAL_SPI_Init(&SPI2_Handler); __HAL_SPI_ENABLE(&SPI2_Handler); //使能 SPI2 SPI2_ReadWriteByte(0Xff); //启动传输}//SPI2 底层驱动,时钟使能,引脚配置//此函数会被 HAL_SPI_Init()调用//hspi:SPI 句柄void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi){ GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOB_CLK_ENABLE(); //使能 GPIOF 时钟__HAL_RCC_SPI2_CLK_ENABLE(); //使能 SPI2 时钟 //PB13,14,15 GPIO_Initure.Pin=GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; GPIO_Initure.Mode=GPIO_MODE_AF_PP;//复用推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FAST; //快速 GPIO_Initure.Alternate=GPIO_AF5_SPI2; //复用为 SPI2 HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化}//SPI 速度设置函数//SPI 速度=fAPB1/分频系数//@ref SPI_BaudRate_Prescaler://SPI_BAUDRATEPRESCALER_2~SPI_BAUDRATEPRESCALER_2 256//fAPB1 时钟一般为 54Mhz:void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler){ assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性 __HAL_SPI_DISABLE(&SPI2_Handler); //guān闭 SPI SPI2_Handler.Instance->CR1&=0XFFC7; //位 3-5 清零,用来设置波特率 SPI2_Handler.Instance->CR1|=SPI_BaudRatePrescaler;//设置 SPI 速度 __HAL_SPI_ENABLE(&SPI2_Handler); //使能 SPI}//SPI2 读写一个字节//TxData:要写入的字节//返回值:读取到的字节u8 SPI2_ReadWriteByte(u8 TxData){ u8 Rxdata; HAL_SPI_TransmitReceive(&SPI2_Handler,&TxData,&Rxdata,1, 1000);return Rxdata;//返回收到的数jù}
这里实现了 4 个函数,分别是 SPI2 初始化函数(SPI2_Init)、SPI 初始化回调函数
HAL_SPI_MspInit , SPI2 通 信 速 度 设 置 函 数 ( SPI2_SetSpeed ) 和 SPI2 读 写 操 作 函 数
(SPI2_ReadWriteByte)。SPI2_Init 函数是按 41.1.1 小节的步骤 2 讲解的调用 SPI 初始化函数
HAL_SPI_Init 来实现 SPI2 初始化。SPI 初始化回调函数 HAL_SPI_MspInit 内部主要根据 41.1.1
小节讲解的步骤 1 来实现 SPI2 时钟使能和 IO 复用映射。SPI2_ReadWriteByte 函数主要是通过
调用 HAL 库中 SPI 发送接收函数 HAL_SPI_TransmitReceive 来实现数据的发送和接收。这里我
们着重看一下 SPI2_SetSpeed 函数,该函数用来设置 SPI2 的传输速度也就是波特率,SPI2 的传
输速度是通过 SPI2->CR1 寄存器的位 3-5 来设置,具体设置方法请参考《STM32F7 中文参考手
册》32.9.1 小节中 CR1 寄存器描述。
接下来我们打开 24l01.c 文件,代码如下:
const u8 TX_ADDRESS[TX_ADR_width=\”360px\”,height=\”auto\” />
状态寄存器值u8 NRF24L01_Read_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++)pBuf[u8_ctr]=SPI2_ReadWriteByte(0XFF);//读出数据 NRF24L01_CSN(1); //关闭 SPI 传输 return status; //返回读到的状态值}//在指定位置写指定长度的数据//reg:寄存器(位置)//*pBuf:数据指针//len:数据长度//返回值,此次读到的zhuàng态寄存器值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_8); //spi 速度为 6.75MhzNRF24L01_CE(0); NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_width=\”360px\”,height=\”auto\” />
此部分代mǎ完成了对 NRF24L01 的初始化、模式设置(发送/接收)、数据读写等操作。在这
里强调一个要注意的地方,在 NRF24L01_Init 函数里面,我们调用了 SPI2_Init()函数,该函
数设置的是 SCK 空闲时为高,但是 NRF24L01 的 SPI 通信时序如图 39.3.1 所示:
图 39.3.1 NRF24L01 读写操作时序
上图中 Cn 代表指令位,Sn 代表状态寄存器位,Dn 代表数据位。从图中可以看出,SCK 空
闲的时候是低电平的,而数据在 SCK 的上升沿被读写。所以,我们需要设置 SPI 的 CPOL 和 CPHA
均为 0,来满足 NRF24L01 对 SPI 操作的要求。所以,我们在 NRF24L01_Init 函数里面又单独添
加了将 CPOL 和 CPHA 设置为 0 的函数 NRF24L01_SPI_Init。这里主要是修改了下面两行代码;
SPI2_Handler.Init.CLKPolarity=SPI_POLARITY_LOW; //串行同步时钟的空闲状态为低电平
SPI2_Handler.Init.CLKPhase=SPI_PHASE_1EDGE; //同步时钟的第 1 个跳变沿数据被采样
接下来我们看看 24l01.h 头文件部分内容:
#ifndef __24L01_H#define __24L01_H#include "sys.h"//NRF24L01 寄存器操作命令#define READ_REG0x00//读配置寄存器,低 5 位为寄存器地址……//省略部分定义#define FIFO_STATUS 0x17//FIFO 状态寄存器;bit0,RX FIFO 寄存器空标志;//bit1,RX FIFO 满标志;bit2,3,保留 bit4,TX FIFO 空标志;bit5,TX FIFO 满标志;//bit6,1, 循环发送上一数据包.0,不循环;//24L01 cāo作线#define NRF24L01_CE(n) (n?HAL_GPIO_WritePin(GPIOG,GPIO_PIN_12,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOG,GPIO_PIN_12,GPIO_PIN_RESET))//24L01 片选信号#define NRF24L01_CSN(n) (n?HAL_GPIO_WritePin(GPIOG,GPIO_PIN_10, \\\\GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOG,GPIO_PIN_10,GPIO_PIN_RESET))//SPI 片选信号#define NRF24L01_IRQ HAL_GPIO_ReadPin(GPIOI,GPIO_PIN_11)//IRQ 主机数据输入//24L01 发送接收数据宽度定义#define TX_ADR_width=\”360px\”,height=\”auto\” />
部分代码,主yào定义了一些 24L01 的命令字(这里我们省略了一部分),以及函数声明,这
里还通过 TX_PLOAD_width=\”360px\”,height=\”auto\” />
发射和接受的有效字节数。NRF24L01 每次最多传输 32 个字节,再多的字节传输则需要多次传
送。
最后我们看看主函数:
int main(void){u8 key,mode;u16 t=0;u8 tmp_buf[33]; Cache_Enable(); //打开 L1-Cache HAL_Init(); //初始化 HAL 库 Stm32_Clock_Init(432,25,2,9); //设置时钟,216Mhz delay_init(216); //延时初始化…//此处省略部分代码NRF24L01_Init();//初始化 NRF24L01while(NRF24L01_Check()){LCD_ShowString(30,130,200,16,16,"NRF24L01 Error");delay_ms(200);LCD_Fill(30,130,239,130+16,WHITE);delay_ms(200);}LCD_ShowString(30,130,200,16,16,"NRF24L01 OK");while(1){key=KEY_Scan(0);if(key==KEY0_PRES){mode=0;break;}else if(key==KEY1_PRES){mode=1;break;}t++;if(t==100)LCD_ShowString(10,150,230,16,16,"KEY0:RX_ModeKEY1:TX_Mode"); //闪烁显示提示信息if(t==200){LCD_Fill(10,150,230,150+16,WHITE);t=0;}delay_ms(5);}LCD_Fill(10,150,240,166,WHITE);//清空上面的显示POINT_COLOR=BLUE;//设置字体为蓝色if(mode==0)//RX 模式{LCD_ShowString(30,150,200,16,16,"NRF24L01 RX_Mode");LCD_ShowString(30,170,200,16,16,"Received DATA:");NRF24L01_RX_Mode();while(1){if(NRF24L01_RxPacket(tmp_buf)==0)//一旦接收到信息,则显示出来.{tmp_buf[32]=0;//加入字符串结束符LCD_ShowString(0,190,lcddev.width=\”360px\”,height=\”auto\” />
以上代码,我们就实现了 40.2 节所介绍的功能,程序运行时先通过 NRF24L01_Check 函
数检测 NRF24L01 是否存在,如果存在,则让用户选择发送模式(KEY1)还是接收模式(KEY0),
在确定模式之后,设置 NRF24L01 的工作模式,然后执行相应的数据发送/接收处理。
至此,我们整个实验的软件设计就完成了。
39.4 下载验zhèng
在代码编译成功之后,我们通过下载代码到 ALIENTEK 水星 STM32 开发板上,可以看到
LCD 显示如图 39.4.1 所示的内容(假定 NRF24L01 模块已经接上开发板):
图 39.4.1 选择工作模式界面
通过 KEY0 和 KEY1 来选择 NRF24L01 模块所要进入的工作模式,我们两个开发板一个选
择发送,一个选择接收就可以了。设置好后通信界面如图 39.4.2 和图 39.4.3 所示:
图 39.4.2 开发板 A 发送数据
图 39.4.3 开发板 B 接收数据
图 39.4.2 来自开发板 A,工作在发送模式。图 39.4.3 来自开发板 B,工作在接收模式,A
发送,B 接收。可以看到收发数据是一致的,说明实验成功。
水星落在天蝎座(0度);在命盘的第7宫
楼上复制党不解释。待我物塌桥慢慢分析。太阳天蝎你性格深衫尺沉倔强而冷漠魅力惊人非常性感但占有欲强好嫉妒月亮巨蟹平和了你感情偏激的特点你温柔而平和和家人女友有着良好的关系不喜欢被人在思想上引领乐yú助人沉默喜欢依恋他人而细腻水星天蝎你有侦探的才能会有这种才能去对付自己的恋人表达力精准犀利爱好批评有时让人受不了金星天蝎你太专情爱得无法平淡骨子里是认定一个人就一生一世的火星摩羯你个性过度坚决谋略和体力过人木星天蝎这个和我一样属于对罩猛异性有奇特吸引力的土星天秤你擅长合作担负巨大责任天王海王冥王和时代有关不好详细解释婚神星意味着你的真命天子与你自身相差很大你的生命中会遇到一场流年奇缘留恋中有等待别的星星我也不是很了解上升双鱼面相柔弱有桃花眼看起来跟你坚硬好强的本来面貌全然不似为所爱之人牺牲综上我打了很多字希望你给分还有就是出手大方点
以上就是关于水星第七宫,水星由近到远的知识,后面我们会继续为大家整理关于水星第7?m的知识,希望能够帮助到大家!
联系我们
关注公众号