zstack 串口使用指南
Zstack协议栈对串口进行操作
Zstack协议栈对串口进行操作Zstack协议栈中如何对串口进行操作想要使用串口功能,首先要进行初始化操作:halUARTCfg_t uartConfig;uartConfig.configured = TRUE; // 2x30 don't care - see uart driver.uartConfig.baudRate = SERIAL_APP_BAUD;uartConfig.flowControl = TRUE;uartConfig.flowControlThreshold = SERIAL_APP_THRESH; // 2x30 don't care - see uart driver.uartConfig.rx.maxBufSize = SERIAL_APP_RX_SZ; // 2x30 don't care - see uart driver.uartConfig.tx.maxBufSize = SERIAL_APP_TX_SZ; // 2x30 don't care - see uart driver.uartConfig.idleTimeout = SERIAL_APP_IDLE; // 2x30don't care - see uart driver.uartConfig.intEnable = TRUE; // 2x30 don't care - see uart driver.uartConfig.callBackFunc = SerialApp_CallBack; HalUARTOpen (SERIAL_APP_PORT, &uartConfig);程序首先定义了halUARTCfg类型的变量uartConfig,用来配置跟串口功能相关的波特率、流控制等等,其中最重要的是uartConfig.callBackFunc=SerialApp_CallBack。
Zstack入门教程
Zstack入门教程第一步:安装Zstack从TI官方网站上下载的Zstack为:swrc072c.zip,我想这个压缩包大家都认识。
解压之后为:ZStack-CC2430-1.4.3.exe文件。
这个安装文件大家都会了。
默认安装路径为:C:\Texas Instruments\ZStack-1.4.3。
安装之后在C:\Texas Instruments\ZStack-1.4.3目录下有各PDF 文档为:Getting Started Guide CC2430.pdf,不用多说,这个肯定是要看的。
既然把它放到这么前面,说明它是入门中的入门文档。
下面就简单介绍下这个文档:1、介绍了安装ZStack-CC2430-1.4.3.exe需要的硬件软件条件:需要电脑、操作系统为Windows 2000或Windows XP。
至于更高或更低版本的本人没有尝试。
2、讲了安装流程。
这个有点多余了,这年月哪个有电脑的没有安装上百上千次的软件啊?但是需要强调的是安装路径----默认就好!3、接下来就是让我们看的第一个文档为:Start->Programs->Texas Instruments->ZStack-1.4.3->Z-Stack User’s Guide,既然让我看我就来看看这个文档!!第二步:Z-Stack 用户指导这个文档的更新时间为:2007年12月21日----应该还是比较新的版本。
由于本人英文的却有限,就不翻译了,浏览一遍,把大概意思说下就可以了:1、介绍1.1、适用范围本文档适用于CC2430ZigBee开发板----CC2430ZDK。
2、产品包描述(TI提供的CC2430ZDK工具包)2.1、安装包内容这个就是上面提到的的ZStack-CC2430-1.4.3.exe安装之后的所有内容了。
说白了就是包含Zstack开发所需要的所有软件和文档资料等。
2.2、开发板介绍两块SmartRF04EB 评估版,每个都可以用于CC2430EM评估模块。
ZStack V3.10.0 日志服务器 使用教程说明书
3. 验证日志服务器
文档版本:V3.10.0
5
日志服务器 使用教程 / 3 典型场景实践
配置完成后,在日志服务器中输入以下命令,查看是否已正常获取管理节点日志: cat /var/log/test.log
如图 3: 获取管理节点日志所示: 图 3: 获取管理节点日志
如上所述,日志服务器已成功接收到管理节点日志信息,日志服务器配置生效。
云主机(VM Instance)
运行在物理机上的虚拟机实例,具有独立的IP地址,可以访问公共网络,运行应用服务。
镜像(Image)
云主机或云盘使用的镜像模板文件,镜像模板包括系统云盘镜像和数据云盘镜像。
文档版本:V3.10.0
7
日志服务器 使用教程 / 术语表
云盘(Volume)
云主机的数据盘,给云主机提供额外的存储空间,共享云盘可挂载到一个或多个云主机共同使用。
如图 1: 配置syslog server所示: 图 1: 配置syslog server
2. 在云平台创建日志服务器 在ZStack私有云主菜单,点击平台管理 > 日志服务器按钮,进入日志服务器界面,点击添加 日志服务器按钮,参考以下内容进行配置:
• 名称:设置日志服务器名称 • 简介:可选项,可留空不填 • IP地址:输入日志服务器的IP地址
注意事项 • 需要设置日志级别与日志服务器的配置完全一致,才能正常接收日志信息,日志级别支持设 置LOCAL0-9,仅为了匹配日志服务器,无高低之分。 • 需确保云平台管理节点与日志服务器的连通性。 • 配置成功后,管理节点的全部日志均会发送至日志服务器,不区分DEBUG、INFO、ERROR等 输出级别。 • 仅admin/平台管理员支持设置日志服务器。
【无线通信篇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协议栈基础和数据传输实验
「ZigBee模块」协议栈-Z-Stack协议栈基础和数据传输实验花了好久写的...感觉还不错的呢...如果看,请细看...Mua~Z-Stack协议栈基础和数据传输实验一、实验目的终端节点将数据无线发送到协调器,协调器通过串口将数据发送到PC端,并在屏幕上显示出来。
串口优化把有线串口传输改为无线蓝牙传输。
二、实验平台硬件:2个zigbee节点,1个编译器,1根方口转USB数据线,一个蓝牙模块软件:实验基于SampleApp工程进行。
三、实验步骤1.串口初始化代码2.发送部分代码3.接收部分代码四、协议栈基础做实验之前先了解一点关于协议栈的基础知识吧~什么是协议栈?我们知道使用Zigbee一般都要进行组网、传输数据。
可想而知其中的代码数量是非常庞大的,如果我们每次使用zigbee都需要自己写所以代码的话,会非常麻烦。
因此就有了协议栈。
可以说它是一个小型的操作系统,把很多通信、组网之类的代码都封装起来了。
我们要做的只是通过调用函数来实现我们的目的。
来看一下协议栈的工作流程图(图1)。
然后我会对照流程图对协议栈进行简单的分析。
图1我们就从流程图的“开始”开始分析吧~打开工程文件SampleApp,main函数是程序执行的开始,我们要先找到它。
Main函数在ZMAin文件夹的ZMain.c下,打开它,找到main函数。
main();浏览一下main函数可以看到一开始都是各种初始化函数,即对应流程图中的“各种初始化函数”。
初始化中我们需要注意的是“osal_init_system();”初始化操作系统函数。
等一下会对它进行说明。
继续看下去,“osal_start_system();”这是执行操作系统函数,对应流程中的“运行操作系统”。
注意这个函数进去之后是不会再返回的。
总结main函数就是初始化和执行操作系统两个部分。
我们再来分析一下“osal_init_system();”这个函数,它的功能是初始化操作系统。
Z-stack串口的DMA模式简介
协议栈串口的DMA模式以下修改皆基于ZStack-CC2530-2.3.0-1.4.0版本:1.串口的初始化根据底板的引脚分配,我们用的是串口的UART0的Alt2方式。
需要修改的地方:(1)将option里预编译选项,ZTOOL_P1改成ZTOOL_P2,使#define HAL_UART_DMA 2为真。
(2)_hal_uart_dma.c的HalUARTInitDMA函数是对UART引脚以及寄存器的操作,修改如下:在HAL_UART_DMA == 2情况下的//#define HAL_UART_Px_RTS 0x20 // Peripheral I/O Select for RTS.//#define HAL_UART_Px_CTS 0x10 // Peripheral I/O Select for CTS.//屏蔽上两句,是因为该底板没有分配RTS和CTS的引脚#define HAL_UART_PERCFG_BIT 0x01 // USART0 on P1, Alt-2; so set this bit. //这里是将串口设置为UART0的Alt2方式#define HAL_UART_Px_RX_TX 0x30 // Peripheral I/O Select for Rx/Tx.//此处设置RX,TX引脚为P1_4,P1_5(3)在osal_init_system里osalInitTasks下MT_TaskInit的MT_UartInit(),是对串口的配置但要将uartConfig.flowControl = MT_UART_DEFAULT_OVERFLOW;改为uartConfig.flowControl = FALSE;协议栈默认的流控制是TRUE。
2. 串口的事件处理//系统主循环void osal_start_system( void ){……Hal_ProcessPoll(); // 串口与定时器轮询函数……}//定时器与串口轮询函数void Hal_ProcessPoll (){…….#if (defined HAL_UART) && (HAL_UART == TRUE)HalUARTPoll();#endif……}//串口轮询函数void HalUARTPoll( void ){#if HAL_UART_DMAHalUARTPollDMA();//根据DMA的方式选择DMA的轮询方式#endif……}//DMA串口轮询函数static void HalUARTPollDMA(void){……//以上是检查rxbuf里是否有数据写入,并对uartDMACfg_t dmaCfg结构体赋值if (evt && (dmaCfg.uartCB != NULL)){dmaCfg.uartCB(HAL_UART_DMA-1, evt);}//执行回调函数}注:回调函数dmaCfg.uartCB的初始化在HalUARTOpenDMA的第一句代码:dmaCfg.uartCB = config ->callBackFunc;而halUARTCfg_t uartConfig结构体的初始化在MT包里的MT_UART.c的MT_UartInit ()中1)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;该结构体是UART的配置结构体,设置UART的波特率,流控制,回调函数等等。
基于Z-Stack的串口通信.ppt
灯的亮灭与闪烁。
战略性信息产业教育服务提供商
联世界 育未来——创新物联教育
目
录
一、实训目的
二、实训内容 三、实训原理 四、实训步骤
战略性信息产业教育服务提供商
联世界 育未来——创新物联教育
实训内容
在用户应用层任务处理函数 SampleApp_ProcessEvent 中实 现每隔5秒向串口发送“Hello NEWLab!”;并增加一个应用层新任 务,实现由PC 端发送字符“1”和“ 2” 控制ZigBee模块的LED2 灯的
实训原理
(1) 第5)行代码HAL_ENTER_CRITICAL_SECTION(intSta te)函数的作用是把原先中断状态EA赋给X,然后关中断;以便后面 可以恢复原先的中断状态。目的是为了在访问共享变量时,保证变 量不被其它任务同时访问。
(2) 第6)行代码HAL_EXIT_CRITICAL_SECTION(intState)
tasksEvents[tasksCnt] SampleApp_ProcessEvent tasksArr[tasksCnt]
. . .
. . .
tasksEvents[2] tasksEvents[1] tasksEv ents tasksEvents[0] 事件表
Hal_ProcessEve nt Nwk_event_loo p macEventLoop tasksArr[ ] 函数表
数组tasksArr[ ]的每个元素都是函数的地址(用函数名表示函数
的地址),即该数组的元素都是事件处理函数的函数名,如第16行, SampleApp_ProcessEvent就是“通用应用任务事件处理函数名”, 该函数在SampleApp.c文件中被定义了。
ZSTACK串口读写的深度分析 DMA操作部分
HAL_ISR_FUNCTION( halUart1RxIsr, URX1_VECTOR ) HAL_ISR_FUNCTION( halUart0TxIsr, UTX0_VECTOR ) HAL_ISR_FUNCTION( halUart1TxIsr,t0 发送 //uart1 发送
U0BAUD = (config->baudRate == HAL_UART_BR_38400) ? 59 : 216; U0GCR = (config->baudRate == HAL_UART_BR_38400) ? 10 : 11; 这两个是真正定义波特率的地方,具体细节的寄存器定义同学们还是要看手册的 uart 部分哦。下图给 出了在 32MHz 频率下手册中的一波特率表:
代码比较多,我不一一列出,请自行比对代码。看代码,首先是 UART0 和 UART0 占用 P0 口的优先 级,UART0 最优先。之后根据是否使用 UART0 或 UART1 来初始化端口配置和 UART 工作模式配置,并 且为了防止片内 ADC 和 UART 抢 P0 口,还要禁止 ADC 用 RX 和 TX 口。实际上,我们做硬件的也不可 能糊涂到这两个口线同时使用。(TI 考虑的还是很全面的,赞一个!)。之后就是如果使用了 DMA 功能为 串口搞数据,就初始化 DMA 的一大套东西,不过值得注意的是这个协议栈只允许每一个时刻只能让 DMA 操作一个 UART。如果你想让两个 UART 都用 DMA 功能,那么恐怕 DMA 的 1,2 两个通道也要被 UART 使用了,如此太不厚道了,一共 5 个通道,被 UART 搞走了 4 个,哈哈。
为什么要这么做一个结构体呢?这个事情还是要从 CC2430 处理器 user guide 中 DMA 控制器操作说明 说起。我们先节选手册上关于 DMA 的几段描述:
z-stack串口详解
好久没写了,今天正式回归,这次要用到串口了,一到用的时候我就发现自己傻逼了,很多东西在脑海里乱七八糟的,有很多简单的问题还没搞清楚,管它呢,先把这些幼稚的问题搞清楚再说。
(1)在z-stack中应用串口有几种方式?哪位大侠有答案。
(2)关于中断和DMA方式有何区别?(3)我想用中断方式,该怎么用??这些问题很幼稚,但我还不懂,杯具了。
看了网上的资料,转载如下(抄袭的滋味真不好受啊):串口接收发送数据有两种方式,一种是中断的模式,另一种是DMA方式,这里主要以中断的方式,来看一下使用串口来发送,接收数据的整个流程。
这里以SerialApp例程为例子。
在mian函数中的调用HalDriverInit();函数,在函数中初始化串口,主要是配置管脚和DMA通道void HalDriverInit (void){...................................#if (defined HAL_UART) && (HAL_UART == TRUE)HalUARTInit();#endif ....................................}从程序中可以看出要想使用协议栈中串口,初始化串口必须定义HAL_UART和HAL_UART TRUE 在hal_board_cfg.h文件中。
#ifndef HAL_UART#if (defined ZAPP_P1) || (defined ZAPP_P2) || (defined ZTOOL_P1) || (defined ZTOOL_P2)#define HAL_UART TRUE#else#define HAL_UART FALSE#endif#endif然后在osal_start_system()开始系统后,会调用Hal_ProcessPoll()来读取时间和串口。
在CC2430的数据手册中有这样一段话。
从零开始学习Zstack_1-9
从零开始学习Zstack之1Zstack情况:本人采用的是TI的Zstack1.4.3协议,据说这个需要IAR7.30B及以上版本,而目前市面上又没有破解,所以用的人很少,这也是我的机会!呵呵!(傻笑有点多,关键是WORD里没有表情符号,不能正常表达我此时的心情!)正式开始:开始之前在说一句:从TI网站上下载的Zstack的方法就不介绍了。
否则就是从-1开始了而不是从0开始了-----------------我是这么觉得的!第一步:安装Zstack从 TI官方网站上下载的Zstack为:swrc072c.zip,我想这个压缩包大家都认识。
解压之后为:ZStack- CC2430-1.4.3.exe文件。
这个安装文件大家都会了。
默认安装路径为:C:\ Texas Instruments\ZStack-1.4.3。
安装之后在C:\Texas Instruments\ZStack-1.4.3目录下有各PDF文档为:Getting Started Guide CC2430.pdf,不用多说,这个肯定是要看的。
既然把它放到这么前面,说明它是入门中的入门文档。
下面就简单介绍下这个文档:1、介绍了安装ZStack-CC2430-1.4.3.exe需要的硬件软件条件:需要电脑、操作系统为Wi ndows 2000或 Windows XP。
至于更高或更低版本的本人没有尝试。
2、讲了安装流程。
这个有点多余了,这年月哪个有电脑的没有安装上百上千次的软件啊?但是需要强调的是安装路径----默认就好!3、接下来就是让我们看的第一个文档为:Start->Programs->Texas Instruments->ZStack-1.4.3->Z-Stack User’s Guide,既然让我看我就来看看这个文档!!第二步:Z-Stack 用户指导这个文档的更新时间为:2007年12月21日----应该还是比较新的版本。
zstack 串口使用指南
zstack 串口使用指南ZStack 串口使用指南1、简介本文档旨在介绍如何在ZStack开发框架中使用串口功能。
通过串口,可以实现与外部设备进行数据交互,如与传感器通信、与PC 机通信等。
本文将从串口的基本概念开始介绍,然后详细说明在ZStack中如何配置和使用串口功能。
2、串口基础知识2.1 串口的概念串口是一种通过对数据进行串行传输的方式来实现数据通信的接口。
它对数据进行分帧、传输、接收和解析,是常用的外部设备与主控进行通信的方式之一。
2.2 串口的工作原理串口通信是通过发送和接收两个方向上的信号来实现的。
发送端将数据进行串行化处理,然后通过串口线依次发送给接收端。
接收端接收到数据后,再进行解析和处理。
3、ZStack中的串口配置3.1 串口引脚配置在ZStack开发框架中,需要根据具体的硬件平台来配置串口引脚。
一般情况下,需要连接UART芯片与主控芯片。
3.2 串口初始化配置在ZStack中,可以通过调用相关API来进行串口的初始化配置。
具体的配置包括波特率、数据位、停止位、校验位等。
可以根据业务需求进行相应的配置。
4、串口数据收发4.1 数据发送在ZStack中,可以使用相关API来实现串口数据的发送。
可以将需要发送的数据通过API传递给串口发送缓冲区,然后通过调用相应的API来发送数据。
4.2 数据接收在ZStack中,可以使用相关API来实现串口数据的接收。
通过配置串口的接收中断,并设置接收缓冲区,当接收到数据时,会触发相应的中断,通过API可以读取到接收到的数据。
5、附件:示例代码本文档附带一个示例代码,展示了在ZStack中使用串口的基本操作。
可以通过参考示例代码来加深理解和实践。
6、法律名词及注释6.1 波特率:串口通信中的数据传输速率,表示每秒传输的数据bit数。
6.2 数据位:表示每个字节中有效数据的位数。
6.3 停止位:表示每个字节结束后的空闲时间,用于区分不同字节。
zstack完整资料
\ZigBee\南京\cc2530模块资料(天线杆版本)\cc2530模块资料(天线杆版本)\相关的学习文档\Zstack OSAL详解.pdf\ZigBee\南京\cc2530模块资料(天线杆版本)\cc2530模块资料(天线杆版本)\相关的学习文档\zigbee技术实践教程.pdf\ZigBee\z-stack\Z-Stack_API.pdf配置cc2530的第2功能时,不需要配置方向寄存器,否则可能出错hal_key.c下的HalKeyConfig()函数中/* Rising/Falling edge configuratinn */HAL_KEY_JOY_MOVE_ICTL &= ~(HAL_KEY_JOY_MOVE_EDGEBIT); /* Clear the edge bit */ /* For falling edge, the bit must be set. */#if (HAL_KEY_JOY_MOVE_EDGE == HAL_KEY_FALLING_EDGE)HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_EDGEBIT;#endif有错,应将HAL_KEY_JOY_MOVE_ICTL改为PICTL1ZigBee协议架构1.1ZigBee简介Zigbee是IEEE 802.15.4协议的代名词。
根据这个协议规定的技术是一种短距离、低功耗的无线通信技术。
这一名称来源于蜜蜂的八字舞,由于蜜蜂(bee)是靠飞翔和“嗡嗡”(zig)地抖动翅膀的“舞蹈”来与同伴传递花粉所在方位信息,也就是说蜜蜂依靠这样的方式构成了群体中的通信网络。
其特点是近距离、低复杂度、自组织、低功耗、低数据速率、低成本。
主要适合用于自动控制和远程控制领域,可以嵌入各种设备。
Zigbee是一种新兴的短距离、低速率、低功耗无线网络技术,它是一种介于无线标记技术和蓝牙之间的技术提案。
ZigBee学习之13——ZStack_API解读
ZigBee 学习之1313——————ZStackZStack API 解读API实现了所有ZDP(ZigBee Device Profile)定义的命令和回应所需要的函数。
ZDP 描述了ZDO 如何实现普通ZigBee 设备的特性,它定义了设备描述和簇,ZDP 为ZDO 和应用提供一下功能:•设备网络建立•设备和服务发现•节点设备邦定和解邦定服务•网络管理服务设备发现是ZigBee 设备发现其他ZigBee 设备的过程。
比如将已知的IEEE 地址作为数据载荷广播到网络的NWK 地址请求,相关设备必须回应并告知其网络地址。
服务发现提供了PAN 中一个设备发现其他设备提供的服务的能力。
它利用多种描述符去指定设备的能力。
当用户需要邦定控制器与被控设备(比如开关和灯)时,将用到邦定和解邦定服务。
特别是终端设备邦定支持利用用户的输入来定义控制/被控设备对的简单邦定方法。
邦定和解邦服务可以创建和删除邦定表入口。
网络管理服务主要提供给用户和调试工具网络管理的能力,它能够从设备重新获得管理信息,包括网络发现结果,路由表的内容,邻居节点链路质量,邦定表内容。
也可以通过解关联将设备从PAN 中脱离来控制网络关联。
ZDO 设备网络建立在ZigBee 网络中默认ZDApp_Init()[in ZDApp.c]开始器件的启动,但是应用能覆盖整个默认行为,为了使应用接管网络的启动,必须在编译选项中包含HOLD_AUTO_START,推荐同时包含NV_RESTORE(储存ZigBee 网络状态到NV)编译选项,包含这个两个编译选项后就需要调用ZDOIni tDevice()来启动网络中的设备。
uint8ZDOInitDevice(uint16startDelay )启动网络中的设备。
如果应用想要强制一个“新的”加入(即不恢复网络状态),则应该先调用z gWriteStartupOptions(ZG_STARTUP_SET,ZCD_STARTOPT_DEFAULT_NETWORK_STATE)来设置ZCD_NV_STARTUP_OPTION 中的ZCD_STARTOPT_DEFAULT_NETWORK_STATE 位。
zigbee之Zstack添加应用
一、修改HALHAL及所谓的Hardware Abstration Layer,通俗的了解即为开发板的硬件驱动,由于所用的是无线龙的开发板,与Ti的原装开发板有差异,需要对协议栈自带的HAL进行修改。
HAL文件存放在目录<Components/hal>中,里面有<common>、<include>、<target>三个目录,<common>中定义的与外设无关的硬件操作,<include>存放的是头文件,而<target>存放的是目标文件,里面根据目标板的不同分为<CC2430BB>、<CC2430DB>、<CC2430EB>。
以按键例程为例:(1)从主函数main()可以看出,里面都是初始化函数init,执行过程HalDriverInit()→HalKeyInit();在HalKeyInit()里基本完成了相应管脚的输入输出配置,然后到zmain_ext_addr();时,判断物理扩展地址是否合法。
(2)然后到osal_init_system();→osalInitTasks();→SAPI_Init(taskID); →RegisterForKeys(sapi_TaskID);注册按键事件。
(3)最后InitBoard(OB_READY);→HalKeyConfig(OnboardKeyIntEnable,OnBo ard_KeyCallback);配置按键为中断方式还是轮询方式。
默认是配置为轮询方式的。
这就是主函数大致对按键的处理过程。
(4)接下来从HalKeyConfig()入手:void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback){#if (HAL_KEY == TRUE)/* Enable/Disable Interrupt or */Hal_KeyIntEnable = interruptEnable;/* Register the callback fucntion */pHalKeyProcessFunction = cback; //指向回调函数/* Determine if interrupt is enable or not */if (Hal_KeyIntEnable) //如果设为中断方式{………………..进行一些中断的相关配置}else /* Interrupts NOT enabled */ //否则为轮询方式{…………………….osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_POLLING_VALUE); /* Kick off polling */}……………………..}可以看出,配置为轮询方式时启动osal_start_timerEx()函数。
Z-STACK问题之串口结构(转载)
Z-STACK问题之串口结构(转载)(2010-12-09 09:43)分类:ZigBee 技术学习typedefstruct{uint8 *rxBuf;//接收缓存uint8 rxHead;//头uint8 rxTail;//尾uint8 rxMax;//接收最大长度uint8 rxCnt;//计数uint8 rxTick;//时间uint8 rxHigh;//高位uint8 *txBuf;#if HAL_UART_BIG_TX_BUFuint16 txHead;uint16 txTail;uint16 txMax;uint16 txCnt;#elseuint8 txHead;uint8 txTail;uint8 txMax;uint8 txCnt;#endifuint8 txTick;uint8 flag;//标志位halUARTCBack_trxCB;} uartCfg_t;有个朋友问我上面的问题,说句老实话,我可是第一次见这个东东,拿到手之后比我那朋友还迷糊,那位朋友至少还知道大概是什么功能,仅仅是不清楚每个参数的具体含义和功能。
为了解决这个问题,我可是遍寻名家,最终结果是人家也不是很清楚,因为平常大家只管用,哪管那么多这些具体细节?没办法,我只有自己解决了,希望我的努力能给大家一点点启示!首先说说这个结构的应用范畴,它是直接面向串口的应用层,也就是与客户接触的还是比较紧密的一个结构,一般是在串口接收数据和发送数据的时候使用。
而串口有两种方式,一种是普通的串口,一种是DMA方式。
这里我只针对普通串口来分析这个结构。
首先来看看这个结构在什么地方用到了?static void pollDMA( uartCfg_t *cfg )static void pollISR( uartCfg_t *cfg )这两个函数直接就用到了这个结构作为参数,应该说是联系最紧密的了,是我们重点剖析的对象了,但是这里不看DMA,因为这个俺很外行----------哈哈!!!!uint16 HalUARTRead( uint8 port, uint8 *buf, uint16 len )uint8 HalUARTOpen( uint8 port, halUARTCfg_t *config )void HalUARTClose( uint8 port )void HalUARTPoll( void )uint16 Hal_UART_RxBufLen( uint8 port )uint16 HalUARTWrite( uint8 port, uint8 *buf, uint16 len )这几个函数都在其中定义了这个结构的变量在使用,所以我们也需要关注。
如何使用ZStack
2010-10-08 21:30如何使用ZStack——网络配置1.PAN ID 和Channel(f8wConfig.cfg)ZigBee协议使用一个14位的个域网标志符(PAN ID)来标识一个网络。
ZStack 允许用两种方式配置PAN ID,当ZDAPP_CONFIG_PAN_ID值不设置为0xFFFF时,那么设备建立或加入网络的PAN ID由ZDAPP_CONFIG_PAN_ID指定;如果设置ZDAPP_CONFIG_PAN_ID为0xFFFF,那么设备就将建立或加入一个“最优”的网络。
//-DZDAPP_CONFIG_PAN_ID=0xFFFF-DZDAPP_CONFIG_PAN_ID=0x2FFFIEEE 802.15.4/ZIGBEE规范在2.4G频段上规定了16各频道,用户可以通过选择DEFAULT_CHANLIST不同的值选择不同的频道,协议默认频道为0xB即0x00000800。
//-DDEFAULT_CHANLIST=0x04000000 // 26 - 0x1A//-DDEFAULT_CHANLIST=0x02000000 // 25 - 0x19-DDEFAULT_CHANLIST=0x01000000 // 24 - 0x18//-DDEFAULT_CHANLIST=0x00800000 // 23 - 0x17//-DDEFAULT_CHANLIST=0x00400000 // 22 - 0x16//-DDEFAULT_CHANLIST=0x00200000 // 21 - 0x15//-DDEFAULT_CHANLIST=0x00100000 // 20 - 0x14//-DDEFAULT_CHANLIST=0x00080000 // 19 - 0x13//-DDEFAULT_CHANLIST=0x00040000 // 18 - 0x12//-DDEFAULT_CHANLIST=0x00020000 // 17 - 0x11//-DDEFAULT_CHANLIST=0x00010000 // 16 - 0x10//-DDEFAULT_CHANLIST=0x00008000 // 15 - 0x0F//-DDEFAULT_CHANLIST=0x00004000 // 14 - 0x0E//-DDEFAULT_CHANLIST=0x00002000 // 13 - 0x0D//-DDEFAULT_CHANLIST=0x00001000 // 12 - 0x0C//-DDEFAULT_CHANLIST=0x00000800 // 11 - 0x0B2.网络结构(nwk_globals.h,nwk_globals.c)STACK_PROFILE_ID定义为NETWORK_SPECIFIC、 HOME_CONTROLS、BUILDING_AUTOMATION、GENERIC_STAR、GENERIC_TREE中的一个,默认为HOME_CONTROLS,并据此设置MAX_NODE_DEPTH、NWK_MODE等,具体如下:#define STACK_PROFILE_ID HOME_CONTROLS#if ( STACK_PROFILE_ID == HOME_CONTROLS )#define MAX_NODE_DEPTH 5#define NWK_MODE NWK_MODE_MESH#define SECURITY_MODE SECURITY_RESIDENTIAL#if ( SECURE != 0 )#define USE_NWK_SECURITY 1 // true or false#define SECURITY_LEVEL 5#else#define USE_NWK_SECURITY 0 // true or false#define SECURITY_LEVEL 0#endif网络最大设备数设定:#if !defined( NWK_MAX_DEVICE_LIST )#define NWK_MAX_DEVICE_LIST 20 // Maximum number of devices in the // Assoc/Device list.#endif路由器和终端设备数设定:#if defined ( RTR_NWK )// change this if using a different stack profile...// Cskip arrayuint16 *Cskip;#if ( STACK_PROFILE_ID == HOME_CONTROLS )byte CskipRtrs[MAX_NODE_DEPTH+1] = {6,6,6,6,6,0};byte CskipChldrn[MAX_NODE_DEPTH+1] = {20,20,20,20,20,0};#elif ( STACK_PROFILE_ID == GENERIC_STAR )byte CskipRtrs[MAX_NODE_DEPTH+1] = {5,5,5,5,5,0};byte CskipChldrn[MAX_NODE_DEPTH+1] = {5,5,5,5,5,0};#elif ( STACK_PROFILE_ID == NETWORK_SPECIFIC )byte CskipRtrs[MAX_NODE_DEPTH+1] = {5,5,5,5,5,0};byte CskipChldrn[MAX_NODE_DEPTH+1] = {5,5,5,5,5,0};#endif // STACK_PROFILE_ID#endif // RTR_NWK其中CskipRtrs和CskipChldrn分别为每一级的最大路由器数和最大节点数,前者是后者的子集。
Z-STACK按键
Z-STACK按键的使用总结#define HAL_KEY_SW_6_ENABLE// SW_6的IO端口#define HAL_KEY_SW_6_PORT P0//SW6接到IO端口的位数P0.1#define HAL_KEY_SW_6_BIT HAL_KEY_BIT1// SW_6的IO端口选择#define HAL_KEY_SW_6_SEL P0SEL// SW_6的IO端口方向#define HAL_KEY_SW_6_DIR P0DIR// SW_6的IO端口中断使能#define HAL_KEY_SW_6_IEN IEN1// SW_6的IO端口中断使能的掩码#define HAL_KEY_SW_6_IENBIT HAL_KEY_BIT5// SW_6的IO端口中断的边沿选择#define HAL_KEY_SW_6_EDGE HAL_KEY_RISING_EDGE // SW_6的IO端口边沿掩码#define HAL_KEY_SW_6_EDGEBIT HAL_KEY_BIT0// SW_6的IO端口总中断#define HAL_KEY_SW_6_ICTL PICTL// SW_6的IO端口总中断掩码#define HAL_KEY_SW_6_ICTLBIT HAL_KEY_BIT3// SW_6的IO端口中断标志位#define HAL_KEY_SW_6_PXIFG P0IFG按键主要使用的是IO来设置的,这里需要设置的参数主要有按键设置在哪个端口以及掩码、按键中断使能标志以及掩码、引起中断的上升沿还是下降沿以及掩码涉及的主要寄存器有PICTL端口输入中断控制IEN1端口0总中断使能IEN2 端口1和2总中断使能比如需要设置HAL_KEY_SW_6为P0.4为输入下降沿有效中断设置如下:#define HAL_KEY_SW_6_ENABLE#define HAL_KEY_SW_6_PORT P0#define HAL_KEY_SW_6_BIT HAL_KEY_BIT4#define HAL_KEY_SW_6_SEL P0SEL#define HAL_KEY_SW_6_DIR P0DIR#define HAL_KEY_SW_6_IEN IEN1#define HAL_KEY_SW_6_IENBIT HAL_KEY_BIT5#define HAL_KEY_SW_6_EDGE HAL_KEY_FALLING_EDGE#define HAL_KEY_SW_6_EDGEBIT HAL_KEY_BIT0#define HAL_KEY_SW_6_ICTL PICTL#define HAL_KEY_SW_6_ICTLBIT HAL_KEY_BIT4#define HAL_KEY_SW_6_PXIFG P0IFG比如需要设置HAL_KEY_SW_6为P2.1为输入上升沿有效中断设置如下:#define HAL_KEY_SW_6_ENABLE#define HAL_KEY_SW_6_PORT P2#define HAL_KEY_SW_6_BIT HAL_KEY_BIT4#define HAL_KEY_SW_6_SEL P2SEL#define HAL_KEY_SW_6_DIR P2DIR#define HAL_KEY_SW_6_IEN IEN2#define HAL_KEY_SW_6_IENBIT HAL_KEY_BIT1#define HAL_KEY_SW_6_EDGE HAL_KEY_RISING_EDGE#define HAL_KEY_SW_6_EDGEBIT HAL_KEY_BIT2#define HAL_KEY_SW_6_ICTL PICTL#define HAL_KEY_SW_6_ICTLBIT HAL_KEY_BIT5#define HAL_KEY_SW_6_PXIFG P2IFG这样设置后就可以正常使用KEY 中断。
z-stack协议栈串口驱动详解与同时使用两个串口的配置方法
Z-Stack串口操作:CC2530共有两个串口,UART0和UART1,两个串口可以通过设置寄存器PERCFG的值映射到不同的引脚上,对应的映射关系如下:在CC2530中提供了两种方式来操作串口,即直接存取访问(DMA)和中断(ISR)方式,两种操作方式的区别在这里不再叙述,想了解的请自行查阅相关资料。
在z-stack中默认的使用DMA方式来操作串口,默认配置的串口为UART0,UART0默认使用位置1,即P02为UART的RX,P03为UART的TX。
接下来将详细介一下Z-STACK串口默认的配置流程,并介绍如何配置同时使用两个串口。
一、串口默认配置的流程从main函数开始,串口的初始化化函数在调用HalDriverInit()函数时被调用,在HalDriverInit函数中调用了函数HalUARTInit()函数,函数原型如下:void HalUARTInit(void){#if HAL_UART_DMAHalUARTInitDMA();#endif#if HAL_UART_ISRHalUARTInitISR();#endif#if HAL_UART_USBHalUARTInitUSB();#endif}可以看出,协议栈通过判断宏定义的方法来判断以何种方式来初始化串口,有关的宏可以在hal_board_cfg.h中找到,先将与串口有关的宏列出以便分析:* Set to TRUE enable UART usage, FALSE disable it */#ifndef HAL_UART //如果未定义HAL_UART/*如果定义了defined ZAPP_P1、defined ZAPP_P2、defined ZTOOL_P1、defined ZTOOL_P2中的一个,就定义HAL_UART为1,协议栈默认地定义了ZTOOL_P1,可以点击project->options->c/c++complier->preprocess->defined symbols来查看预编译的宏*/#if (defined ZAPP_P1) || (defined ZAPP_P2) || (defined ZTOOL_P1) || (defined ZTOOL_P2) #define HAL_UART TRUE#else //否则的话在进行下面的#define HAL_UART FALSE //将HAL_UART定义为0,即不使用串口#endif#endif#if HAL_UART //如果HAL_UART为1// Always prefer to use DMA over ISR.总是优先地使用DMA方式#if HAL_DMA#ifndef HAL_UART_DMA#if (defined ZAPP_P1) || (defined ZTOOL_P1)#define HAL_UART_DMA 1#elif (defined ZAPP_P2) || (defined ZTOOL_P2)#define HAL_UART_DMA 2#else#define HAL_UART_DMA 1#endif#endif/*执行完上面的一部分代码后,HAL_UART_DMA的值就为1了,具体自行分析#define HAL_UART_ISR 0 //默认不实用ISR方式来处理中断/*在这里已经定义了HAL_UART_ISR,所以就不会进入下面的#ifndef HAL_UART_ISR判断了*/#else#ifndef HAL_UART_ISR#if (defined ZAPP_P1) || (defined ZTOOL_P1)#define HAL_UART_ISR 1#elif (defined ZAPP_P2) || (defined ZTOOL_P2)#define HAL_UART_ISR 2#else#define HAL_UART_ISR 1#endif#endif#define HAL_UART_DMA 0#endif/*执行完上面的代码后,HAL_UART_ISR就被定义为0了*/// Used to set P2 priority - USART0 over USART1 if both are defined.#if ((HAL_UART_DMA == 1) || (HAL_UART_ISR == 1))#define HAL_UART_PRIPO 0x00#else#define HAL_UART_PRIPO 0x40#endif/*上述代码设置了两个串口的优先级,串口0大于串口1*//*这里的#else对应的是#if HAL_UART,意思就是如果串口使用,就将两种方式的宏都定义为0*/#else#define HAL_UART_DMA 0#define HAL_UART_ISR 0#endif/* USB is not used for CC2530 configuration */#define HAL_UART_USB 0上述代码的if和else对应的关系可能很难看出,可以用notepad打开源文件来查看对应关系。
基于Z-Stack的串口透传
目录
一、实训目的 二、实训内容 三、实训原理 四、实训步骤
实训目的
通过实训,对Z-Stack有更进一步的了解,了解Z-Stack网络 节点的类型和功能,能实现模块之间无线串口通信。
目录
一、实训目的 二、实训电脑A与电脑B分别连接一块ZigBee模块,再用串口收发信息, 实现串口透传。
目录
一、实训目的 二、实训内容 三、实训原理 四、实训步骤
实训原理
参照实训10、实训11等内容。
目录
一、实训目的 二、实训内容 三、实训原理 四、实训步骤
实训步骤
第一步,打开Z-Stack的SampleApp.eww工程。 具体参考实训10的操作。 第二步,修改Coordinator.h 在文件中增加以下代码: //应用事件 #define SAMPLEAPP_SEND_PERIODIC_MSG_EVT 0x0001 #define SAMPLEAPP_READ_PERIODIC_MSG_EVT 0x0002 #define SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT 50 00 // 每5秒一次
实训步骤
第五步,下载程序、运行。 编 译 无 误 , 在 Workspace 下 面 的 下 拉 列 表 框 中 选 择 CoordinatorEB把协调器程序下载到ZigBee模块中,再在Workspace下 面的下拉列表框中选择EndDeviceEB把将终端节点程序下载到另一块 ZigBee模块。用串口线将协调器与电脑连接,终端节点也通过串口与 电脑相连接,可以是同一台电脑也可以是不同电脑,但是距离必须在 ZigBee的通信范围内。然后,打开两个串口调试助手,设置波特率为 115200,打开串口,然后会看到连接灯点亮,说明网络正常,在串口 调试窗口分别输入“Hello,NEWLab1!”和“Hello,NEWLab2!”,单击
基于Zstack的串口控制LED 实验报告
西北师范大学计算机科学与工程学院课程实验报告实验设计思想描述及实验原理1.ZIGBEE(CC2530)模块LED硬件接口 :ZIGBEE(CC2530)模块硬件上设计有2个LED灯,用来编程调试使用。
分别连接CC2530的P1_0、P、1_1两个IO引脚。
从原理图上可以看出,2个LED灯共阳极,当P1_0、P1_1引脚为低电平时候,LED灯点亮。
2. SampleApp实验简介:SampleApp实验是协议栈自带的ZIGBEE无线网络自启动(组网)样例,该实验实现的功能主要是协调器自启动(组网),节点设备自动入网。
之后两者建立无线通讯,数据的发送主要有2中方式,一种为周期定时发送信息(本次实验采用该方法测试),另一种需要通过按键事件触发发送FLASH信息。
由于实验配套ZIGBEE模块硬件上与TI公司的ZIGBEE样板有差异,因此本次实验没有采用按键触发方式。
Periodic消息是通过系统定时器开启并定时广播到group1出去的,因此在SampleApp_ProcessEvent事件处理函数中有如下定时器代码:当设备加入到网络后,其状态就会变化,对所有任务触发ZDO_STATE_CHANGE事件,开启一个定时器。
当定时时间一到,就触发广播periodic消息事件,触发事件SAMPLEAPP_SEND_PERIODIC_MSG_EVT,相应任务为SampleApp_TaskID,于是再次调用SampleApp_ProcessEvent()处理SAMPLEAPP_SEND_PERIODIC_MSG_EVT事件,该事件处理函数调用SampleApp_SendPeriodicMessage()来发送周期信息。
3. MT层串口通讯:协议栈将串口通讯部分放到了MT层的MT任务中去处理了,因此我们在使用串口通讯的时候要在编译工程(通常是协调器工程)时候在编译选项中加入MT层相关任务的支持:MT_TASK,ZTOOL_P1 或ZAPP_P1。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
它到底有什么意义。 cfg->rxHead = cfg->rxTail = 0; 在打开串口中有这么赋值,把它初始化为 0. 其实从上面那个中断函数就已经把这个参数的功能体现的淋漓尽致了: 就是串口接收数据,这个参数始终指向像一个参数被存放到 rxBuf 的位置。因为硬件串口缓 存器 U0DBUF 只能存放一个字节,如果不及时把这个接收到的转移出去,那么就会被下一个到 来的字节覆盖掉,所以 rxHead 变量就指向了这个存放的地址,当然是基于定义的 rxBuf 存储 空间。相当于一个数组赋值,那么必然有个变量会指向该数组的下一个赋值的参数,当然这 个变量的最终值也能在一定程度上体现这个被赋值数组的大小。所以 rxHead 在这里起到了类 似的作用,而 if ( cfg0->rxHead == cfg0->rxMax )这一句判断也说明的很清楚,一旦这个 计数达到了定义的最大接收数量,也就是说已经把 rxBuf 存储空间占满了,那么就不能在继 续存放了,否则存放的位置就未知,而且有可能造成程序中其他变量的损坏,那么这个时候 如果串口还有数据怎么办?那就需要把 rxBuf 清空在接收了,否则就会丢失数据。 3、uint8 rxTail; 这个变量就与上面提到的清空 rxBuf 密切相关了。 while ( (cfg->rxTail != cfg->rxHead) && (cnt < len) ) {
}
/* It is necessary to stop Rx flow in advance of a full Rx buffer because
* bytes can keep coming while sending H/W fifo flushes.
*/
if ( cfg->rxCnt >= (cfg->rxMax - SAFE_RX_MIN) )
还是藏的很隐蔽就是了,呵呵!!!!关于这个 128 我是做个实验的,在串口互发的实验也是定
义的 128.多了就会丢掉!这个下次有机会在说。
5、uint8 rxCnt ;
static void pollISR( uartCfg_t *cfg )
{
uint8 cnt = UART_RX_AVAIL( cfg );
cfg0->rxHead = 0; } else {
cfg0->rxHead++; } } 这个是串口 0 中断函数:其中 cfg0->rxBuf[cfg0->rxHead] = U0DBUF,显然是把 U0DBUF 中 的数据转移到存储区去。 从这个函数中还能看出两个问题: rxHead 是否用作了串口接收计数,而 rxMax 代表最大的接收数据长度。 2、uint8 rxHead 字面理解为接收头,但是上面已经提到了似乎起到了串口接收计数的功能。那下面就来看看
走的数据。首先从字面理解 avail 为“效用”的意思,那么扩展下为 available,那么意思
就是“有用的”“有空的”,呵呵!只有理解其实也很有意思哈。
再从后面的判断语句,cfg->rxHead - cfg->rxTail,由于有上面的讲解,理解这个就很容易 了,有的数据数量-已经取走的数据数量,那么就省还有多少各有用的数据量。 而 cfg->rxMax - cfg->rxTail + cfg->rxHead +1 理解就需要转个弯了,因为此时 cfg->rxHead > cfg->rxTail,那么什么情况下才满足这种条件呢,只有一种情况,rxHead 已经是第二轮 接收计数了,而 rxTail 还在上一轮取数。cfg->rxMax - cfg->rxTail,也就是第一轮把 rxBuf 填满的数据取走 cfg->rxTail,那么就是第一轮剩下又有的数据,那么在+ cfg->rxHead 这个, 就 是 加 上 cfg->rxHead 第 二 轮 接 收 的 数 据 , 至 于 后 面 +1 的 理 解 为 cfg->rxBuf = osal_mem_alloc( cfg->rxMax+1) , 分 配 存 储 空 间 本 来 就 比 rxMax 多 分 了 一 个 。 ------------------------------这里我仍然有疑惑,谁有深刻的理解欢迎交流! 而 if ( cfg->rxCnt >= (cfg->rxMax - SAFE_RX_MIN) )这里理解就更微妙了,表明接收缓 存空间已经满了,所以下面就 RX_STOP_FLOW( cfg ); #define RX_STOP_FLOW( cfg ) { \ if ( !(cfg->flag & UART_CFG_U1F) ) \ {\
{
RX_STOP_FLOW( cfg );
ቤተ መጻሕፍቲ ባይዱ
}
}
}
就这个函数使用这个参数最典型了。
关心的第一句不 if ( cfg->rxCnt != cnt )一开始就与 cnt 变量有关系,而且更加过分的是
在里面直接 cfg->rxCnt = cnt,所以不得不关系下 cnt 了。
uint8 cnt = UART_RX_AVAIL( cfg );这个函数的第一句,而:
if ( !(cfg->flag & UART_CFG_RXF) )
{
// If anything received, reset the Rx idle timer.
if ( cfg->rxCnt != cnt )
{
cfg->rxTick = HAL_UART_RX_IDLE;
cfg->rxCnt = cnt;
zstack 串口使用指南.txt 如果不懂就说出来,如果懂了,就笑笑别说出来。贪婪是最真实 的贫穷,满足是最真实的财富。幽默就是一个人想哭的时候还有笑的兴致。转载 zstack 串 口使用指南 2009-05-04 02:00Z-STACK 问题之串口结构 uartCfg_t 乱说
typedef struct { uint8 *rxBuf;//接收缓存 uint8 rxHead;//头 uint8 rxTail;//尾 uint8 rxMax;//接收最大长度 uint8 rxCnt;//计数 uint8 rxTick;//时间 uint8 rxHigh;//高位 uint8 *txBuf; #if HAL_UART_BIG_TX_BUF uint16 txHead; uint16 txTail; uint16 txMax; uint16 txCnt; #else uint8 txHead; uint8 txTail; uint8 txMax; uint8 txCnt; #endif uint8 txTick; uint8 flag;//标志位 halUARTCBack_t rxCB; } uartCfg_t; 有个朋友问我上面的问题,说句老实话,我可是第一次见这个东东,拿到手之后比我那朋友 还迷糊,那位朋友至少还知道大概是什么功能,仅仅是不清楚每个参数的具体含义和功能。 为了解决这个问题,我可是遍寻名家,最终结果是人家也不是很清楚,因为平常大家只管用, 哪管那么多这些具体细节?没办法,我只有自己解决了,希望我的努力能给大家一点点启示! 首先说说这个结构的应用范畴,它是直接面向串口的应用层,也就是与客户接触的还是比较 紧密的一个结构,一般是在串口接收数据和发送数据的时候使用。而串口有两种方式,一种 是普通的串口,一种是 DMA 方式。这里我只针对普通串口来分析这个结构。 首先来看看这个结构在什么地方用到了? static void pollDMA( uartCfg_t *cfg ) static void pollISR( uartCfg_t *cfg ) 这两个函数直接就用到了这个结构作为参数,应该说是联系最紧密的了,是我们重点剖析的 对象了,但是这里不看 DMA,因为这个俺很外行----------哈哈!!!! uint16 HalUARTRead( uint8 port, uint8 *buf, uint16 len ) uint8 HalUARTOpen( uint8 port, halUARTCfg_t *config )
*buf++ = cfg->rxBuf[cfg->rxTail]; if ( cfg->rxTail == cfg->rxMax ) {
cfg->rxTail = 0; } else {
cfg->rxTail++; } cnt++; } 这里是在 uint16 HalUARTRead( uint8 port, uint8 *buf, uint16 len )函数中调用的,实 际上把 rxBuf 空间的数据读走,然后 rxBuf 可以继续串口数据的接收了。可以看到*buf++ = cfg->rxBuf[cfg->rxTail]这个是在转移数据,而转移多少的计数是以 rxTail 来计数的。一 旦计数达到 rxMax,那么该计数归 0,因为 rxMax 定义了 rxBuf 的最大的数据量。 这里需要强调一点:rxTail 和 rxHead 的区别。 我第一眼看到这个两个变量的反应是:rxHead 为串口数据串接收的头,而 rxTail 为串口数 据串接收的尾(结束),因为这样理解符合我们平常编写串口通信协议习惯,有头有尾。但是 仔细看了只有,虽然也是头与尾的概念,但是却不应该这么理解。 rxTail 和 rxHead 应该是针对 rxBuf 来说的。rxHead 是往 rxBuf 装数据的计数,而 rxTail 是从 rxBuf 取走数据的计数。希望这个一定要注意。所以我们就不难理解:rxHead 是在串口 接收中断的时候强调使用,而 rxTail 是在 HalUARTRead 函数中使用了。这里还需要注意一点 点,HalUARTRead 并不是读取 UxBUF 数据,而是读取 rxBuf 中数据。 其实仔细想想,这两个参数还是与串口的头和尾有关的。头又名开始,串口接收数据开始存 放数据的指向;尾又名结束,是把串口数据取走用作他用的指向。rxHead=0,标示串口接收 数据新的起点,新的开始;而 rxTail=0,标示把串口接收到的数据全部取走用作他用,-----结束。体现了串口数据从接收到被使用的整个过程。