PIC32MM 移植 SX1280 驱动程序(含收发控制)
一、硬件连接基础(必须对齐的引脚)
SX1280采用SPI接口通信,和PIC32MM的最小连接要求如下:
| PIC32MM引脚 | SX1280引脚 | 功能说明 |
|---|---|---|
| SPI_SCK | SCK | SPI时钟 |
| SPI_MOSI | MOSI | 主机输出从机输入 |
| SPI_MISO | MISO | 主机输入从机输出 |
| GPIO_NSS | NSS | 片选信号(低电平有效) |
| GPIO_BUSY | BUSY | 忙状态检测(高电平表示芯片忙) |
| GPIO_DIO1 | DIO1 | 收发完成中断引脚 |
| 3.3V | VCC | 供电,必须稳定,避免射频发送时压降 |
| GND | GND | 共地 |
SPI时序必须匹配SX1280要求:CPOL=0、CPHA=0(模式0),时钟频率建议4MHz以内,避免通信错误。
二、核心收发控制代码逻辑
驱动核心由SX1280-HAL.c(硬件抽象层)和SX1280.c(业务控制层)组成,关键收发逻辑如下:
1. SPI底层读写适配(HAL层核心)
#include "mcc_generated_files/spi/spi2.h"
#include "mcc_generated_files/pin_manager.h"
/**
* @brief SPI读写函数,适配PIC32MM SPI2外设
* @param txBuffer 发送缓冲区
* @param rxBuffer 接收缓冲区
* @param size 传输长度
*/
void SpiInOut(uint8_t *txBuffer, uint8_t *rxBuffer, uint16_t size)
{
SPI2_Open(SPI2_DEFAULT);
NSS_SetLow(); // 拉低片选
SPI2_Exchange(txBuffer, rxBuffer, size);
NSS_SetHigh(); // 拉高片选释放总线
SPI2_Close();
}
/**
* @brief 等待SX1280 BUSY脚释放
*/
void SX1280HalWaitOnBusy(void)
{
while(BUSY_GetValue() == 1) // 忙状态阻塞等待
{
// 可根据需求添加超时退出逻辑
}
}
2. LoRa发送控制流程
/**
* @brief LoRa模式发送数据
* @param payload 待发送数据缓冲区
* @param size 发送长度(最大255字节)
*/
void SX1280_LoRaTx(uint8_t *payload, uint8_t size)
{
SX1280HalWaitOnBusy();
// 1. 设置数据包类型
uint8_t setPacketTypeCmd[] = {0x8A, 0x01}; // 0x01为LoRa模式
SpiInOut(setPacketTypeCmd, NULL, 2);
// 2. 配置调制参数:SF7、BW 1600kHz、CR 4/5
uint8_t setModulationCmd[] = {0x8B, 0x70, 0x0A, 0x01};
SpiInOut(setModulationCmd, NULL, 4);
// 3. 配置发射参数:20dBm发射功率
uint8_t setTxParamCmd[] = {0x8E, 0x1F, 0x00};
SpiInOut(setTxParamCmd, NULL, 3);
// 4. 写入发送缓冲区(偏移量0)
uint8_t writeBufCmd[size+3];
writeBufCmd[0] = 0x0E;
writeBufCmd[1] = 0x00; // 偏移量高位
writeBufCmd[2] = 0x00; // 偏移量低位
memcpy(writeBufCmd+3, payload, size);
SpiInOut(writeBufCmd, NULL, size+3);
// 5. 启动发射,超时时间10秒
uint8_t setTxCmd[] = {0x83, 0x00, 0x03, 0xE8};
SpiInOut(setTxCmd, NULL, 4);
// 6. 等待DIO1中断触发(发射完成)
while(DIO1_GetValue() == 0);
// 清除中断标志
uint8_t clearIrqCmd[] = {0x97, 0x00, 0x00, 0x00, 0x00};
SpiInOut(clearIrqCmd, NULL, 5);
}
3. LoRa接收控制流程
/**
* @brief LoRa模式接收数据
* @param rxBuffer 接收缓冲区
* @return 接收到的数据长度,0表示无数据
*/
uint8_t SX1280_LoRaRx(uint8_t *rxBuffer)
{
SX1280HalWaitOnBusy();
// 1. 进入连续接收模式
uint8_t setRxCmd[] = {0x82, 0x00, 0x03, 0xE8};
SpiInOut(setRxCmd, NULL, 4);
// 2. 等待DIO1中断触发(收到数据包)
if(DIO1_GetValue() == 1)
{
// 3. 获取接收状态,读取包长度
uint8_t getStatusCmd[] = {0x15, 0x00, 0x00};
uint8_t statusBuf[3];
SpiInOut(getStatusCmd, statusBuf, 3);
uint8_t rxLen = statusBuf[1]; // 包长度
// 4. 读取接收缓冲区
uint8_t readBufCmd[3] = {0x1E, 0x00, 0x00};
SpiInOut(readBufCmd, rxBuffer, rxLen);
// 5. 清除中断标志
uint8_t clearIrqCmd[] = {0x97, 0x00, 0x00, 0x00, 0x00};
SpiInOut(clearIrqCmd, NULL, 5);
return rxLen;
}
return 0;
}
参考代码 PIC32MM移植的SX1280驱动程序,收发控制 www.youwenfan.com/contentcst/182652.html
三、调试避坑指南
- SPI通信通断验证:先调用
GetFirmwareVersion()接口读取SX1280固件版本号,正常返回0xA9B7,不通则检查SPI时序和BUSY脚逻辑 - 电源稳定性要求:必须使用输出电流≥300mA的3.3V LDO供电,射频发射瞬间峰值电流可达100mA以上,电源纹波大会导致通信不稳定
- 中断优先级配置:DIO1接收中断优先级建议高于普通外设中断,避免丢包
- 低功耗优化:空闲时可配置SX1280进入休眠模式,通过唤醒引脚或DIO中断唤醒,待机电流可低至2μA