完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
/********** mySpi.h****************/
#ifndef __MY_SPI_H #define __MY_SPI_H #include "stm32f10x.h" #include #define SPI1_CSN_HIGH() GPIO_SetBits(GPIOA,GPIO_Pin_1); #define SPI1_CSN_LOW() GPIO_ResetBits(GPIOA,GPIO_Pin_1); #define SPI2_CSN_HIGH() GPIO_SetBits(GPIOB,GPIO_Pin_12); #define SPI2_CSN_LOW() GPIO_ResetBits(GPIOB,GPIO_Pin_12); void mySpi1Config(void); u8 mySpi1SendByte(u8 byte); void mySpi2Config(void); u8 mySpi2SendByte(u8 byte); #endif /**********mySpi.c************/ #include "mySpi.h" void mySpi1Config(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //SCK,MISO,MOSI GPIOA^5,GPIOA^6,GPIOA^7 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能 GPIO_Init(GPIOA, &GPIO_InitStructure); //CSN GPIOA^1 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); SPI1_CSN_HIGH(); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主机模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟空闲时为低 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一个边沿有效 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件产生 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //8分频=9MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前 SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); } void mySpi2Config(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI2, ENABLE); //SCK,MISO,MOSI GPIOB^13,GPIOB^14 GPIOB^15 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能 GPIO_Init(GPIOB, &GPIO_InitStructure); //CSN GPIOB^12 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); SPI2_CSN_HIGH(); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主机模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟空闲时为低 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一个边沿有效 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件产生 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //8分频=9MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前 SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI2, &SPI_InitStructure); SPI_Cmd(SPI2, ENABLE); } u8 mySpi1SendByte(u8 byte) { while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);// 当SPI发送缓存不为空 SPI_I2S_SendData(SPI1, byte);//通过SPI发送数据 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //当SPI接收缓存不为空 return SPI_I2S_ReceiveData(SPI1); //读取缓存数据 } u8 mySpi2SendByte(u8 byte) { while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);// 当SPI发送缓存不为空 SPI_I2S_SendData(SPI2, byte);//通过SPI发送数据 while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); //当SPI接收缓存不为空 return SPI_I2S_ReceiveData(SPI2); //读取缓存数据 } /***********myNRF24L01.h********************/ #ifndef __MY_NRF24L01_H #define __MY_NRF24L01_H #include "stm32f10x.h" #include /********** 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 // 空操作-用于读状态寄存器 /********** NRF24L01寄存器地址 *************/ #define CONFIG 0x00 // 配置寄存器地址 #define EN_AA 0x01 // 使能自动应答功能 #define EN_RXADDR 0x02 //接收地址允许 #define SETUP_AW 0x03 // 设置地址宽度 #define SETUP_RETR 0x04 //建立自动重发 #define RF_CH 0x05 //RF通道 #define RF_SETUP 0x06 // RF寄存器 #define STATUS 0x07 //状态寄存器 #define OBSERVE_TX 0x08 //发送检测寄存器 #define CD 0x09 // 载波检测寄存器 #define RX_ADDR_P0 0x0A //数据通道0接收地址 #define RX_ADDR_P1 0x0B // 数据通道1接收地址 #define RX_ADDR_P2 0x0C // 数据通道2接收地址 #define RX_ADDR_P3 0x0D //数据通道3接收地址 #define RX_ADDR_P4 0x0E //数据通道4接收地址 #define RX_ADDR_P5 0x0F //数据通道5接收地址 #define TX_ADDR 0x10 // 发送地址寄存器 #define RX_PW_P0 0x11 // 接收数据通道0有效数据宽度(1~32字节) #define RX_PW_P1 0x12 // 接收数据通道1有效数据宽度(1~32字节) #define RX_PW_P2 0x13 // 接收数据通道2有效数据宽度(1~32字节) #define RX_PW_P3 0x14 // 接收数据通道3有效数据宽度(1~32字节) #define RX_PW_P4 0x15 // 接收数据通道4有效数据宽度(1~32字节) #define RX_PW_P5 0x16 // 接收数据通道5有效数据宽度(1~32字节) #define FIFO_STATUS 0x17 // FIFO状态寄存器 /****** STATUS寄存器BIT位定义 *******/ #define MAX_TX 0x10 //达到最大发送次数中断 #define TX_OK 0x20 //TX发送完成中断 #define RX_OK 0x40 //接收到数据中断 void myNrfConfig(void); u8 myNrfWriteReg(u8 reg,u8 dat); u8 myNrfReadReg(u8 reg); u8 myNrfWriteBuf(u8 reg,u8 *pBuf,u8 byte); u8 myNrfReadBuf(u8 reg,u8 *pBuf,u8 byte); u8 myNrfCheck(void); void myNrfRxMode(void); void myNrfTxMode(void); u8 myNrfTxDat(u8 *txbuf); u8 myNrfRxDat(u8 *rxbuf); #endif /*******************myNRF24L01.c*********************/ #include "myNRF24L01.h" #include "mySpi.h" #define NRF_CE_HIGH() GPIO_SetBits(GPIOA,GPIO_Pin_2); #define NRF_CE_LOW() GPIO_ResetBits(GPIOA,GPIO_Pin_2); #define NRF_READ_IRQ() GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3) //IRQ #define myNrfSpiConfig mySpi1Config //替换NRF的SPI配置函数 #define myNrfSpiSendByte mySpi1SendByte //替换NRF的SPI读写函数 #define NRF_CSN_LOW SPI1_CSN_LOW //替换NRF的SPI的CSN宏定义 #define NRF_CSN_HIGH SPI1_CSN_HIGH #define CHANAL 0 //频道选择 #define TX_ADR_WIDTH 5 //5字节地址宽度 #define RX_ADR_WIDTH 5 //5字节地址宽度 #define TX_PLOAD_WIDTH 32 //32字节有效数据宽度 #define RX_PLOAD_WIDTH 32 //32字节有效数据宽度 u8 RX_BUF[RX_PLOAD_WIDTH]; //接收数据缓存 u8 TX_BUF[TX_PLOAD_WIDTH]; //发送数据缓存 u8 TX_ADDRESS[TX_ADR_WIDTH] = {0xFF,0xFF,0xFF,0xFF,0xFF}; //静态地址 u8 RX_ADDRESS[RX_ADR_WIDTH] = {0xFF,0xFF,0xFF,0xFF,0xFF}; void myNrfConfig(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //NRF CE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //NRF IRQ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //NRF SPI配置 myNrfSpiConfig(); } //指定寄存器写入指定数据 u8 myNrfWriteReg(u8 reg,u8 dat) { u8 status; NRF_CE_LOW(); NRF_CSN_LOW(); status = myNrfSpiSendByte(reg);// myNrfSpiSendByte(dat); // NRF_CSN_HIGH(); return(status); } //从指定寄存器读取数据 u8 myNrfReadReg(u8 reg) { u8 reg_val; NRF_CE_LOW(); NRF_CSN_LOW(); myNrfSpiSendByte(reg); // reg_val = myNrfSpiSendByte(NOP); // NRF_CSN_HIGH(); return reg_val; } //从指定寄存器读取一串数据 u8 myNrfReadBuf(u8 reg,u8 *pBuf,u8 bytes) { u8 status, byte_cnt; NRF_CE_LOW(); NRF_CSN_LOW(); status = myNrfSpiSendByte(reg); // for(byte_cnt=0;byte_cnt pBuf[byte_cnt] = myNrfSpiSendByte(NOP); // } NRF_CSN_HIGH(); return status; // } //向指定寄存器写入一串数据 u8 myNrfWriteBuf(u8 reg ,u8 *pBuf,u8 bytes) { u8 status,byte_cnt; NRF_CE_LOW(); NRF_CSN_LOW(); status = myNrfSpiSendByte(reg); for(byte_cnt=0;byte_cnt myNrfSpiSendByte(*pBuf++); // } NRF_CSN_HIGH(); return (status); // } //检测NRF与MCU连接与否 u8 myNrfCheck(void) { u8 buf[5]={0xC2,0xC2,0xC2,0xC2,0xC2}; u8 buf1[5]; u8 i; myNrfWriteBuf(nRF_WRITE_REG+TX_ADDR,buf,5); //дÈë5¸ö×ֽڵĵØÖ· myNrfReadBuf(TX_ADDR,buf1,5); //¶Á³öдÈëµÄµØÖ· //±È½Ï for(i=0;i<5;i++) { if(buf1!=0xC2) break; } if(i==5) return SUCCESS ; //MCUÓëNRF³É¹¦Á¬½Ó else return ERROR ; //MCUÓëNRF²»Õý³£Á¬½Ó } //配置NRF进入发送模式 void myNrfRxMode(void) { NRF_CE_LOW(); myNrfWriteBuf(nRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);设置RX节点地址 myNrfWriteReg(nRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 myNrfWriteReg(nRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的自动应答 myNrfWriteReg(nRF_WRITE_REG+RF_CH,CHANAL); //设置RF通道 myNrfWriteReg(nRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//设置通道0 的有效数据宽度 myNrfWriteReg(nRF_WRITE_REG+RF_SETUP,0x0f);//设置发射参数 -0db增益,2Mbps,低噪音增益开启 myNrfWriteReg(nRF_WRITE_REG+CONFIG, 0x0f);//配置基本工作模式-PWR_UP, EN_CRC, 16BIT_CRC 接收模式 开启所有中断 NRF_CE_HIGH(); } //配置NRF进入接收模式 void myNrfTxMode(void) { NRF_CE_LOW(); myNrfWriteBuf(nRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //设置TX节点地址 myNrfWriteBuf(nRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//设置RX节点地址-使能ACK myNrfWriteReg(nRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 myNrfWriteReg(nRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 myNrfWriteReg(nRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔 myNrfWriteReg(nRF_WRITE_REG+RF_CH,CHANAL); //设置RF通道 myNrfWriteReg(nRF_WRITE_REG+RF_SETUP,0x0f);//设置发射参数 -0db增益,2Mbps,低噪音增益开启 myNrfWriteReg(nRF_WRITE_REG+CONFIG,0x0e);//配置基本工作模式-PWR_UP, EN_CRC, 16BIT_CRC 发射模式 开启所有中断 NRF_CE_HIGH(); } //向NRF的发送缓存写入数据 u8 myNrfTxDat(u8 *txbuf) { u8 state; |
|
|
|
|
|
NRF_CE_LOW(); //进入发送模式
myNrfWriteBuf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH); //写数据到发送缓存 NRF_CE_HIGH(); //CE为高 发送缓存不为空 则发送数据包 while(NRF_READ_IRQ()!=0); //等待发送完成 state = myNrfReadReg(STATUS); //读取状态寄存器 myNrfWriteReg(nRF_WRITE_REG+STATUS,state); //清除中断标志 myNrfWriteReg(FLUSH_TX,NOP); //清除TX FIFO寄存器 if(state&MAX_TX) //达到最大重发次数 { return MAX_TX; } else if(state&TX_OK) //发送完成 { return TX_OK; } else { return ERROR; //其它原因失败 } } //从NRF接收缓存读取数据 u8 myNrfRxDat(u8 *rxbuf) { u8 state; u16 ii = 2000; NRF_CE_HIGH(); //进入接收模式 while(ii && NRF_READ_IRQ()!=0) //等待接收数据 { ii--; } NRF_CE_LOW(); //进入待机状态 state=myNrfReadReg(STATUS); //读取状态寄存器 myNrfWriteReg(nRF_WRITE_REG+STATUS,state); //清除中断标志 if(state&RX_OK) //接收到数据 { myNrfReadBuf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据 myNrfWriteReg(FLUSH_RX,NOP); //清除FIFO寄存器 return RX_OK; } else { return ERROR; // } } /************main.c********************/myNrfConfig(); int main(void) { myNrfConfig(); status = myNrfCheck(); //检测 if(status == SUCCESS) printf("SUCCESrn"); else printf("ERRORrn"); while (1) { myNrfRxMode(); //进入接收模式 status = myNrfRxDat(rxbuf); //等待接收数据 switch(status) { case RX_OK: myNrfTxMode(); //进入发送模式 status = myNrfTxDat(rxbuf); //将接收到的数据发送出去 break; } } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1553 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1497 浏览 1 评论
925 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
660 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1551 浏览 2 评论
1846浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
603浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
503浏览 3评论
504浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
486浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-8 05:25 , Processed in 0.462596 second(s), Total 46, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号