NV操作实验
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
- #include "OSAL.h"
- #include "AF.h"
- #include "ZDApp.h"
- #include "ZDObject.h"
- #include "ZDProfile.h"
- #include <string.h>
- #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)
- {
- }
4、实验结果(ASCII中十六进制的31、38表字符1、8):
5、本文参考自:《ZigBee无线传感器网络设计与实现》 王小强等人编著化学工业出版社