由于appLight()的主循环一直在等待 接收中断完成,一旦有接收中断并接收完成则进行后续的数据处理,因此这里主要介绍一下接收中断服务子函数basicRfRxFrmDoneIsr(该函数指针在basicRfInit()被声明,详细介绍参看上一篇),具体代码如下:

/***********************************************************************************

* @fn          basicRfRxFrmDoneIsr

*

* @brief       Interrupt service routine for received frame from radio

*              (either data or acknowlegdement)

*              //当无线信号有接收帧时执行中断服务子程序;

* @param      rxi - file scope variable info extracted from the last incoming

*                    frame

*              //最近一次接收帧信息;

*              txState - file scope variable that keeps tx state info

*              //发送状态信息,在中断服务子程序中主要在接收ACK中涉及;

* @return      none

*/

static void basicRfRxFrmDoneIsr(void)

{

basicRfPktHdr_t *pHdr;  //帧头结构体指针;

uint8 *pStatusWord;     //存储读RSSI和CRC信息;

#ifdef SECURITY_CCM

uint8 authStatus=0;

#endif

// Map header to packet buffer

//帧头指针指向 所接收的MPDU数据单元;

//结构体间的强制类型转换,起始地址的指向;

pHdr= (basicRfPktHdr_t*)rxMpdu;

// Clear interrupt and disable new RX frame done interrupt

//关闭通用RF中断 和 RXPKTDONE中断;

halRfDisableRxInterrupt();

// Enable all other interrupt sources (enables interrupt nesting)

//始能总中断;(考虑默认优先级 其他中断)

halIntOn();

// Read payload length.

//读取长度域的值;

halRfReadRxBuf(&pHdr->packetLength,1);

pHdr->packetLength &= BASIC_RF_PLD_LEN_MASK; // Ignore MSB

//最大程度为127字节,故忽略最高有效位;

// Is this an acknowledgment packet?

// Only ack packets may be 5 bytes in total.

//由于只有ACK帧的数据长度为5,所以可以通过 帧 长度来判断该帧的类型:数据帧 or 应答帧;

if (pHdr->packetLength == BASIC_RF_ACK_PACKET_SIZE) {

// Read the packet

//将接收数据 通过RFD从缓存中一个字节一个字节读出;

halRfReadRxBuf(&rxMpdu[1], pHdr->packetLength);

// Make sure byte fields are changed from network to host byte order

//将网络参数的高4位和低4位交换 ,由 无线网络格式 转换为 本地格式;

UINT16_NTOH(pHdr->panId);

UINT16_NTOH(pHdr->destAddr);

UINT16_NTOH(pHdr->srcAddr);

#ifdef SECURITY_CCM

UINT32_NTOH(pHdr->frameCounter);

#endif

//读取应答帧帧的应答位信息,对于应答帧的FCF该位应该为0;

rxi.ackRequest = !!(pHdr->fcf0 & BASIC_RF_FCF_ACK_BM_L);

// Read the status word and check for CRC OK

//指向该帧的FCS;

pStatusWord= rxMpdu + 4;

// Indicate the successful ACK reception if CRC and sequence number OK

//若CRC校验位和帧序号无误,则将txState.ackReceived 设置为 TRUE,表示数据发送及对方节点接收完成;

if ((pStatusWord[1] & BASIC_RF_CRC_OK_BM) && (pHdr->seqNumber == txState.txSeqNumber)) {

txState.ackReceived = TRUE;

}

// No, it is data

} else {

// It is assumed that the radio rejects packets with invalid length.

// Subtract the number of bytes in the frame overhead to get actual payload.

//在灯开关例程中,默认 非应答帧长度的数据 皆为有效数据,即:假定非有效数据都被拒绝(假定很恶劣= =!);如果传输的数据长度是固定的可以更换 固定的长度条件,其他 长度的无线数据都不进行处理;

//长度域的值减去(MHR+MFR)获得有效负载长度;

rxi.length = pHdr->packetLength - BASIC_RF_PACKET_OVERHEAD_SIZE;

#ifdef SECURITY_CCM

rxi.length -= (BASIC_RF_AUX_HDR_LENGTH + BASIC_RF_LEN_MIC);

authStatus = halRfReadRxBufSecure(&rxMpdu[1], pHdr->packetLength, rxi.length,

BASIC_RF_LEN_AUTH, BASIC_RF_SECURITY_M);

#else

halRfReadRxBuf(&rxMpdu[1], pHdr->packetLength); //将接收数据 通过RFD从缓存中一个字节一个字节读出;

#endif

// Make sure byte fields are changed from network to host byte order

//将网络参数的高4位和低4位交换 ,由 无线网络格式 转换为 本地格式;

UINT16_NTOH(pHdr->panId);

UINT16_NTOH(pHdr->destAddr);

UINT16_NTOH(pHdr->srcAddr);

#ifdef SECURITY_CCM

UINT32_NTOH(pHdr->frameCounter);

#endif

//读取该帧的应答位信息;

rxi.ackRequest = !!(pHdr->fcf0 & BASIC_RF_FCF_ACK_BM_L);

// Read the source address

//读取源地址;

rxi.srcAddr= pHdr->srcAddr;

// Read the packet payload

//读取净载荷数据;

rxi.pPayload = rxMpdu + BASIC_RF_HDR_SIZE;

// Read the FCS to get the RSSI and CRC

//读取帧校验中的RSSI和CRC相关信息;

pStatusWord= rxi.pPayload+rxi.length;

#ifdef SECURITY_CCM

pStatusWord+= BASIC_RF_LEN_MIC;

#endif

//读取RSSI的值;

rxi.rssi = pStatusWord[0];

// Notify the application about the received data packet if the CRC is OK

// Throw packet if the previous packet had the same sequence number

//根据CRC校验位来判定是否 为有效数据帧;

//其中,还要求对 帧序号 进行验证,如果该数据帧 要求有应答的情况下 在数据帧发送接收流程上不完整,帧序号连续两次相同的那么不对重复数据帧进行后续的处理,需要被丢弃;

//另外如果发送节点 确定数据被正确接收 可以采用连续发送两次,并根据 应答是否成功 来判断程序是否进行二次重复发送;

if( (pStatusWord[1] & BASIC_RF_CRC_OK_BM) && (rxi.seqNumber != pHdr->seqNumber) ) {

// If security is used check also that authentication passed

#ifdef SECURITY_CCM

if( authStatus==SUCCESS ) {

if ( (pHdr->fcf0 & BASIC_RF_FCF_BM_L) ==

(BASIC_RF_FCF_NOACK_L | BASIC_RF_SEC_ENABLED_FCF_BM_L)) {

rxi.isReady = TRUE;

}

}

#else

if ( ((pHdr->fcf0 & (BASIC_RF_FCF_BM_L)) == BASIC_RF_FCF_NOACK_L) ) {

rxi.isReady = TRUE;  //如果接收到的FCF满足无ACK位的条件,说明正确接收,将接收节点状态 设置为TRUE;

//其中BASIC_RF_FCF_NOACK_L = 0x61表示PANID一致而且该帧类型为 数据帧;

//数据帧的通过验证的判断条件:1.CRC = OK ;2.SeqNumber和上一次的不同;3.保持PANID 和 帧类型 一致;

}

#endif

}

//帧序号在灯开关例程作用:

//数据帧要求有应答的情况,应答成功→下一帧SeqNumber自加→(PANID 和 帧类型一致的条件下)下一帧进行的后期操作;然而 应答不成功→下一帧SeqNumber保持→rxi.isReady始终为FALSE下一帧无法进行后期处理,表现现象为对应节点发送的数据始终无法接收!

//数据帧要求无应答的情况,下一帧SeqNumber始终自加,不会造成对应节点发送的数据无法接收的问题;

//SeqNumber在灯开关例程作用始终是 ACK的成功与否来决定的,因此应该善于利用  ACK是否成功完成的条件!

rxi.seqNumber = pHdr->seqNumber;

}

// Enable RX frame done interrupt again

//关闭总中断,会在 basicRfReceive()中 复制完接收数据 后重新始能;

halIntOff();  //调用函数HAL_INT_OFF();

//#define HAL_INT_OFF(x)      st( EA = 0; )

//x的指向可以是空?

//始能通用RF中断 和 RXPKTDONE中断;

halRfEnableRxInterrupt();

}

BasicRF之中断接收basicRfRxFrmDoneIsr相关推荐

  1. STM32串口中断接收方式详细比较

    本例程通过PC机的串口调试助手将数据发送至STM32,STM32通过SP3232芯片采用中断接收方式完成,然后接收数据后将所接收的数据又发送至PC机. 实例一: void USART1_IRQHand ...

  2. STM32 HAL库 串口DMA(收发)和STM32串口中断接收(接收时间管理机制)+ESP8266 wifi模组通信问题

    一.HAL库 串口 DMA+ESP8266模组通信问题 用STM32 HAL库串口的DMA发送和空闲中断接收处理数据,单片机发送AT指令给ESP8266 wifi模组问题:单片机连续几次给wifi模组 ...

  3. bufferedreader接收不到数据_FreeRTOS例程3-串口中断接收不定长的数据与二值信号量的使用

    1 基础知识点 1.1 串口中断种类 串口中断属于STM32本身的资源,不涉及到FreeRTOS,但可与FreeRTOS配合使用. 串口接收中断 中断标志为:USART_IT_RXNE,即rx non ...

  4. STM32串口的使用(原理、结构体、库函数、串口发送字符(串)、重定向printf串口发送、串口中断接收控制灯)

    参考:串口的结构体 重定向printf串口发送stm32等博文 作者:点灯小哥 发布时间: 2021-03-06 21:46:33 网址:https://blog.csdn.net/weixin_46 ...

  5. STM32H743+CubeMX-串口非空闲中断接收

    文章目录 一.前言 二.CubeMX 2.1.选择串口 三.代码 3.1.main.c 3.2.stm32f7xx_it.c 相关笔记: STM32H743-串口重定向printf 一.前言 在实际工 ...

  6. stm32串口空闲中断接收不定长数据

    串口空闲中断接收不定长数据 空闲中断是接受数据后出现一个byte的高电平(空闲)状态,就会触发空闲中断.并不是空闲就会一直中断,准确的说应该是上升沿(停止位)后一个byte,如果一直是低电平是不会触发 ...

  7. STM32 利用空闲中断接收数据

    STM32 利用串口空闲中断接收不定长数据 利用cubeMX打开DMA串口接收中断 利用CubeMX打开串口中断 HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); HA ...

  8. stc 串口收发 c语言,STC12C5A60S2 串口中断接收程序

    原标题:STC12C5A60S2 串口中断接收程序 #define UART0_BUF_LEN 32 int UART1_Recv_count; //接收计数 bit UART1_Overflow_F ...

  9. STM32使用串口中断接收HWT101的数据

    因研究生阶段项目需求,需要采用HWT101给单片机提供角度信息. HWT101是维特智能公司下的一款角度传感器,它可以通过计算角速度测量绕Z轴旋转的水平方向的偏航角,具有高精度.几乎无漂移.不受磁场干 ...

最新文章

  1. 【2018-01-22】HTML-表单及表单元素
  2. easyui的combobox下拉框初始化默认值以及保持该值一直显示的方法
  3. android edittext标签,TagEditText,类似微博标签的文本控件
  4. Selenium java环境搭建
  5. javaScript实现字符串首字母大写
  6. 安徽省2019年普通高校招生文史、理工类最低控制分数线一览表
  7. [转]有关IIS的虚拟目录的控制总结
  8. 小型的网站服务器配置,中小型网站服务器配置参考
  9. RabbitMQ脑裂
  10. OpenShift安装
  11. selenium操作cookies实现免密登录,自动发微博
  12. 如何通过RFID开发来迎接第四次工业革命(转)
  13. Nginx访问403异常问题处理
  14. 使用 JavaScript,也能在 Web 应用中实现人脸检测功能?!
  15. 计算机二级b5纸是多大尺寸,两张b5纸是多大
  16. 利用R语言做可重复性报告研究
  17. 非晶金属模型建模:Ovito方法
  18. linux 中的3类驱动程序
  19. 数字信号处理原理及实现一书的思维导图
  20. (连载0.1)实践报告:在深度系统用Python3对上市公司年度报告财务报表进行提取

热门文章

  1. Opencv-python教程(6)——Thresholding OpenCV
  2. Word问题解决-双栏论文左下角作者简介信息的编辑-脚注
  3. 人生应该要有梦想,万一见鬼了呢?!
  4. java存钱_用Java编写一个简单的存款
  5. POJ3208:Apocalypse Someday
  6. 机器视觉有哪些定位算法?
  7. Linner和WebStorm前端开发环境搭建
  8. 返利机器人php,快速入门
  9. 树莓派安装Opencv+Contrib和 QT 详细教程
  10. 微信小程序周日历制作