当前位置: 首页 > news >正文

STM32F103C8T6 + SI24R1实现2.4G通信

原理图:

SPI时序

可以看的出来,SCK空闲时低电平,第一个跳变采样,高位先行,8Bit,HAL库可以这样配置

宏定义:

#define MY_RF_CH 69 #define RX_MODE 0 #define TX_MODE 1 #define SI24R1_CSN_LOW HAL_GPIO_WritePin(SI24R1_CSN_GPIO_Port, SI24R1_CSN_Pin, GPIO_PIN_RESET) #define SI24R1_CSN_HIGH HAL_GPIO_WritePin(SI24R1_CSN_GPIO_Port, SI24R1_CSN_Pin, GPIO_PIN_SET) #define SI24R1_CE_LOW HAL_GPIO_WritePin(SI24R1_CE_GPIO_Port, SI24R1_CE_Pin, GPIO_PIN_RESET) #define SI24R1_CE_HIGH HAL_GPIO_WritePin(SI24R1_CE_GPIO_Port, SI24R1_CE_Pin, GPIO_PIN_SET) // SI24R1 PIN DEFINITION #define MOSI P13 // Master Out, Slave In pin (output) #define MISO P10 // Master In, Slave Out pin (input) #define SCK P12 // Serial Clock pin, (output) #define CSN P15 // Slave Select pin, (output to CSN) #define CE P14 // Chip Enable pin signal (output) #define IRQ P11 // Interrupt signal, from nRF24L01 (input) #define TX_ADR_WIDTH 5 // 5字节宽度的发送/接收地址 #define TX_PLOAD_WIDTH 17 // 数据通道有效数据宽度 //********************************************************************************************************************// // SPI(SI24R1) commands #define SI24R1_READ_REG 0x00 // Define read command to register #define SI24R1_WRITE_REG 0x20 // Define write command to register #define RD_RX_PLOAD 0x61 // Define RX payload register address #define WR_TX_PLOAD 0xA0 // Define TX payload register address #define FLUSH_TX 0xE1 // Define flush TX register command #define FLUSH_RX 0xE2 // Define flush RX register command #define REUSE_TX_PL 0xE3 // Define reuse TX payload register command #define NOP 0xFF // Define No Operation, might be used to read status register //********************************************************************************************************************// // SPI(SI24R1) registers(addresses) #define CONFIG 0x00 // 'Config' register address #define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address #define EN_RXADDR 0x02 // 'Enabled RX addresses' register address #define SETUP_AW 0x03 // 'Setup address width' register address #define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address #define RF_CH 0x05 // 'RF channel' register address #define RF_SETUP 0x06 // 'RF setup' register address #define STATUS 0x07 // 'Status' register address #define OBSERVE_TX 0x08 // 'Observe TX' register address #define RSSI 0x09 // 'Received Signal Strength Indecator' register address #define RX_ADDR_P0 0x0A // 'RX address pipe0' register address #define RX_ADDR_P1 0x0B // 'RX address pipe1' register address #define RX_ADDR_P2 0x0C // 'RX address pipe2' register address #define RX_ADDR_P3 0x0D // 'RX address pipe3' register address #define RX_ADDR_P4 0x0E // 'RX address pipe4' register address #define RX_ADDR_P5 0x0F // 'RX address pipe5' register address #define TX_ADDR 0x10 // 'TX address' register address #define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address #define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address #define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address #define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address #define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address #define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address #define FIFO_STATUS 0x17 // 'FIFO Status Register' register address //********************************************************************************************************************// // STATUS Register #define RX_DR 0x40 /**/ #define TX_DS 0x20 #define MAX_RT 0x10 //********************************************************************************************************************// // FUNCTION's PROTOTYPES // //********************************************************************************************************************// // SI24R1 API Functions void Int_SI24R1_Init(uint8_t mode); // SI24R1 Pin Init uint8_t Int_SI24R1_Write_Reg(uint8_t reg, uint8_t value); uint8_t Int_SI24R1_Write_Buf(uint8_t reg, const uint8_t *pBuf, uint8_t bytes); uint8_t Int_SI24R1_Read_Reg(uint8_t reg); uint8_t Int_SI24R1_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes); void Int_SI24R1_RX_Mode(void); void Int_SI24R1_TX_Mode(void); uint8_t Int_SI24R1_RxPacket(uint8_t *rxbuf); uint8_t Int_SI24R1_TxPacket(uint8_t *txbuf);

读写寄存器:

static uint8_t SPI_RW(uint8_t byte) { uint8_t rx_byte = 0; HAL_SPI_TransmitReceive(&hspi1, &byte, &rx_byte, 1, UINT32_MAX); return rx_byte; } /******************************************************** 函数功能:写寄存器的值(单字节) 入口参数:reg:寄存器映射地址(格式:SI24R1_WRITE_REG|reg) value:寄存器的值 返回 值:状态寄存器的值 *********************************************************/ uint8_t Int_SI24R1_Write_Reg(uint8_t reg, uint8_t value) { uint8_t status; SI24R1_CSN_LOW; status = SPI_RW(reg); SPI_RW(value); SI24R1_CSN_HIGH; return (status); } /******************************************************** 函数功能:写寄存器的值(多字节) 入口参数:reg:寄存器映射地址(格式:SI24R1_WRITE_REG|reg) pBuf:写数据首地址 bytes:写数据字节数 返回 值:状态寄存器的值 *********************************************************/ uint8_t Int_SI24R1_Write_Buf(uint8_t reg, const uint8_t *pBuf, uint8_t bytes) { uint8_t status, byte_ctr; SI24R1_CSN_LOW; status = SPI_RW(reg); for (byte_ctr = 0; byte_ctr < bytes; byte_ctr++) SPI_RW(pBuf[byte_ctr]); SI24R1_CSN_HIGH; return (status); } /******************************************************** 函数功能:读取寄存器的值(单字节) 入口参数:reg:寄存器映射地址(格式:SI24R1_READ_REG|reg) 返回 值:寄存器值 *********************************************************/ uint8_t Int_SI24R1_Read_Reg(uint8_t reg) { uint8_t value; SI24R1_CSN_LOW; SPI_RW(reg); value = SPI_RW(0); SI24R1_CSN_HIGH; return (value); } /******************************************************** 函数功能:读取寄存器的值(多字节) 入口参数:reg:寄存器映射地址(SI24R1_READ_REG|reg) pBuf:接收缓冲区的首地址 bytes:读取字节数 返回 值:状态寄存器的值 *********************************************************/ uint8_t Int_SI24R1_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes) { uint8_t status, byte_ctr; SI24R1_CSN_LOW; status = SPI_RW(reg); for (byte_ctr = 0; byte_ctr < bytes; byte_ctr++) pBuf[byte_ctr] = SPI_RW(0); // 读取数据,低字节在前 SI24R1_CSN_HIGH; return (status); }

SI24R1的SPI通信前三位是固定的,读是000,写是001,后五位是对应寄存器地址,所以写命令可以用0x20+寄存器地址进行

SI24R1接收模式初始化:

uint8_t TX_ADDRESS[TX_ADR_WIDTH] = {0x0A, 0x01, 0x07, 0x0E, 0x01}; // 定义一个静态发送地址

这里的静态地址,需要接收端和发送端相同

void Int_SI24R1_RX_Mode(void) { SI24R1_CE_LOW; Int_SI24R1_Write_Buf(SI24R1_WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 接收设备接收通道0使用和发送设备相同的发送地址 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + EN_AA, 0x01); // 使能接收通道0自动应答 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + EN_RXADDR, 0x01); // 使能接收通道0 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + RF_CH, MY_RF_CH); // 选择射频通道(信道)69 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // 接收通道0选择和发送通道相同有效数据宽度 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + RF_SETUP, 0x0f); // 数据传输率2Mbps,发射功率7dBm Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + CONFIG, 0x0f); // CRC使能,16位CRC校验,上电,接收模式 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + STATUS, 0xff); // 清除所有的中断标志位 Int_SI24R1_Write_Reg(FLUSH_RX, 0xff); // 为了解决硬件BUG SI24R1_CE_HIGH; // 拉高CE启动接收设备 }

SI24R1发送模式初始化:

void Int_SI24R1_TX_Mode(void) { SI24R1_CE_LOW; Int_SI24R1_Write_Buf(SI24R1_WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写入发送地址 Int_SI24R1_Write_Buf(SI24R1_WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 为了应答接收设备,接收通道0地址和发送地址相同 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + EN_AA, 0x01); // 使能接收通道0自动应答 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + EN_RXADDR, 0x01); // 使能接收通道0 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + SETUP_RETR, 0x0a); // 自动重发延时等待250us+86us,自动重发10次 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + RF_CH, MY_RF_CH); // 选择射频通道69 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + RF_SETUP, 0x0f); // 数据传输率2Mbps,发射功率7dBm Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + CONFIG, 0x0e); // CRC使能,16位CRC校验,上电 // SI24R1_CE_HIGH; }

SI24R1初始化:

void Int_SI24R1_Init(uint8_t mode) { // 检查有没有上电成功(启动) while (1) { Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + RF_CH, MY_RF_CH); uint8_t res = Int_SI24R1_Read_Reg(RF_CH); if (res == MY_RF_CH) { break; } } if (mode == RX_MODE) { Int_SI24R1_RX_Mode(); } else if (mode == TX_MODE) { Int_SI24R1_TX_Mode(); } }

先读取状态寄存器判断是否启动,通过传参配置SI24R1模式

读取接受数据:

/******************************************************** 函数功能:读取接收数据 入口参数:rxbuf:接收数据存放首地址 返回 值:0:接收到数据 1:没有接收到数据 *********************************************************/ uint8_t Int_SI24R1_RxPacket(uint8_t *rxbuf) { uint8_t state; state = Int_SI24R1_Read_Reg(STATUS); // 读取状态寄存器的值 Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + STATUS, state); // 清除RX_DR中断标志 if (state & RX_DR) // 接收到数据 { Int_SI24R1_Read_Buf(RD_RX_PLOAD, rxbuf, TX_PLOAD_WIDTH); // 读取数据 Int_SI24R1_Write_Reg(FLUSH_RX, 0xff); // 清除RX FIFO寄存器 return 0; } return 1; // 没收到任何数据 }

发送数据包:

/******************************************************** 函数功能:发送一个数据包 入口参数:txbuf:要发送的数据 返回 值:0x10:达到最大重发次数,发送失败 0x20:发送成功 0xff:发送失败 *********************************************************/ uint8_t Int_SI24R1_TxPacket(uint8_t *txbuf) { uint8_t state; SI24R1_CE_LOW; // CE拉低,使能SI24R1配置 Int_SI24R1_Write_Buf(WR_TX_PLOAD, txbuf, TX_PLOAD_WIDTH); // 写数据到TX FIFO,32个字节 SI24R1_CE_HIGH; // CE置高,使能发送 while (1) { // 读取状态寄存器的值 state = Int_SI24R1_Read_Reg(STATUS); Int_SI24R1_Write_Reg(SI24R1_WRITE_REG + STATUS, state); // 清除TX_DS或MAX_RT中断标志 if (state & MAX_RT) // 达到最大重发次数 { Int_SI24R1_Write_Reg(FLUSH_TX, 0xff); // 清除TX FIFO寄存器 return MAX_RT; } if (state & TX_DS) // 发送完成 { return TX_DS; } }; // 等待发送完成 }

发送端配置:

uint8_t absda[17] = "HELLO WORLD!!!!!"; while (1) { Int_SI24R1_TxPacket(absda); }

接收端配置:

uint8_t rx_buf[32]; while(1){ uint8_t res = Int_SI24R1_RxPacket(rx_buf); if (res == 0){ printf("Comm_Task: %s\n", rx_buf); } }

最终效果:

http://www.cnnetsun.cn/news/43062.html

相关文章:

  • 无需运动恢复结构(SfM)的层级训练三维高斯溅射(3D Gaussian Splatting)
  • CS配合CrossC2插件,实现MacOS/Linux上线
  • 4、Puppet 入门:从基础使用到主从架构搭建
  • 线性代数(五)向量空间与子空间
  • matlab debug 调试程序
  • VibeVoice-Large-Q8:语音模型存储与性能的革命性突破——8位选择性量化技术深度解析
  • 腾讯开源双引擎AI模型:混元3D开创多模态创作新纪元,千倍效率革命重塑数字内容生产
  • Csharp学习笔记——常用类、集合框架、泛型、字典精华总结
  • 下载神器downkyi:5分钟掌握任务优先级管理技巧
  • 63.测试策略-领域模型测试集成测试实操方法-附测试框架选择
  • 1.2 主流大模型初探:解锁OpenAI、Gemini、Claude的强大能力
  • Ring-mini-linear-2.0:融合线性注意力与稀疏专家的下一代高效大语言模型
  • MFC消息处理机制
  • 商业级图像合成引擎6.0版本重磅发布:解锁跨场景视觉创作新范式
  • MyBatis-Plus与Spring整合(02--Service的代理)
  • 11、渗透测试实战:目标探索、利用与攻击行动
  • 16、攻击收尾:报告与撤离
  • 20、树莓派的替代项目探索
  • 事件查看器-事件ID
  • 单步出图革命:Consistency Model如何以100倍效率重构AI绘画产业格局
  • 搭建鸿蒙PC命令行适配环境测试hello程序
  • 编辑相似度(Edit Similarity):原理、演进与多模态扩展
  • 【深度解析】MiniCPM 2.0:端侧大模型的技术性进展与技术革新
  • ClickHouse 快速入门
  • 基于SpringBoot的人事管理系统设计与实现
  • 【论文阅读】Multi-modal Spatial Clustering for Spatial Transcriptomics Utilizing High-resolution Histology
  • Day36官方文档的阅读
  • Windows右键菜单终极优化指南:让你的右键菜单重获新生
  • ZTools v1.1.2:桌面应用启动器与搜索工具
  • Flutter Android APK 重命名 签名验证操作