第一范文网 - 专业文章范例文档资料分享平台

z-stack协议栈串口驱动详解与同时使用两个串口的配置方法

来源:用户分享 时间:2020-06-30 本文由-醉影伴着 分享 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

Z-Stack串口操作:

CC2530共有两个串口,UART0和UART1,两个串口可以通过设置寄存器PERCFG的值映射到不同的引脚上,对应的映射关系如下:

端口 串口0 位置1 位置2 串口1 位置1 位置2 P0 5 RT RX P1 4 3 2 7 CT TX RX TX RT CT RX 6 TX 5 TX RT 4 RX CT 3 RT 2 CT

PERCFG寄存器相关位的描述如下: 位 名称 复位 1 U1CFG 0 0 U0CFG 0 读/写 读/写 读/写 描述 串口1端口映射。0:位置1;1:位置2 串口0端口映射。0:位置1;1:位置2 在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_DMA HalUARTInitDMA(); #endif

#if HAL_UART_ISR HalUARTInitISR(); #endif

#if HAL_UART_USB HalUARTInitUSB(); #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打开源文件来查看对应关系。

总结一下,上述代码完成的功能就是将HAL_UART_DMA宏设置为1,将HAL_UART_ISR宏设置为0。

然后我们再回到HalUARTInit(void)函数,可以看出在这里调用的串口初始化函数是HalUARTInitDMA()函数,函数原型如下(省略了部分不必要的代码): static void HalUARTInitDMA(void) {

halDMADesc_t *ch; //定义了一个DMA通道 /*设置串口优先级*/ P2DIR &= ~P2DIR_PRIPO; P2DIR |= HAL_UART_PRIPO;

#if (HAL_UART_DMA == 1) //默认配置会执行这里的语句 /*设置UART0在位置1,P0口*/

PERCFG &= ~HAL_UART_PERCFG_BIT; // Set UART0 I/O to Alt. 1 location on P0. #else

/*否则的话UART0在位置2,P1口*/

PERCFG |= HAL_UART_PERCFG_BIT; // Set UART1 I/O to Alt. 2 location on P1. #endif

/*设置P0口的P02、P03为外设功能,P02为RX、P03为TX*/ PxSEL |= HAL_UART_Px_RX_TX; // Enable Tx and Rx on P1.

/*禁用P02和P03的ADC功能,以防止对串口通信产生干扰。TI的工程师是挺细心的,其实我们在使用的时候也不会傻到把这两个端口硬件连接为ADC吧*/

ADCCFG &= ~HAL_UART_Px_RX_TX; // Make sure ADC doesnt use this. /*设置为UART模式,还可配置为SPI模式*/

UxCSR = CSR_MODE; // Mode is UART Mode. /**清除单元/

UxUCR = UCR_FLUSH; // Flush it. /*未列出DMA初始化的一些代码*/ ……………………. }

上面的函数执行完成以后就基本上完成了串口的初始化,包括串口处理方式、串口对应的引脚等,进一步的串口初始化设置在HalUARTOpenDMA(halUARTCfg_t *config)函数中被完成,该函数的原型如下,在看懂这个函数之前我们需要先了解一下结构体halUARTCfg_t这个结构

体的定义在hal_uart.h文件中,原型如下: typedef struct {

bool configured; //是否注册串口

uint8 baudRate; //串口通信波特率设置 bool flowControl; //硬件流控制

uint16 flowControlThreshold; //don’t care uint8 idleTimeout; //don’t care halUARTBufControl_t rx; //don’t care halUARTBufControl_t tx; //don’t care

bool intEnable; //don’t care uint32 rxChRvdTime; //don’t care halUARTCBack_t callBackFunc; //串口回调函数 }halUARTCfg_t;

可以看出上述结构体完成了串口初始化所需要的各项参数,包括在OSAL中注册串口,通信波特率的设置等,同时HalUARTOpenDMA函数的形参也是这个结构体,也就是说这些初始化将在这个函数中被完成,下面来通过注释来分析这个函数。 static void HalUARTOpenDMA(halUARTCfg_t *config) {

/*注册串口回调函数,串口收到数据后会调用回调函数*/ dmaCfg.uartCB = config->callBackFunc; /

// Only supporting subset of baudrate for code size - other is possible. HAL_UART_ASSERT((config->baudRate == HAL_UART_BR_9600) || (config->baudRate == HAL_UART_BR_19200) || (config->baudRate == HAL_UART_BR_38400) || (config->baudRate == HAL_UART_BR_57600) || (config->baudRate == HAL_UART_BR_115200));

if (config->baudRate == HAL_UART_BR_57600 || config->baudRate == HAL_UART_BR_115200) {

UxBAUD = 216; } else {

UxBAUD = 59; }

switch (config->baudRate) {

case HAL_UART_BR_9600: UxGCR = 8;

dmaCfg.txTick = 35; // (32768Hz / (9600bps / 10 bits))

// 10 bits include start and stop bits.

break;

case HAL_UART_BR_19200: UxGCR = 9;

dmaCfg.txTick = 18; break;

case HAL_UART_BR_38400: UxGCR = 10;

dmaCfg.txTick = 9; break;

case HAL_UART_BR_57600: UxGCR = 10;

dmaCfg.txTick = 6; break; default:

// HAL_UART_BR_115200 UxGCR = 11;

dmaCfg.txTick = 3; break; }

/*上面的部分代码通过switch判断完成了对串口波特率的设置,具体的寄存器值可以参考下面的波特率寄存器设置表*/

// 8 bits/char; no parity; 1 stop bit; stop bit hi. if (config->flowControl) {

UxUCR = UCR_FLOW | UCR_STOP; PxSEL |= HAL_UART_Px_CTS;

// DMA Rx is always on (self-resetting). So flow must be controlled by the S/W polling the Rx

// buffer level. Start by allowing flow. PxOUT &= ~HAL_UART_Px_RTS; PxDIR |= HAL_UART_Px_RTS; } else {

UxUCR = UCR_STOP; //停止位为高电平 }

/*don’t care*/

dmaCfg.rxBuf[0] = *(volatile uint8 *)DMA_UDBUF; // Clear the DMA Rx trigger. HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_RX); HAL_DMA_ARM_CH(HAL_DMA_CH_RX);

osal_memset(dmaCfg.rxBuf, (DMA_PAD ^ 0xFF), HAL_UART_DMA_RX_MAX*2);

UxCSR |= CSR_RE;

搜索“diyifanwen.net”或“第一范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,第一范文网,提供最新教学研究z-stack协议栈串口驱动详解与同时使用两个串口的配置方法 全文阅读和word下载服务。

z-stack协议栈串口驱动详解与同时使用两个串口的配置方法 .doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/wenku/1108719.html(转载请注明文章来源)
热门推荐
Copyright © 2018-2022 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top