13_multipipe 多通道通信例程¶
一、简介¶
本例程演示 PAN211 芯片的多通道通信功能,包含发送端和接收端两部分。发送端在6个通道上轮流发送数据,接收端可以同时监听6个通道的数据。
二、条件说明¶
芯片工作模式:PAN211_CHIPMODE_XN297
CRC:2字节
数据速率:1Mbps
SPI类型:3线SPI
通道数量:6个
通道地址:
通道0:{0xC0, 0xCC, 0xCC, 0xCC, 0xCC}
通道1:{0xC1, 0xCC, 0xCC, 0xCC, 0xCC}
通道2:{0xC2, 0xCC, 0xCC, 0xCC, 0xCC}
通道3:{0xC3, 0xCC, 0xCC, 0xCC, 0xCC}
通道4:{0xC4, 0xCC, 0xCC, 0xCC, 0xCC}
通道5:{0xC5, 0xCC, 0xCC, 0xCC, 0xCC}
数据长度:32字节
工作模式:增强型
发送功率:9dBm
发送间隔:500ms
三、接口(移植)实现¶
根据硬件实现以下配置:
SPI_CS引脚配置为推挽输出
SPI_SCK引脚配置为推挽输出
SPI_DATA引脚配置为推挽输出或输入模式,低功耗模式下需配置为输入模式并启用上拉电阻
#define SPI_CS_HIGH CS_PIN = 1 /* 将SPI_CS引脚设置为高电平 */
#define SPI_CS_LOW CS_PIN = 0 /* 将SPI_CS引脚设置为低电平 */
#define SPI_SCK_HIGH SCK_PIN = 1 /* 将SPI_SCK引脚设置为高电平 */
#define SPI_SCK_LOW SCK_PIN = 0 /* 将SPI_SCK引脚设置为低电平 */
#define SPI_DATA_HIGH DATA_PIN = 1 /* 将SPI_DATA引脚设置为高电平 */
#define SPI_DATA_LOW DATA_PIN = 0 /* 将SPI_DATA引脚设置为低电平 */
#define SPI_DATA_STATUS DATA_PIN /* 读取SPI_DATA引脚状态 */
#define SPI_DATA_OUTPUT GPIO_SetModeByPin(P4_3, GPIO_MODE_OUTPUT) /* 配置SPI_DATA引脚为输出模式 */
#define SPI_DATA_INPUT GPIO_SetModeByPin(P4_3, GPIO_MODE_INPUT) /* 配置SPI_DATA引脚为输入模式 */
根据实际使用的MCU修改SPI接口初始化代码:
/**
* @brief 初始化PAN211 3线SPI接口
* @param 无
* @return 无
* @note 该函数配置SPI_SCK、SPI_CS和SPI_DATA引脚为GPIO模式,并设置为输出模式
* @note PAN211没有独立中断引脚,可开启SPI_DATA引脚中断复用功能
* @note PAN216具有独立中断引脚,可通过P4_5来检测PAN216的中断事件
*/
void BSP_3LineSPIInit(void)
{
CLK_AHBPeriphClockCmd(CLK_AHBPeriph_GPIO, ENABLE);
// 将引脚配置为GPIO模式,以软件SPI实现
SYS_ConfigMFP(P4_0, SYS_MFP_GPIO); // SPI_SCK
SYS_ConfigMFP(P4_1, SYS_MFP_GPIO); // SPI_CS
SYS_ConfigMFP(P4_3, SYS_MFP_GPIO); // SPI_DATA
SYS_ConfigMFP(P4_5, SYS_MFP_GPIO); // IRQ引脚,PAN211未使用
GPIO_SetModeByPin(P4_1, GPIO_MODE_OUTPUT); // 配置SPI_CS为输出模式
GPIO_SetModeByPin(P4_0, GPIO_MODE_OUTPUT); // 配置SPI_SCK为输出模式
GPIO_SetModeByPin(P4_3, GPIO_MODE_OUTPUT); // 配置SPI_DATA为输出模式,后续根据时序需要设置为输入模式
GPIO_SetModeByPin(P4_5, GPIO_MODE_INPUT); // PAN211没有中断引脚,PAN216有中断引脚,配置为输入模式
P41 = 1; // SPI_CS置高,表示未选中
P40 = 0; // SPI_SCK置低,SPI时钟极性为低电平有效
P43 = 0; // SPI_DATA置低
GPIO_EnablePullupPath(P4, BIT3); // 将SPI_DATA引脚设置为输入模式,并启用上拉电阻
}
四、应用范例¶
1、发送端配置¶
int main(void)
{
/* MCU 初始化 */
if (PAN211_Init() != 1) /* 初始化&校准 PAN211 芯片 */
{
printf("PAN211 init failed.\r\n");
while (1);
}
/* (可选)读取 TX_NOACK 标志 */
TxNoAck = (PAN211_ReadReg(0x07) & 0x02) > 0 ? 1 : 0;
printf("XN297 multipipe tx test start.\r\n");
while (1)
{
/* PipeIndex值的变化规律:0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 0 -> 1 -> 2 ... */
PAN211_SetTxAddr(AddressList[PipeIndex], 5); /* 将既定的通道地址写入PAN211 */
PipeIndex = (PipeIndex + 1) % 6;
PAN211_WriteFIFO(TxBuf, sizeof(TxBuf)); /* 将待发送的数据写入PAN211 TX FIFO */
PAN211_TxStart(); /* PAN211进入发送状态并开始送数据 */
/* 等待发送完成并处理中断 */
while (1)
{
while (!IRQDetected()); /* 等待SPI_DATA/IIC_SDA引脚变低,指示发送完成 */
IRQFlag = PAN211_GetIRQFlags(); /* 获取中断标志 */
if (IRQFlag & RF_IT_TX_IRQ) /* 发送中断 */
{
PAN211_ClearIRQFlags(RF_IT_TX_IRQ); /* 清除发送中断标志 */
printf(">> RF_IT_TX_IRQ[0x%02X].%d\r\n", IRQFlag, ++TxCount);
break;
}
}
BSP_Led2Toggle(); /* 切换LED2状态 */
BSP_DelayMs(500); /* 延时500ms后再发送下一包数据 */
}
}
2、接收端配置¶
int main(void)
{
/* MCU 初始化 */
if (PAN211_Init() != 1) /* 初始化&校准 PAN211 芯片 */
{
printf("PAN211 init failed.\r\n");
while (1);
}
/* (可选)读取 TX_NOACK 标志 */
TxNoAck = (PAN211_ReadReg(0x07) & 0x02) > 0 ? 1 : 0;
PAN211_RxStart(); /* 进入接收模式 */
printf("XN297 multipipe rx test start.\r\n");
while (1)
{
while (!IRQDetected()); /* 等待SPI_DATA/IIC_SDA引脚变低,指示发送完成 */
IRQFlag = PAN211_GetIRQFlags(); /* 获取中断标志 */
if (IRQFlag & RF_IT_RX_IRQ) /* 接收中断 */
{
unsigned char PipeNum;
unsigned char RxLen;
PipeNum = PAN211_GetRxPipeNum(); /* 获取接收数据的管道号 */
RxLen = PAN211_GetRecvLen(); /* 获取接收数据长度 */
if (TxNoAck == 0) /* 如果需要回应ACK数据 */
{
PAN211_SetAckPipeNum(PipeNum); /* 设置ACK数据的管道号 */
PAN211_WriteFIFO(TxBuf, sizeof(TxBuf)); /* 将待发送的ACK数据写入PAN211 FIFO */
}
PAN211_ReadFIFO(RxBuf, RxLen); /* 读取FIFO数据到RxBuf缓冲区 */
PAN211_ClearIRQFlags(RF_IT_RX_IRQ); /* 清除接收中断标志 */
printf("Rx[%d] on pipe %d\r\n", ++RxCount, PipeNum); /* 打印接收计数 */
BSP_Led3Toggle(); /* 切换LED3状态 */
}
}
}
五、例程演示¶
使用步骤:
找到两块PAN211x开发板,分别作为发送端和接收端。
用Type-C数据线供电。
用跳线帽连接电源跳线P9。
将电源切换开关S1切换至“USB”端。
将发送端和接收端的代码分别烧录到两块开发板上。
打开串口调试助手,设置波特率为115200,数据位8位,无校验位,停止位1位,分别选择发送端和接收端的串口,点击连接。
观察串口调试助手,发送端会在6个通道上轮流发送数据,接收端会同时监听6个通道并打印接收到的数据。
普通型发送端日志示例:
Tx Count = 1
Tx Count = 2
Tx Count = 3
普通型接收端日志示例:
Rx on pipe 0, Rx Count = 1
+RxHexData:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
增强型发送端日志示例:
>> RF_IT_TX_IRQ[0x80].1
>> RF_IT_RX_IRQ[0x01].
Rx on pipe 0
+RxLen = 32, Rx Count = 1
+RxHexData:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
增强型接收端日志示例:
Rx[101] on pipe 5
+RxLen = 32, Tx Count = 101
+RxHexData:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
>> RF_IT_TX_IRQ[0x80].