TI CC2530组网演练(BasicRF 您所在的位置:网站首页 zigbee终端节点发送LED TI CC2530组网演练(BasicRF

TI CC2530组网演练(BasicRF

2024-06-11 09:16| 来源: 网络整理| 查看: 265

本文将从两个方面着手,一方面分析TI官网下载的CC2530 BasicRF源码中的无线发送,另一方面根据自己的板子来修改实现无线发送控制灯的亮灭。

一、CC2530 BasicRF

Basic RF由TI公司提供,它包含了IEEE 802.15.4标准的数据包的收发功能但并没有使用到协议栈,它仅仅是让两个节点进行简单的通信,也就是说Basic RF仅仅是包含着IEEE 802.15.4标准的一小部分而已。其主要特点有:

1、不会自动加入协议、也不会自动扫描其他节点、同时也没有组网指示灯(LED3)

2、没有协议栈里面所说的协调器、路由器或者终端的区分,节点的地位都是相等的

3、没有自动重发的功能

Basic RF layer为双向无线通信提供了一个简单的协议,通过这个协议能够进行数据的发送和接收。Basic RF还提供了安全所使用的CCM-64身份验证和数据加密,它的安全性在工程文件里定义SECURITY_CCM了。在Project->Option->C/C++ Compiler->Preprocess里面就选择,本次实验并不是什么高度机密,所有在SECURITY_CCM前面带X了。

Basic RF的工作过程:启动、发射、接收

工程文件分析

宏:

MCU_IO_DIR_OUTPUT(port, pin);

/*********************************************************************** * MCU_IO_DIR_OUTPUT(port, pin);将端口port对应的pin位设置为输出(高电平) * ##为连接符,如port=0,pin=1,即P0DIR |= BM(1); **********************************************************************/ #define MCU_IO_DIR_OUTPUT(port, pin) MCU_IO_DIR_OUTPUT_PREP(port, pin) #define MCU_IO_DIR_OUTPUT_PREP(port, pin) st( P##port##DIR |= BM(pin); ) #define st(x) do { x } while (__LINE__ == -1) #define BM(n) (1 this is a critical region // Critical region start halIntOff(); memcpy(pRxData, rxi.pPayload, min(rxi.length, len)); if(pRssi != NULL) { if(rxi.rssi < 128){ *pRssi = rxi.rssi - halRfGetRssiOffset(); } else{ *pRssi = (rxi.rssi - 256) - halRfGetRssiOffset(); } } rxi.isReady = FALSE; halIntOn(); // Critical region end return min(rxi.length, len); } uint8 basicRfSendPacket(uint16 destAddr, uint8* pPayload, uint8 length) { uint8 mpduLength; uint8 status; // Turn on receiver if its not on if(!txState.receiveOn) { halRfReceiveOn(); } // Check packet length length = min(length, BASIC_RF_MAX_PAYLOAD_SIZE); // Wait until the transceiver is idle halRfWaitTransceiverReady(); // Turn off RX frame done interrupt to avoid interference on the SPI interface halRfDisableRxInterrupt(); mpduLength = basicRfBuildMpdu(destAddr, pPayload, length); #ifdef SECURITY_CCM halRfWriteTxBufSecure(txMpdu, mpduLength, length, BASIC_RF_LEN_AUTH, BASIC_RF_SECURITY_M); txState.frameCounter++; // Increment frame counter field #else halRfWriteTxBuf(txMpdu, mpduLength); #endif // Turn on RX frame done interrupt for ACK reception halRfEnableRxInterrupt(); // Send frame with CCA. return FAILED if not successful if(halRfTransmit() != SUCCESS) { status = FAILED; } // Wait for the acknowledge to be received, if any if (pConfig->ackRequest) { txState.ackReceived = FALSE; // We'll enter RX automatically, so just wait until we can be sure that the ack reception should have finished // The timeout consists of a 12-symbol turnaround time, the ack packet duration, and a small margin halMcuWaitUs((12 * BASIC_RF_SYMBOL_DURATION) + (BASIC_RF_ACK_DURATION) + (2 * BASIC_RF_SYMBOL_DURATION) + 10); // If an acknowledgment has been received (by RxFrmDoneIsr), the ackReceived flag should be set status = txState.ackReceived ? SUCCESS : FAILED; } else { status = SUCCESS; } // Turn off the receiver if it should not continue to be enabled if (!txState.receiveOn) { halRfReceiveOff(); } if(status == SUCCESS) { txState.txSeqNumber++; } #ifdef SECURITY_CCM halRfIncNonceTx(); // Increment nonce value #endif return status; } 二、无线控制灯的亮灭

实现:通过按S1键来控制另一个板子上的LED1灯的亮灭

1、电路原理图

2、分析

既然要实现通过按S1键来控制另一个板子上的LED1灯的亮灭,那么首先需要将被控制版上的LED1对应的P1_0设置为输出模式,且当P1_为低电平时LED1等亮,为高电平时LED1等灭。以及将控制板上的S1对应的P0_4设置为输入模式,当检测到P0_4引脚为低电平表示按键S1被按下,反之为高电平时表示按键S1没有被按下。由于CC2530中的无线发送功能是内置的,不是外设,即TI官网下载的CC2530 BasicRF中的无线发送代码仍然适合我的板子,不需要怎么修改。这样,将按键S1端作为无线发送的发送端,而LED1端作为无线发送的接收端。

根据上面的代码分析,来实现自己的无线点灯,代码修改如下:

(1)、首先根据上面的分析,可以知道TI官网的CC2530 BasicRF中有4个LED,其分别是P0_0、P1_1、P1_4、P0_1,而我的板子中有个两个LED灯,分别是LED1(P1_0)、LED2(P1_1)。所有需要修改LED1的引脚定义,修改hal_board.h对应LEDs的引脚定义处。

修改前:

// LEDs #define HAL_BOARD_IO_LED_1_PORT 0 // Green #define HAL_BOARD_IO_LED_1_PIN 0 #define HAL_BOARD_IO_LED_2_PORT 1 // Red #define HAL_BOARD_IO_LED_2_PIN 1 #define HAL_BOARD_IO_LED_3_PORT 1 // Yellow #define HAL_BOARD_IO_LED_3_PIN 4 #define HAL_BOARD_IO_LED_4_PORT 0 // Orange #define HAL_BOARD_IO_LED_4_PIN 1 修改后:

// LEDs #define HAL_BOARD_IO_LED_1_PORT 1 // Green******************LED1 #define HAL_BOARD_IO_LED_1_PIN 0 #define HAL_BOARD_IO_LED_2_PORT 1 // Red********************LED2 #define HAL_BOARD_IO_LED_2_PIN 1 #define HAL_BOARD_IO_LED_3_PORT 1 // Yellow #define HAL_BOARD_IO_LED_3_PIN 4 #define HAL_BOARD_IO_LED_4_PORT 0 // Orange #define HAL_BOARD_IO_LED_4_PIN 1(2)、首先根据上面的分析,可以知道TI官网的CC2530 BasicRF中有1个按键S1,对应的引脚为P0_1,而我板子上的按键S1引脚为P0_4。所有需要修改LED1的引脚定义,修改hal_board.h对应Buttons的引脚定义处。

修改前:

// Buttons #define HAL_BOARD_IO_BTN_1_PORT 0 // Button S1 #define HAL_BOARD_IO_BTN_1_PIN 1 修改后:

// Buttons #define HAL_BOARD_IO_BTN_1_PORT 0 // Button S1 #define HAL_BOARD_IO_BTN_1_PIN 4(3)、将板子的LED1和LED2灯,设置为关闭状态,修改light_switch.c的main函数,在halLedSet(1)上面添加一行代码:halLesSet(2);

halLedSet(2); //关闭LED2 halLedSet(1); //关闭LED1(4)、根据上面的light_switch.c中的appSwitch()函数分析,在其函数内死循环中,它是去判断多方向按键是否按下,而实际需要判断自己板子的单方向按键是否按下。 修改前:

while (TRUE) { if( halJoystickPushed() ) { //判断多方向按键是否按下 basicRfSendPacket(LIGHT_ADDR, pTxData, APP_PAYLOAD_LENGTH);//发送命令 // Put MCU to sleep. It will wake up on joystick interrupt halIntOff(); halMcuSetLowPowerMode(HAL_MCU_LPM_3); // Will turn on global // interrupt enable halIntOn(); } } 修改后:

while (TRUE) { //if( halJoystickPushed() ) { //判断多方向按键是否按下 if (halButtonPushed()){ basicRfSendPacket(LIGHT_ADDR, pTxData, APP_PAYLOAD_LENGTH);//发送命令 // Put MCU to sleep. It will wake up on joystick interrupt halIntOff(); halMcuSetLowPowerMode(HAL_MCU_LPM_3); // Will turn on global // interrupt enable halIntOn(); } }(5)、将 light_switch.c中的main函数中一些有关lcd屏的操作、模式选择、等待用户按键等代码注释掉,注释如下:

#if 0 // Print Logo and splash screen on LCD utilPrintLogo("Light Switch"); //有关LCD的函数不管 // Wait for user to press S1 to enter menu while (halButtonPushed()!=HAL_BUTTON_1); halMcuWaitMs(350); halLcdClear(); //lcd清屏,不用管 // Set application role appMode = appSelectMode(); //模式选择 halLcdClear(); // Transmitter application if(appMode == SWITCH) { // No return from here appSwitch(); } // Receiver application else if(appMode == LIGHT) { // No return from here appLight(); } #endif(7)、根据是控制端(按键端)还是终端(LED灯端),在main函数添加不同函数。如果是将程序下载到控制端板子上,在main函数HAL_ASSERT(FLASE)上方添加appSwitch()函数,而如果是将程序下载到终端板子上,在main函数HAL_ASSERT(FLASE)上方添加appLight()函数。

控制端:

appSwitch(); // Role is undefined. This code should not be reached HAL_ASSERT(FALSE); 终端:

appLight(); // Role is undefined. This code should not be reached HAL_ASSERT(FALSE);

准备就绪

按下S1



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有