完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32软件SPI实现NRF24L01
NRF一共是八个引脚,除去VCC和GND还有六个引脚。 所以我们只需要配置这六个引脚就可以了。 这六个引脚分别是SCK,MOSI,MISO,CSN,CE,IRQ 除了MISO和IRQ配置成输入,其他的都配置为输出即可,其实如果不配IRQ也没事,如果有需要的话可以配置,不配的也是可以的,不会影响单片机的通信。 配置输入和输出就和配置LED和按键输入是一样的,代码可以参考LED和按键输入的代码。 以上的代码是NRF的初始化 接下来我们需要几个宏定义,具体的作用是方面我们随时改变管教的高低电平 /* SCK PA0 */ #define NRF_SCK(x) GPIOA->ODR &=~(1<<0);GPIOA->ODR |= x<<0 /* MOSI PA1*/ #define NRF_MOSI(x) GPIOA->ODR &=~(1<<1);GPIOA->ODR |= x<<1 /* MISO PA2*/ #define NRF_MISO(x) GPIOA->ODR &=~(1<<2);GPIOA->ODR |= x<<2 #define NRF_MISO_VALUE (u8)((GPIOA->IDR&0x04)>>2) /* CSN PA3 */ #define NRF_CSN(x) GPIOA->ODR &=~(1<<3);GPIOA->ODR |= x<<3 /* CE PA4 */ #define NRF_CE(x) GPIOA->ODR &=~(1<<4);GPIOA->ODR |= x<<4 /* IRQ PA5 */ #define NRF_IRQ_VALUE (u8)((GPIOA->IDR&0x20)>>5) 这里我写的代码是基于寄存器的操作,这个是简单的宏定义,例如当我们写NRF_SCK(1)时PA0也就是接到NRF的SCK引脚配置为高电平。 我们还需要相应的寄存器的地址宏定义 #define NRF_READ_REG 0X00 #define NRF_WRITE_REG 0X20 #define RD_RX_PLOAD 0X61 #define WR_TX_PLOAD 0XA0 #define FLUSH_TX 0XE1 #define FLUSH_RX 0XE2 #define REUSE_TX_PL 0XE3 #define NOP 0XFF #define CONFIG 0x00 #define EN_AA 0x01 #define EN_RXADDR 0x02 #define SETUP_AW 0x03 #define SETUP_RETR 0x04 #define RF_CH 0x05 #define RF_SETUP 0x06 #define STATUS 0x07 #define MAX_TX 0x10 #define TX_OK 0x20 #define RX_OK 0x40 #define OBSERVE_TX 0x08 #define CD 0x09 #define RX_ADDR_P0 0x0A #define RX_ADDR_P1 0x0B #define RX_ADDR_P2 0x0C #define RX_ADDR_P3 0x0D #define RX_ADDR_P4 0x0E #define RX_ADDR_P5 0x0F #define TX_ADDR 0x10 #define RX_PW_P0 0x11 #define RX_PW_P1 0x12 #define RX_PW_P2 0x13 #define RX_PW_P3 0x14 #define RX_PW_P4 0x15 #define RX_PW_P5 0x16 #define NRF_FIFO_STATUS 0x17 #define TX_ADR_WIDTH 5 #define RX_ADR_WIDTH 5 #define TX_PLOAD_WIDTH 32 #define RX_PLOAD_WIDTH 32 这个时候我们基本已经完成了,现在我们可以写SPI了,简单的操作,具体几个函数如下 /* 写入的时候并读取一个字节 */ u8 NRF_WR(u8 byte) { u8 i; for(i = 0;i<8; i++) { /* 先发送高位 */ NRF_MOSI((byte & 0X80)>>7); byte = (byte << 1); NRF_SCK(1); byte |= NRF_MISO_VALUE; NRF_SCK(0); } return byte; } /* 向一个寄存器写入一个值 */ u8 NRF_WR_REG(u8 reg,u8 value) { u8 status; NRF_CSN(0); status = NRF_WR(reg); NRF_WR(value); NRF_CSN(1); return status; } /* 读取寄存器 */ u8 NRF_READ(u8 reg) { u8 reg_val; NRF_CSN(0); NRF_WR(reg); reg_val = NRF_WR(0XFF); NRF_CSN(1); return reg_val; } /* 读取指定长度的值 */ u8 NRF_READ_BUF(u8 reg,u8 *pBuf,u8 bytes) { u8 status,byte; NRF_CSN(0); status = NRF_WR(reg); for(byte = 0;byte < bytes;byte ++) { pBuf[byte] = NRF_WR(0); } NRF_CSN(1); return status; } /* 写入指定长度的值 */ u8 NRF_WRITE_BUF(u8 reg,u8 *pBuf,u8 bytes) { u8 status,byte; NRF_CSN(0); status = NRF_WR(reg); for(byte = 0;byte < bytes;byte ++) { NRF_WR(*pBuf++); } NRF_CSN(1); return status; } 好大致的操作已经完成了,我们现在向NRF寄存器中写入一个值,然后我们再去读这个NRF寄存器的值,应该就是我们写的值。这一步就是我们所说的NRF自检。 /* NRF自检 */ /* 就是先写入一个值 然后再读出一个值 看一下自己读出来的是否和自己写入的是否一样*/ /* 一样自检通过 不一样自检不通过 */ u8 NRF24L01_Check(void) { u8 i; u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5}; NRF_WRITE_BUF((NRF_WRITE_REG+TX_ADDR),buf,5); NRF_READ_BUF(TX_ADDR,buf,5); for(i=0;i<5;i++)if(buf!=0XA5)break; if(i!=5)return 1; return 0; } 这个时候该配置的都配置了接下来就是两个单片机之间的通信了。 主机我们负责发送数据,我们需要配置发送地址和发送的速率 从机负责接受数据,我们需要配置接收地址和接受速率等 /* 配置接受和发送的地址 */ const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x09,0x25,0x57,0x11,0x01}; //发送地址 const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x09,0x25,0x57,0x11,0x01}; //发送地址 地址可以自己随意设定,但是主机和从机的地址应该一样,否则连接不上 /* RX模式 */ void RX_MODE(void) { NRF_CE(0); /* 配置接收的地址 */ NRF_WRITE_BUF(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); /* 通道0自动应答 */ NRF_WR_REG(NRF_WRITE_REG+EN_AA,0x01); /* 接收数据通道0允许 */ NRF_WR_REG(NRF_WRITE_REG+EN_RXADDR,0x01); /* 设置工作频率 */ NRF_WR_REG(NRF_WRITE_REG+RF_CH,40); /* 接收数据有效宽度为32字节 */ NRF_WR_REG(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); /* 低噪声放大 发射功率 数据传输率2M */ NRF_WR_REG(NRF_WRITE_REG+RF_SETUP,0x0f); /* 配置为接收 */ NRF_WR_REG(NRF_WRITE_REG+CONFIG, 0x0f); NRF_CE(1); } /* TX模式 */ void TX_MODE(void) { NRF_CE(0); /* 发送的地址 */ NRF_WRITE_BUF(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH); /* 有效的字节宽度为32字节 */ NRF_WRITE_BUF(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); /* 通道0自动应答 */ NRF_WR_REG(NRF_WRITE_REG+EN_AA,0x01); /* 数据接收通道0允许 */ NRF_WR_REG(NRF_WRITE_REG+EN_RXADDR,0x01); /* 等待500+86us 自动重发次数为10次*/ NRF_WR_REG(NRF_WRITE_REG+SETUP_RETR,0x1a); /* 设置工作频率 */ NRF_WR_REG(NRF_WRITE_REG+RF_CH,40); /* 低噪声放大 发射功率 数据传输率2M */ NRF_WR_REG(NRF_WRITE_REG+RF_SETUP,0x0f); /* 配置为发送 */ NRF_WR_REG(NRF_WRITE_REG+CONFIG, 0x0e); NRF_CE(1); } **好 至此我们配置已经全部完成了大致分为
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1916 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1680 浏览 1 评论
1172 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
771 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1732 浏览 2 评论
1973浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
808浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
257浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
625浏览 3评论
634浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-24 21:16 , Processed in 0.598268 second(s), Total 41, Slave 36 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号