解包”CC2530 BasicRF(TI 原文件).rar”到C:盘.
1) 无线点灯:
双击打开"C:\CC2530 BasicRF\CC2530 BasicRF\ide\srf05_cc2530\iar\light_switch.eww"
打开后,可以看出整个工程由5个目录组成.
application: 应用程序, 即这里的代码是基于调用其它目录里提供的功能实现的
basic rf: 最基本功能的zigbee网络协议栈. 如无线网络数据的发送与接收.
hal(Hardware abstraction layer): 把SOC里的硬件功能封装起来,开发人员可以通过标准的函数来操作硬件。
就像Linux内核里的gpio操作一样,只要通过gpio_set_value(…)来设置IO口的电平而无须关心寄存器的配置.
utilities: 提供一些辅助功能,如lcd输出
output: 编译输出的路径。
打开basic rf目录里的basic_rf.h头文件:
typedef struct {
uint16 myAddr; //相当于本机的ip地址
uint16 panId; //这个非常重要,相当局域网的网段。注意不能有多个协调器共用一个panId.
uint8 channel; //RF通道(必须在11-26之间) 表示不同的频段从(2405 – 2480)MHz
uint8 ackRequest; //是否需要确认信号
#ifdef SECURITY_CCM //加密模式才会用到
uint8* securityKey;
uint8* securityNonce;
#endif
} basicRfCfg_t; //不管发送端还是接收到都需要用此结构体对象来指定本机的设置.
发送端,接收端的工作流程:
INSTRUCTIONS:
Startup:
1. Create a basicRfCfg_t structure, and initialize the members:
2. Call basicRfInit() to initialize the packet protocol.
Transmission:
1. Create a buffer with the payload to send
2. Call basicRfSendPacket()
Reception:
1. Check if a packet is ready to be received by highger layer with basicRfPacketIsReady()
uint8 basicRfPacketIsReady(void); //检查是否已接收到数据包.
2. Call basicRfReceive() to receive the packet by higher layer
basicrf里的函数:
uint8 basicRfInit(basicRfCfg_t* pRfConfig);
//指定本机的设置
uint8 basicRfSendPacket(uint16 destAddr, uint8* pPayload, uint8 length);
// destAddr指发送到哪个地址的设备(即目标ip地址), pPayload表示要发出的数据缓冲区地址, length表示发出的数据长度
uint8 basicRfPacketIsReady(void);
//检查是否已接收到数据包, 返回非0值表示已接收到.
int8 basicRfGetRssi(void); //检查当前使用的数据通道的流量状况,值越大表示越忙
uint8 basicRfReceive(uint8* pRxData, uint8 len, int16* pRssi);
//接收数据的处理
void basicRfReceiveOn(void); //打开接收数据的功能
void basicRfReceiveOff(void); //关闭数据接收的功能
//
在application目录里的light_switch.c就是基于一份代码,实现一个zigbee模块作开关通过无线网络控制另一模块作的灯。
也就是开关模块作网络的发送端, 灯的模块作网络的接收端.
基于原厂代码改成发送端的两个按钮分别控制另一模块的两个led灯.
/***********************************************************************************
* INCLUDES
*/
#include <hal_lcd.h>
#include <hal_led.h>
#include <hal_joystick.h>
#include <hal_assert.h>
#include <hal_board.h>
#include <hal_int.h>
#include "hal_mcu.h"
#include "hal_button.h"
#include "hal_rf.h"
#include "util_lcd.h"
#include "basic_rf.h"
/***********************************************************************************
* CONSTANTS
*/
// Application parameters
#define RF_CHANNEL 25 // 2.4 GHz RF channel
// BasicRF address definitions
#define PAN_ID 0x2007
#define SWITCH_ADDR 0x2520
#define LIGHT_ADDR 0xBEEF
#define APP_PAYLOAD_LENGTH 1
#define LIGHT1_TOGGLE_CMD 0
#define LIGHT2_TOGGLE_CMD 1
// Application states
#define IDLE 0
#define SEND_CMD 1
// Application role
#define NONE 0
#define SWITCH 1
#define LIGHT 2
#define APP_MODES 2
/***********************************************************************************
* LOCAL VARIABLES
*/
static uint8 pTxData[APP_PAYLOAD_LENGTH];
static uint8 pRxData[APP_PAYLOAD_LENGTH];
static basicRfCfg_t basicRfConfig;
/***********************************************************************************
* LOCAL FUNCTIONS
*/
static void appLight();
static void appSwitch();
static uint8 appSelectMode(void);
static void appLight()
{
// Initialize BasicRF
basicRfConfig.myAddr = LIGHT_ADDR;
if(basicRfInit(&basicRfConfig)==FAILED) {
HAL_ASSERT(FALSE);
}
basicRfReceiveOn();
// Main loop
while (TRUE) {
while(!basicRfPacketIsReady());
if(basicRfReceive(pRxData, APP_PAYLOAD_LENGTH, NULL)>0) {
if(pRxData[0] == LIGHT1_TOGGLE_CMD) {
halLedToggle(1);
}
if(pRxData[0] == LIGHT2_TOGGLE_CMD) {
halLedToggle(2);
}
}
}
}
static void appSwitch()
{
uint8 keys;
// Initialize BasicRF
basicRfConfig.myAddr = SWITCH_ADDR;
if(basicRfInit(&basicRfConfig)==FAILED) {
HAL_ASSERT(FALSE);
}
// Keep Receiver off when not needed to save power
basicRfReceiveOff();
// Main loop
while (TRUE) {
keys = halButtonPushed();
if(keys == HAL_BUTTON_1) {
halLedToggle(1);
pTxData[0] = LIGHT1_TOGGLE_CMD;
}
if(keys == HAL_BUTTON_2) {
halLedToggle(2);
pTxData[0] = LIGHT2_TOGGLE_CMD;
}
if (keys == HAL_BUTTON_NONE)
continue;
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();
}
}
void main(void)
{
uint8 appMode = NONE;
// Config basicRF
basicRfConfig.panId = PAN_ID;
basicRfConfig.channel = RF_CHANNEL;
basicRfConfig.ackRequest = TRUE;
// Initalise board peripherals
halBoardInit();
// Initalise hal_rf
if(halRfInit()==FAILED) {
HAL_ASSERT(FALSE);
}
// Indicate that device is powered
halLedSet(1); // LED1 on
appMode = SWITCH; //另一模块需要改成LIGHT再编译烧写
// Transmitter application
if(appMode == SWITCH) {
// No return from here
appSwitch();
}
// Receiver application
else if(appMode == LIGHT) {
// No return from here
appLight();
}
// Role is undefined. This code should not be reached
HAL_ASSERT(FALSE);
}
//也修改了halButtonPushed函数的功能,以支持两个按键
uint8 halButtonPushed(void)
{
uint8 v= HAL_BUTTON_NONE;
// Need to set direction because the button is shared with LED4 on SmartRF05EB rev 1.7+
MCU_IO_INPUT(HAL_BOARD_IO_BTN_1_PORT, HAL_BOARD_IO_BTN_1_PIN, MCU_IO_TRISTATE);
if (HAL_BUTTON_1_PUSHED() || HAL_BUTTON_1_PUSHED() || HAL_BUTTON_1_PUSHED()) {
HAL_DEBOUNCE(!HAL_BUTTON_1_PUSHED());
return HAL_BUTTON_1;
}
MCU_IO_INPUT(HAL_BOARD_IO_BTN_2_PORT, HAL_BOARD_IO_BTN_2_PIN, MCU_IO_TRISTATE);
if (HAL_BUTTON_2_PUSHED() || HAL_BUTTON_2_PUSHED() || HAL_BUTTON_2_PUSHED()) {
HAL_DEBOUNCE(!HAL_BUTTON_2_PUSHED());
return HAL_BUTTON_2;
}
return v;
}
注意:编译时需把Linker配置文件改为:”C:\Program Files\IAR Systems\Embedded Workbench 6.0 Evaluation\8051\config\devices\Texas Instruments\lnk51ew_cc2530F256.xcl”. 否则会报关于Linker的错误.