ZigBee学习Z-stack外部中断

合集下载

【无线通信篇Zstack协议栈】CC2530ZigbeeZstack协议栈组网项目及详细讲解篇

【无线通信篇Zstack协议栈】CC2530ZigbeeZstack协议栈组网项目及详细讲解篇

【⽆线通信篇Zstack协议栈】CC2530ZigbeeZstack协议栈组⽹项⽬及详细讲解篇物联⽹⽆线通信技术,ZigBee⽆线传感⽹络CC2530最⼤的特点就是⼀个拥有⽆线收发器(RF)的单⽚机,既能实现单⽚机功能,也能实现⽆线传输Zstack协议栈是ZigBee协议栈⾥的翘楚,是ZigBee组⽹的⾸选协议栈项⽬实现功能:l 总共有三个端点,⼀个协调器和两个终端节点l 终端节点1连接DHT11温湿度传感器,定时上传给协调器l 终端节点2连接LED,可以通过协调器按键控制,定时上报LED开关状态l 协调器连接12864 OLED 屏幕,实时显⽰温湿度和LED状态l 协调器可以通过按键控制终端2的LED开关,控制后将会显⽰控制结果扩展功能(当前未实现,可进⼀步开发实现):l 连接协调器串⼝,将终端节点采集的数据通过串⼝发送,PC写上位机实现数据展⽰l 连接WIFI或者4G模块,WIFI模块如ESP8266,实现数据局域⽹⽆线传输或者上传到OneNET、机智云、阿⾥云、⾃⼰开发云服务器等,实现WEB或⼿机APP显⽰和控制。

⼀、项⽬测试(可想⽽知,⼴州的天⽓有多热,39℃了都)实现功能汇总:l 总共有三个端点,⼀个协调器和两个终端节点l 终端节点1连接DHT11温湿度传感器,定时上传给协调器l 终端节点2连接LED,可以通过协调器按键控制,定时上报LED开关状态l 协调器连接12864 OLED 屏幕,实时显⽰温湿度和LED状态l 协调器可以通过按键控制终端2的LED开关,控制后将会显⽰控制结果(⼀) 环境汇总芯⽚:CC2530F256Zstack协议栈:ZStack-CC2530-2.5.1a编程环境:IAR(⼆) 引脚分配协调器:128*64 OLED 0.96⼨屏幕供电:3.3V通信协议:IIC引脚:SDA P0_6SCL P0_7按键:IO:P0_1下降沿触发中断终端1:DHT11:通信⽅式:单总线协议供电:3.3VIO:P0_6终端2:LEDIO:P1_0说明:⾼电平点亮,低电平熄灭⼆、基础认识(⼀) CC2530单⽚机CC2530最⼤的特点就是⼀个拥有⽆线收发器(RF)的单⽚机,既能实现单⽚机功能,也能实现⽆线传输。

Z-stack学习笔记

Z-stack学习笔记

2、何为 IEEE 802.15.4,其特点。 是 ZigBee 无限传感器网络通信标准,具有短距离(10m) ,低功 耗,低速率,低成本的特点,支持单跳星形(10m 内)和多跳对
等(>10m)两种网络拓扑。
3、何为 Z-Stack? Z-Stack 是 TI 公司开发的 ZigBee 协议栈,并且经过了 ZigBee 联 盟的认可而为全球众多开发商所广泛采用。 Z-Stack 实际上是帮助 程序员方便开发 ZigBee 的一套系统, 它采用轮转查询式操作系统, 包括两个主要流程(如图) :系统初始化和执行操作系统。系统初 始化完成后,就进入执行操作系统,并且在其中是一个死循环。 执行操作系统中主函数即为轮询式操作系统的主体部分,也是我 们需要重点开发、 调用、 掌握的部分。 欲知其详, 且听下文分解。
Check for keys */表示检查按键情况。
这个程序到最后,调用了一个重要的函数指针 pHalKeyProcessFunction
这个指针是指向 void OnBoard_KeyCallback ( uint8 keys, uint8 state ) 在“ZMain\OnBoard .c”文件中可以找到。
其中 0 号 endpoint 是用"ZDO"预留的,不能占用。 4. Cluster ID,这个怎么叫呢?叫信息簇 ID 吧。我的理解是,“这是个哪类的信息”,发送 端和接收端一定要对应,但是具体这个“类”怎么分,是我们可以自己决定的。比如说这个例 子,我可以这样定:Cluster ID=1 代表开关一次,Cluster ID=2 代表连续闪烁。或者定 义 Cluster ID=1 代表点对点控制,而 Cluster ID=2 代表全部控制,等等。
二、开发 Z-Stack 须知。 1、ZigBee 的体系,数据及管理的方式和方向。ZigBee 网络构架。

ZigBee的Z-Stack操作系统

ZigBee的Z-Stack操作系统

Z-Stack操作系统学习ZigBee有两个月了,学习期间也走了不少弯路,刚开始调试了几个LED小灯的实验,串口通信实验,点对点通信实验,以为这样基本就差不多可以做定位系统了,于是直接跳到定位这一块,实际上远没有那么简单。

我想很多初学者都是打开协议栈就被左边那一列给镇住了,看到那么多代码都不知道从何入手,下面我重点介绍一下关于ZigBee协议栈操作系统的原理,让更多初学者能看清Z-Stack操作系统(其实只是一个简单的小系统,看明白了觉得也没有多复杂)的工作过程。

下面的图片是我根据书上的资料自己绘制出来的,从这个图中可以看到Z-Stack的整个系统的工作流程。

Z-Stack操作系统似乎这个对于初学者来说也看不出什么道道来,我在看代码的时候完全不知道从哪里看起。

即使找到了主函数,找到了OSAL_start_system()也不知道他到底是怎么运行的。

首先我们先好好看一些这个微操作系统的工作流程:在ZMain主函数当中,基本上都是一些初始化函数,从中断、系统时钟、堆栈等等到最后按键、液晶显示初始化,这个对于我们来说基本上不用看,只需大致了解其功能即可,就像在电脑上编程只需了解软件和底层硬件的接口一样。

在初始化函数执行完以后便进入了osal_start_system()函数,开始OSAL操作系统。

OSAL操作系统里面有七个任务,该循环轮询查询每个任务是否有需要处理的事件,如果有则处理,没有则跳到下一个任务,这七个任务有不同的优先级,从图中可以看出MAC层拥有最高的优先级,MAC层如果有任务,则下面的任务不会被处理。

好了,基本上对于该操作系统有了一个简单的了解以后,我们再来结合代码看看代码到底是怎么运行的。

先大致浏览一下协议栈的目录,可以看到有ZMain文件夹(如下乳所示),这个应该就是主函数,看了很多资料确定了确实是从这里开始运行的。

打开ZMain.c,找到ZSEG int main( void )函数,函数内容如下:ZSEG int main( void ){// Turn off interruptsosal_int_disable( INTS_ALL );// Initialize HALHAL_BOARD_INIT();// Make sure supply voltage is high enough to runzmain_vdd_check();// Initialize stack memoryzmain_ram_init();// Initialize board I/OInitBoard( OB_COLD );// Initialze HAL driversHalDriverInit();// Initialize NV Systemosal_nv_init( NULL );// Determine the extended addresszmain_ext_addr();// Initialize basic NV itemszgInit();// Initialize the MACZMacInit();#ifndef NONWK// Since the AF isn't a task, call it's initialization routineafInit();#endif#ifdef LCD_SUPPORTEDHalLcdInit();#endif// Initialize the operating systemosal_init_system();// Allow interruptsosal_int_enable( INTS_ALL );// Final board initializationInitBoard( OB_READY );//HalLcdInit();// Display information about this devicezmain_dev_info();/* Display the device info on the LCD */#ifdef LCD_SUPPORTEDzmain_lcd_init();#endifosal_start_system(); // No Return from here} // main()————来自百度文库,转载请注明出去大致看一下,和上述图中的初始化基本上一样。

ZIGBEE学习笔记

ZIGBEE学习笔记

1、ZigBee协议栈:ZigBee协议是一系列的通信标准,通信双方需要共同按照这一标准进行正常的数据发射和接收。

协议栈是协议的具体实现形式,通俗点来理解就是协议栈是协议和用户之间的一个接口,开发人员通过使用协议栈来遵循和使用这个协议的,进而实现无线数据收发。

2、ZigBee无线网络协议层的架构:ZigBee协议分为两部分---IEEE 802.15.4和ZigBee,IEEE 802.15.4定义了PHY (物理层)和MAC(介质访问层)技术规范;ZigBee联盟定义了NWK(网络层)、APS(应用程序支持子层)、APL(应用层)技术规范。

ZigBee协议栈就是将各个层定义的协议都集合在一起,以函数的形式实现,并给用户提供API(应用层),用户可以直接调用---学习Zigbee就是熟悉API和学习如何使用对应函数。

3、用户实现简单的无线数据通信的一般步骤:---组网:调用协议栈的组网函数、加入网络函数,实现网络的建立与节点的加入。

---发送:发送节点调用协议栈的无线数据发送函数,实现无线数据发送。

---接收:接收节点调用协议栈的无线数据接收函数,实现无线数据接收。

4、Z-STACK协议栈工作原理:Z-stack可以看做是一个小型的操作系统(本质是大型的程序),用于实现底层和网络层的内容,Z-stack将复杂部分屏蔽掉。

用户通过API函数就可以轻易用ZigBee。

5、协调器、路由器、终端:Router----路由器Coodinator----协调器EndDevice----终端设备(1)协调器:(coordinator)每个zigbee网络只允许有一个zigbee的协调器,协调器首先选择一个信道和网络标识(PAN ID),然后开始这个网络.因为协调器是整个网络的开始,他具有网络的最高权限,是整个网络的维护者,还可以保持间接寻址用的表格绑定,同时还可以设计安全中心和执行其他动作,保持网络其他设备的通信。

转:ZigBeeZ-StackCC2530实现低功耗运行的配置简介

转:ZigBeeZ-StackCC2530实现低功耗运行的配置简介

转:ZigBeeZ-StackCC2530实现低功耗运⾏的配置简介设备⽀持低功耗运⾏是ZigBee⽹络的⼀⼤特点,该特性借助CC2530芯⽚能够很好地体现出来。

CC2530芯⽚有五种运⾏模式,分别为主动模式、空闲模式、PM1、PM2和PM3。

主动模式是⼀般运⾏模式;空闲模式除了CPU内核停⽌运⾏外,其他和主动模式⼀样;PM1、PM2、PM3是低功耗运⾏模式,CC2530通过关闭不必要的部分和调整系统时钟来达到低功耗的效果。

PM1:稳压器的数字部分开启,32 MHzXOSC和 16 MHz RCOSC都不运⾏。

32 kHz RCOSC或32 kHz XOSC运⾏。

复位、外部中断或睡眠定时器溢出时系统将转到主动模式。

PM2:稳压器的数字内核关闭。

32 MHzXOSC和 16 MHz RCOSC都不运⾏。

32kHz RCOSC或32 kHz XOSC运⾏。

复位、外部中断或睡眠定时器过期时系统将转到主动模式。

PM3:稳压器的数字内核关闭。

所有的振荡器都不运⾏。

复位或外部中断时系统将转到主动模式。

⼏种运⾏模式的对⽐如下表所⽰:PM2模式⼜叫LITE SLEEP模式,其功耗在毫安级别,多⽤于需要定时唤醒的场合,⽐如周期性地唤醒传感器来进⾏数据的采集。

PM3模式⼜叫做DEEP SLEEP模式,在⼏种运⾏模式中功耗最低,在微安级别,多⽤于远程遥控场合,⽐如使⽤CC2530做⼀个远程遥控器,在没有按键按下时,可使其进⼊PM3模式以减少电能消耗。

Z-STACK提供了两种低功耗运⾏模式,PM2和PM3。

PM2模式可被睡眠定时器,外部中断和复位唤醒,PM3模式可被外部中断和复位唤醒。

在Z-Stack的使⽤⽂档中得知为了使设备能够进⼊睡眠模式,必须满⾜以下的条件:1、通过添加预编译项POWER_SAVING来使能睡眠模式2、ZDO节点描述符指定“在空闲时发送功能是关闭的”,通过在f8wConfig.cfg⽂件中将RFD_RCVC_ALWAYS_ON设置为FALSE来实现。

zigbee UART 中断方式

zigbee UART 中断方式

如上图为串口的接收和发送缓冲区数据结构图,它是循环数组,等游标到达数组末尾时变为0,即数组头。

在中断方式串口传输数据时,当有数据通过串口传到本地时,接收到的数据由接收中断处理函数填充到rxBuf缓冲区中,填充的游标是rxTail,我们应用程序使用这些数据时是通过rxHead游标读取的。

同样,发送时我们是将数据填充到txBuf 中,填充的游标是txTail,填充完成后(因为在初始化函数中已经设置发送标志位,但是在写串口函数中才使能发送)由串口发送中断发送数据,发送游标是txHead,发送完成即txHead == txTail后设置txMT 标志位(看下文在uartISRCfg_t结构体中)static void HalUARTInitISR(void)串口初始化函数。

主要是配置串口的优先级选择(例如在相同的管脚上如果同时有UART0、UART1、定时器,应该优先将管脚配给谁),选择UART的备用位置(因为每个串口都有两组备用位置,此设置是为了确定串口的管脚位置),把相应的管脚设为外设I/O而不是GPIO,设置为UART模式而不是SPI模式,清除(flush)串口(即初始化串口为使用前的状态)static void HalUARTOpenISR(halUARTCfg_t *config)串口打开函数,其实是串口的进一步初始化函数。

typedef struct{bool configured;uint8 baudRate;bool flowControl;uint16 flowControlThreshold;uint8 idleTimeout;halUARTBufControl_t rx;halUARTBufControl_t tx;bool intEnable;uint32 rxChRvdTime;halUARTCBack_t callBackFunc;}halUARTCfg_t;首先设置串口的回调函数,然后根据给定的参数配置串口波特率、8/9位数据位、有无奇偶校验、停止位等串口相关的参数;若使能硬件流控制,将相应的RTS和CTS管脚也设为外设管脚而不是GPIO;最后接收器使能(UxCSR |= CSR_RE;注意顺序,必须配置完串口其他参数后才能使能),配置接收器中断使能位(URXxIE = 1),设置发送标志位(UTXxIF = 1;)(不知为何)uint16 HalUARTReadISR(uint8 *buf, uint16 len)串口读函数。

物联网系列专业课程之ZStack无线协议栈培训课件

物联网系列专业课程之ZStack无线协议栈培训课件

- ZStack通用配置文件
-DZIGBEEPRO -DREFLECTOR
# 启用ZigBee Pro 协议栈 # 允许绑定
-DDEFAULT_CHANLIST # 选择默认频道,通过在f8wConfig.cfg里面解除注释对应行来选择频道
-DZDAPP_CONFIG_PAN_ID # 通过改变PAN_ID来识别同一个频道里的不同ZigBee网络。
if (event & MY_REPORT_EVT) { myReportData(); osal_start_timerEx( sapi_TaskID, MY_REPORT_EVT, REPORT_DELAY );
} }
sapi接口 - zb_HandleKeys函数
zb_HandleKeys函数
行路由功能的父设备。因此,如果End Device想发送信息给另外一个End Device,在发送信息之 间将会启动路由探测功能,找到相应的父路由节点。
ZStack软件流程
整个ZStack的主要工作流程,大致分为系统启动,驱动初始化,OSAL初始化和启动, 进入任务轮循几个阶段:
开始
关中断
初始化存储器
sapi接口 - zb_HandleOsalEvent函数
zb_HandleOsalEvent函数
作用
当一个任务事件发生了之后,调用这个函数
参数
event:产生的时间
返回

示例
通过自己自定义一个事件来增加自己想要增加的功能 void zb_HandleOsalEvent( uint16 event ) {
MT_SAPI_CB_FUNC # 允许MT处理SAPI返回信息
ZStack无线协议栈 ZStack sapi软件框架 ZStack综合组网实验 ZStack通信协议解析

ZigBee学习之7

ZigBee学习之7

根据Z-Stack1.4.3-1.2.0中OSAL API_F8W-2003-0002_.pdf文档翻译。

Z-Stack1.4.3及以后的版本中引入了一个OS的概念,把应用层和堆栈层进行了分离,但是这个操作系统并不是时实的操作系统,所以有兴趣的话还可以将其改为时实的操作系统,或者用其他开源的实时操作系统取代,比如USOS,呵呵。

我将这个OS的API文档进行了一定的翻译,当然所谓一定,就是说有的地方没有翻译出来罗,要么是我不会的,要么就是我觉得没必要翻译的东西,总之,提供给各位一个参考,最好是对照原文档来阅读拉。

没接触过操作系统,也是第一次搞Zigbee,错误的地方还请各位多多指正。

OSAL(操作系统抽象层) API【OSAL API_F8W-2003-0002_.pdf】这个层次主要是将Z-Stack软件组件从特殊的处理过程相分离,将其保护起来。

一般来说提供如下几个功能:·任务的注册、初始化、开始·任务间的消息交换·任务同步·中断处理·时间管理·内存分配消息管理API消息管理API提供任务(或处理单元)间的消息交换(比如中断服务事务,控制循环中的函数调用)。

这些API能用来允许任务分配和取消分配的消息缓存,发送对其他任务的命令消息,接受应答消息。

byte *osal_msg_allocate(uint16 len)分配一个消息缓存,随后调用它的任务/函数将填充消息并调用osal_msg_send()将消息发送给其他任务。

参数:消息长度;返回值:指向消息缓存的指针,失败则为NULL。

byte osal_msg_deallocate(byte *msg_ptr)任务接收完消息后用来释放分配的消息缓存。

参数:要释放的消息缓存;返回值:ZSUCCESS - 成功INVALID_MSG_POINTER - 无效的消息指针MSG_BUFFER_NOT_AVAIL - 缓存正在队列(queued)byte osal_msg_send(byte destination_task,byte *msg_ptr)向其他任务或处理单元发送命令或数据消息。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ZigBee学习Z-stack外部中断
硬件抽象层:就是对硬件层做好了各种初始化,用户不用考虑硬件的初始配置,直接使用即可。

hal_driver.c文件:
HalDriverInit():用户可在此函数中添加硬件的初始化操作,如定时器、ADC、DMA、FLASH、AES、LCD、LED、UART、KEY、SPI、HID等(还有用于配置外部中断,类似按键的中断方式查询键值)
Hal_ProcessEvent():
处理HAL发生的事件、如:KEY、LED、电源管理等,用户可以在此添加处理自己的HAL事件,此事件ID必须是唯一的,定义在hal_driver.h中。

如:HAL_KEY_EVENT(按键轮询与抖动)、HAL_LED_BLINK_EVENT(LED闪烁)、HAL_SLEEP_TIMER_EVENT(Power saving).
Hal_ProcessPoll():
被osal_start_system()调用,用于HAL_Timer和HAL_UART的事件轮询,关于系统编译连接,只要没有定义相关的宏定义,相应的驱动就不会编译进去,减少代码占用的空间。

有以下的宏定义:
具体操作是:
Options->C/C++
Options->Preprocessor->Defined Symbols->enter:HAL_XXX=TRUE;
when XXX is ADC,UART,LED,LCD,KEY
不编译进代码,只要将其定义成FALSE
如何定做适合自己的HAL处理的程序
①修改原文件的方式:
1、HAL\include下的头文件应该保留一样。

2、在HAL\Target\hal_xxx.c修改相应的驱动函数,hal_adc.c, hal_key.c, hal_lcd.c, hal_led.c, hal_timer.c, and hal_uart.c
3、硬件驱动配置可以被修改在hal_board_cfg.h
②增加用户自己的目标驱动
1、增加新的头文件,在hal\include
2、在hal\Target\hal_xxx.c添加自己运行函数,xxx为自己的目标
3、如果GPIO有冲突或者没用到,应该保证驱动不被编译,否则后果严重。

4、检查GPIO有没有正确设置或冲突,通过hal_board_cfg.h
5、不想被编译,或者是老的文件,没用到的文件,可以通过选择options->"Exclude form build"
外部中断程序中断处理函数的定义:可以查看
hal\Target\hal_XXX.c\hal_mcu.h
HAL_ISR_FUNCTION(f,v)
HAL_ISR_FUNCTION (prototype, vector)
{
/* Do something when this interrupt happens!!! */
}
prototype是中断名称,vector是中断向量
①如何修改存在GPIO外部中断处理函数?
Example: Modify P1INT_VECTOR interrupt service routine in a CC2430 project. P1INT_VECTOR interrupt service routine is declared in hal_key.c.
HAL_ISR_FUNCTION (halKeyPort1Isr, P1INT_VECTOR)
{
halProcessKeyInterrupt ();//中断处理函数
}
增加新的中断处理函数
首先新建头文件,定义中断向量和定义要用到的GPIO地址,
(包函ioCC2530.h 即可)
ex:创建定时器1中断处理程序(T1_VECTOR)(中断向量定义在ioCC2530.h 中)主要就是,知道中断向量表的宏定义,然后使用HAL_ISR_FUNCTION(prototype, vector)建立处理函数。

现在就外部中断例子做以下笔记
新建一个hal_xxx.c文件和hal_xxx.h文件,此hal_xxx.h文件要在hal_driver.c 中包含,主要是使用hal_xxx.c定义外部中断初始化函数,而使用此初始化函数是在HalDriverInit中,在结尾中调用即可,就可以启动外部中断了,如以下
voidLightAdjInit( void )
{
/* Initialize previous key to 0 */
P1SEL&=~(1<<2);//设置P1_2为一般IO口功能
P1DIR&=~(1<<2);//设置P1_2为输入功能
P2INP&=~(1<<2);//设置为上拉
P1IEN|=(1<<2);//P1_2中断使能
PICTL&=~(1<<1);//上升沿引起中断
EA=1;//开启总中断
IEN2|=(1<<4);//端口1中断使能
P1IFG=0;//初始化中断标志位
}设置P1_2外部中断,此函数在hal_xxx.c文件中编写,
在hal_xxx.c中包含相应头文件,编写处理中断的函数和中断函数LightInterrupt(),HAL_ISR_FUNCTION( light_adj, P1INT_VECTOR )
light_adj是中断相应函数名,随便起,P1INT_VECTOR是中断向量,参考ioCC2530.h 在LightInterrupt中想产生相应事件,应该要定义相应的宏,在hal_drivers.h中定义,注意事件的定义规则,只能以0x0001/0x0002/0x0004/0x0008这样不同的位置定义,因此对于每个任务只能定义16个事件
事件的处理要看相应的任务,一般在Hal_ProcessEvent()函数中编写处理如:
if(events & HAL_LIGHT_EVENT)
{
LED2_SBIT=~LED2_SBIT;
return events ^ HAL_LIGHT_EVENT;
}
在外部中断处理函数中产生事件,可以使用osal_start_timerEx (Hal_TaskID, HAL_LIGHT_EVENT, 10);也可以使用osal_set_event(Hal_TaskID,UART_RX_CB_EVT);等让相应的任务处理事件。

相关文档
最新文档