SI4438可变长包数据收发

最近在项目止采用SI4438作为无线通信。采用的是wds内的长包发送模板,用的中断为TX_FIFO_EMPTY和RX_FIFO_FULL两个中断。但是在实际应用中却出现了问题。程序内包长设置的是255字节(项目需要最长为255字节)。由于数据发送较为频繁,即使主机发送7字节数据,从机也会进入5次RX_FIFO_FULL中断,已经影响到了从机其它任务的正常运行。

经分析,此问题存在的根源是,从机每次均按255字节接收,不知道主机所实际传输的字节是多少。后面经查资料,WDS内有可变长包发送的这个功能,所以就进行了程序修改和测试。

具体实现方法如下:

首先配置好WDS的软件,按界面生成如下的工程模板,将radio_config_Si4438.h生成。具体配置如下(具体配置情况以个人为准,此截图仅为本人用):

SI4438可变长包数据收发_第1张图片SI4438可变长包数据收发_第2张图片SI4438可变长包数据收发_第3张图片SI4438可变长包数据收发_第4张图片SI4438可变长包数据收发_第5张图片SI4438可变长包数据收发_第6张图片SI4438可变长包数据收发_第7张图片SI4438可变长包数据收发_第8张图片

WDS配置好了,生成了radio_config_Si4438.h这个文件,放到工程里替换。

接下来是程序的配置:

一、变长包数据收发格式

/*第一字节是长度,后面是数据。实际写入到TX FIFO发送的数据是9字节 = 负载数据8字节+数据长度1字节*/

变长包的格式是:0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08;

二、接收

SI4438的接收和发送是相对独立的,同一时间内只能接收或者只能发送。


转换到接收状态部分程序

void vRadio_StartRX(U8 channel)
{
  /*清除中断标记*/
  si446x_get_int_status(0u, 0u, 0u);
  /*清空RX FIFO*/
  si446x_fifo_info(SI446X_CMD_FIFO_INFO_ARG_FIFO_RX_BIT); 

  /*由于start TX和 start RX命令中的length长度不再起作用,实际需要收发的数据长度由对应的field length寄存器来控制,field1一直代表数据包的长度,收发都是一个字节来表示长度,因此不需要修改field1 length寄存器。修改field2 length的代码如下 */

/*以下程序为指定最长的接收长度  最后一位为目前的长度,设置为255(尽量设置长,目前自测试最长到255,此为最长接收字节。实际接收字节由filed2自动获取)*/ 

si446x_set_property(0x12,0x02,0x11,0x00,0xFF);

  /* Start Receiving packet, channel 0, START immediately, Packet length according to PH */
  si446x_start_rx(channel, 0u, 0u,
                  SI446X_CMD_START_RX_ARG_NEXT_STATE1_RXTIMEOUT_STATE_ENUM_NOCHANGE,
                  SI446X_CMD_START_RX_ARG_NEXT_STATE2_RXVALID_STATE_ENUM_READY,
                  SI446X_CMD_START_RX_ARG_NEXT_STATE3_RXINVALID_STATE_ENUM_RX );

}

接收部分中断

在接收及长包中断处理中,以LongPacket Rx为模板为准,完成接收部分的长包接收部分的程序

三、发送

发送函数如下构成,主要是参照LongPacket Tx模板实现的,主要是对发送的数据长度进行实际区分。如果大于TX FIFO,则分包传输。小于TX FIFO,则一次性传输。

void SI4438_Send(uint8_t *dat,uint8_t length)
{
PacketTxData.length = length+1;
PacketTxData.buf[0] = length;
memcpy(PacketTxData.buf+1,dat,length);      //将数据结构按照无线传输结构去打包 
/*复位TX FIFO*/
si446x_fifo_info(SI446X_CMD_FIFO_INFO_ARG_FIFO_TX_BIT);
/*清除中断标记*/
si446x_get_int_status(0u, 0u, 0u);
/*将所传数据的首地址给指针*/
LongPacketData.pTxPositionInPayload = PacketTxData.buf; /*从数据的首地址开始*/
LongPacketData.NumTxPositionInPayload = 0; /*长度从0开始计算*/


/*要发送的字节长度 大于当前FIFO的空间(64字节)*/
if( RADIO_MAX_PACKET_LENGTH < PacketTxData.length)
{
/* 第一包发送FIFO定长的数据 */
si446x_write_tx_fifo(RADIO_MAX_PACKET_LENGTH, LongPacketData.pTxPositionInPayload);

/*计算发送了多少字节 */
LongPacketData.NumTxPositionInPayload += RADIO_MAX_PACKET_LENGTH;
/* 计算数组偏移 */
LongPacketData.pTxPositionInPayload += RADIO_MAX_PACKET_LENGTH;
/*长度>64*/
LongPacketData.TxlengthGet = 0;
}
else
{
/*未超过FIFO最大值(64字节) 则将所有字节发送出去*/
si446x_write_tx_fifo(PacketTxData.length,LongPacketData.pTxPositionInPayload);
/*长度<64*/
LongPacketData.TxlengthGet = 1;
}
/*需要发送的长度,放到field2 length寄存器中  要发送的长度由这里给出*/   
si446x_set_property(0x12,0x02,0x11,0x00,PacketTxData.length); 
/*立即发送 长度由field2 length决定*/
si446x_start_tx(SI4438Configure.Radio_TX_ChannelNumber, 0x00,  0x00);

}

发送部分中断处理

在发送及长包处理中断程序,以LongPacket Tx为模板为准,完成接收部分的长包接收部分中断的程序


经过以上调试,接收方在接收数据时,能够知道接收字节的长度。433模块会根据字节长度,进入中断。中断次数得到有效的控制。





你可能感兴趣的:(移动开发)