NV操作实验
1、实验内容:通过串口调试助手发送“nvread”命令,开发板接受到该命令读取NV存储器中的数据并发送给PC端的串口调试助手。
2、基本知识:
NV(Non Volatile),即非易失性存储器(Flash存储器),即系统掉电,存储器中的数据不掉失。主要用途保存网路的配置参数,或掉电后,上电该节点还是加入原来的网络并且该节点的网络地址就可以从NV读取。
NV存储器主要的操作有初始化NV存储器、读NV存储器、写NV存储器。这些都在OSAL文件夹下中的OSAL_Nv.h和OSAL.h文件中定义和实现。
下面三个操作函数分别是:
NV初始化函数:uint8 osal_nv_item_init( uint16 id, uint16 len, void *buf ),NV存储器将该存储器分成多个条目,每个条目都有一个ID号。
条目的分类见OSAL文件夹中的ZcomDef.h文件,其中要知道的是:用户应用程序定义的条目地址范围为是0x0201到0x0FFF;
NV写操作函数:uint8 osal_nv_write( uint16 id, uint16 ndx, uint16 len, void *buf );
NV读取函数:uint8 osal_nv_read( uint16 id, uint16 ndx, uint16 len, void *buf );
第一个参数:uint16:NV条目ID号
第二参数:举例条目开始的偏移量
第三参数:要写入的数据长度
第四参数:执行要存放写入或读取数据函数缓冲区的指针
3、实验代码:在实验3 串口通信实验的基础上添加或修改代码实现的。
首先,在OSAL文件夹中的ZcomDef.h文件文件中添加一行代码,如下:
// NV Items Reserved for APS Link Key Table entries
// 0x0201 - 0x02FF
#define ZCD_NV_APS_LINK_KEY_DATA_START 0x0201 // APS key data
#define TEST_NV 0x0202 //添加了该行,表 测试条目
#define ZCD_NV_APS_LINK_KEY_DATA_END 0x02FF
在Coordinator.c中添加或修改代码,具体如下:
//Coordinator.c
#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include
#include "Coordinator.h"
#include "DebugTrace.h"
#if !defined(WIN32) //????
#include "OnBoard.h"
#endif
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_uart.h"
#include "OSAL_Nv.h" //使用NV操作函数,必须包含该头文件
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS]=
{
GENERICAPP_CLUSTERID
};
//简单设备描述符(描述一个ZigBee设备节点)
const SimpleDescriptionFormat_t GenericApp_SimpleDesc=
{
GENERICAPP_ENDPOINT,
GENERICAPP_PROFID,
GENERICAPP_DEVICEID,
GENERICAPP_DEVICE_VERSION,
GENERICAPP_FLAGS,
GENERICAPP_MAX_CLUSTERS,
(cId_t*)GenericApp_ClusterList, //?????
0,
(cId_t *)NULL
};
endPointDesc_t GenericApp_epDesc;//节点描述符
byte GenericApp_TaskID;//任务优先级
byte GenericApp_TransID;//数据发送序列号。
unsigned char uartbuf[128];//串口接收发送数据缓冲单元
void GenericApp_MessageMSGCB(afIncomingMSGPacket_t *pckt);//消息处理函数
void GenericApp_SendTheMessage(void);//数据发送函数
static void rxCB(uint8 port,uint8 envent);//???????????
void GenericApp_Init(byte task_id)//任务初始化函数
{
GenericApp_TaskID =task_id; //初始化任务优先级(任务优先级有协议栈的操作系统OSAL分配)
GenericApp_TransID =0; //发送数据包的序号初始化为0
//对节点描述符进行初始化
GenericApp_epDesc.endPoint =GENERICAPP_ENDPOINT;
GenericApp_epDesc.task_id =&GenericApp_TaskID;
GenericApp_epDesc.simpleDesc =(SimpleDescriptionFormat_t*)&GenericApp_SimpleDesc;
GenericApp_epDesc.latencyReq =noLatencyReqs;
afRegister(&GenericApp_epDesc);//afRegister()对节点的描述符进行注册。注册后,才能使用OSAL提供的系统服务。
halUARTCfg_t uartConfig;//该结构体变量是实现 串口的配置
//串口的初始化
uartConfig.configured =TRUE;
uartConfig.baudRate =HAL_UART_BR_115200;//波特率
uartConfig.flowControl =FALSE; //流控制
uartConfig.callBackFunc =rxCB; //填的是回调函数 ,数的指针(即函数的地址)作为参数传递给另一个函数,
//其实callBackFunc是一个函数指针,它的定义为halUARTCBack_t callBackFunc;
//而halUARTCBack_t的定义为 typed void (*halUARTCBack_t)(uint8 port,uint8 envent) 定义的是一个函数指针
HalUARTOpen(0,&uartConfig); //串口是否打开
}
//下面这个是回调函数,回电函数就是一个通过函数指针(函数地址)调用的函数,如果把函数的指针(即函数的地址)作为参数传递给另一
//个函数,当通过该指正调用它锁指向的函数时,称为函数的回调。
//回调函数不是有该函数的实现方直接调用的,而是在特定的事件或条件时,由另一方调用的额,用于对该事件或条件进行响应。
//回调函数机制提供了系统对异步事件的处理能力。
static void rxCB(uint8 port,uint8 envent)
{
// HalLedBlink(HAL_LED_2,0,50,500); //LED1 闪烁
// HalUARTRead(0,uartbuf,10); //从串口读取数据放在uartbuf缓冲区中
uint8 value_read; //用于存储从NV存储器中读取的数据
uint8 value=18; //写入NV条目的数据
uint8 uartbuf[2]; //存放读取的数据(ASCII码)
uint8 cmd[6]; //从串口读取命令
HalUARTRead(0,cmd,6);
if(osal_memcmp(cmd,"nvread",6))//判断接受到的数据是否是www.wlwmaker.com,如果是,函数返回TURE
{
osal_nv_item_init(TEST_NV,1,NULL); //初始化NV条目
osal_nv_write(TEST_NV,0,1,&value); //向NV条目写入数据
osal_nv_read(TEST_NV,0,1,&value_read); //从NV条目中读取数据
uartbuf[0]=value_read/10+'0';
uartbuf[1]=value_read%10+'0';
HalUARTWrite(0,uartbuf,2); //将接收到的数字输出到串口
HalLedBlink(HAL_LED_1,0,50,500); //LED2 闪烁
}
}
//消息处理函数
UINT16 GenericApp_ProcessEvent(byte task_id,UINT16 events)
{
}
5、本文参考自:《ZigBee无线传感器网络设计与实现》 王小强等人编著化学工业出版社