找到 2 块 ZigBee 模块(蓝色),模拟员工餐厅区的远程灯光自动控制效果,考核选手点对点通讯知识。在“竞赛资料\任务 3\”中提供的工程代码中添加相应代码,实现如下功能:
复制一遍官方的Zigbee通用库, 里面有 CC2530_lib、Project文件夹。
简单介绍一下左边的这些文件夹
右边点对点通信的地址设置
这里只介绍该题用到的头文件(API).
typedef struct
{
uint16 myAddr; // 本机地址
uint16 panId; // 网络ID
uint8 channel; // 通信信道, 11~26
uint8 ackRequest; //应答信号
#ifdef SECURITY_CCM // 是否加密,预定义时取消了加密
uint8 *securityKey;
uint8 *securityNonce;
#endif
} basicRfCfg_t;
相关代码:
static basicRfCfg_t basicRfConfig;
/*****点对点通讯地址设置******/
#define RF_CHANNEL 24 // 频道 11~26
#define PAN_ID 0x8004 //网络id
#define MY_ADDR 0x2019 //本机模块地址
#define SEND_ADDR 0XBEED //发送地址
简述: 初始化点对点数据结构。在芯片中设置通道、短地址和PAN ID,并在数据包接收时配置中断。
参数: pRfConfig - basicRfCfg_t结构体作为参数传递。
在CC2530_lib中rf_set.c的ConfigRf_Init 函数中被调用。
返回值: 设置成功(真),设置失败(假)
// 无线RF初始化
void ConfigRf_Init(void)
{
basicRfConfig.panId = PAN_ID;
basicRfConfig.channel = RF_CHANNEL;
basicRfConfig.myAddr = MY_ADDR;
basicRfConfig.ackRequest = TRUE;
while(basicRfInit(&basicRfConfig) == FAILED); // 初始化点对点数据结构
basicRfReceiveOn(); // 开启接收中断
}
简述:开启无线接收中断。(每次都要开启)
简述:关闭无线接收中断。(关闭之后不再接收)
简述: 检查新数据包是否准备好供下一个更高层读取.
返回值: 有数据包(真),没有数据包(假)
简述: 将最后一个传入数据包的负载复制到缓冲区中。
参数:
相关代码:
#define APP_PAYLOAD_LEN 1 // 应用无线负载长度
#define RELAY_SET_CMD 1 // 继电器命令簇(命令集)
#define RELAY_CLEAR_CMD 0 // 主机(Master)要和从机(Slave)一致
static uint8 pTxData[APP_PAYLOAD_LEN]; // 无线发送缓存
static uint8 pRxData[APP_PAYLOAD_LEN]; // 无线接收缓存
while(1)
{
/* slave code start */
if( basicRfPacketIsReady() )
{
basicRfReceive(pRxData, APP_PAYLOAD_LEN, NULL);
if( pRxData[0] == RELAY_SET_CMD )
{
// 这两个函数在common文件夹下的hal_cc8051.h文件下
MCU_IO_OUTPUT(2, 0, 1); // 设置P2_0输出高电平继电器动作
MCU_IO_SET_HIGH_PREP(1, 0); // 设置P1_0输出高电平点亮LED2
}
else if( pRxData[0] == RELAY_CLEAR_CMD )
{
MCU_IO_OUTPUT(2, 0, 0); // 输出低电平继电器复位
MCU_IO_SET_LOW_PREP(1, 0); // LED2熄灭
}
else
{}
}
/* slave code end */
}
简述: 无线发包
参数:
返回值: basicRFStatus_t - SUCCESS or FAILED(一般不用)
相关代码:
uint16 lightness = 0;
while(1)
{
/* user code start */
if( appMode == MASTER ) // 主机代码
{
lightness = get_guangdian_ad(); // 获取光照值该函数在sensor.h中
if( lightness < 20 ) // 如果光照值小于20
{
pTxData[0] = RELAY_SET_CMD; // 继电器动作命令
basicRfSendPacket(SEND_ADDR, pTxData, APP_PAYLOAD_LEN); // 发包
}
else
{
pTxData[0] = RELAY_CLEAR_CMD; // 继电器复位
basicRfSendPacket(SEND_ADDR, pTxData, APP_PAYLOAD_LEN);
}
printf_str((char *)uTxData,"光照值%d",lightness); // sprintf()
halUartWrite(uTxData,strlen((char *)uTxData)); // 在hal_uart.c文件中,串口输出
}
#include "hal_defs.h"
#include "hal_cc8051.h"
#include "hal_int.h"
#include "hal_mcu.h"
#include "hal_board.h"
#include "hal_led.h"
#include "hal_rf.h"
#include "basic_rf.h"
#include "hal_uart.h"
#include "sensor_drv/sensor.h"
#include "TIMER.h"
#include
#include
#include
#include "UART_PRINT.h"
/*****点对点通讯地址设置******/
#define RF_CHANNEL 24 // 频道 11~26
#define PAN_ID 0x8004 //网络id
#define MY_ADDR 0x2019 //本机模块地址
#define SEND_ADDR 0XBEED //发送地址
#define NONE 0
#define MASTER 1
#define SLAVE 2
#define APP_PAYLOAD_LEN 1 // 应用无线负载长度
#define RELAY_SET_CMD 1
#define RELAY_CLEAR_CMD 0
/**************************************************/
static basicRfCfg_t basicRfConfig;
static uint8 pTxData[APP_PAYLOAD_LEN]; // 无线发送缓存
static uint8 pRxData[APP_PAYLOAD_LEN]; // 无线接收缓存
uint8 appMode = SLAVE ; // 单片机角色 用于代码分支
uint8 uTxData[128]; // 串口缓冲
uint16 lightness = 0; // 光照值
// 无线RF初始化
void ConfigRf_Init(void)
{
basicRfConfig.panId = PAN_ID;
basicRfConfig.channel = RF_CHANNEL;
basicRfConfig.myAddr = MY_ADDR;
basicRfConfig.ackRequest = TRUE;
while(basicRfInit(&basicRfConfig) == FAILED); // 初始化点对点数据结构
basicRfReceiveOn(); // 开启接收中断
}
/********************MAIN************************/
void main(void)
{
// static uint8 relaySta = 0;
halBoardInit();//选手不得在此函数内添加代码???
ConfigRf_Init();//选手不得在此函数内添加代码???
// 设置LED的IO口
MCU_IO_OUTPUT(1, 1, 1);
MCU_IO_OUTPUT(1, 0, 0);
while(1)
{
/* user code start */
if( appMode == MASTER ) // 主机代码
{
lightness = get_guangdian_ad(); // 获取光照值该函数在sensor.h中
if( lightness < 20 ) // 如果光照值小于20
{
pTxData[0] = RELAY_SET_CMD; // 继电器动作命令
basicRfSendPacket(SEND_ADDR, pTxData, APP_PAYLOAD_LEN); // 发包
}
else
{
pTxData[0] = RELAY_CLEAR_CMD; // 继电器复位
basicRfSendPacket(SEND_ADDR, pTxData, APP_PAYLOAD_LEN);
}
printf_str((char *)uTxData,"光照值%d",lightness); // sprintf()
halUartWrite(uTxData,strlen((char *)uTxData)); // 在hal_uart.c文件中,串口输出
}
else if ( appMode == SLAVE )
{
if( basicRfPacketIsReady() )
{
basicRfReceive(pRxData, APP_PAYLOAD_LEN, NULL);
if( pRxData[0] == RELAY_SET_CMD )
{
MCU_IO_OUTPUT(2, 0, 1);
MCU_IO_SET_HIGH_PREP(1, 0);
}
else if( pRxData[0] == RELAY_CLEAR_CMD )
{
MCU_IO_OUTPUT(2, 0, 0);
MCU_IO_SET_LOW_PREP(1, 0);
}
else
{}
}
}
else
{}//nothing
/* user code end */
}
}
void uart_printf(char *fmt,...); // 输出重定向,串口输出
void printf_str(char *buf, char *fmt,...); // sprintf
uint16 halUartWrite(uint8 *pBuffer, uint16 length); // 串口输出
在一个工程中编译主机和从机
代码深入
右击->Go to define of 函数名()
右击->Open Header/Source File
API 都在头文件里!
开源客栈日暮,入栈不知归路。debug无尽头,误入代码深处,单步单步已是代码最最深处,发现bug无数!
写个作业真不容易,