实验现象: 模块通过串口发送“HELLO WEBEE! ”给电脑串口调试助手打印出来。整个实验在协议栈(TI z-stack 2.5.1a)中进行。用上一节的链接即可下载
整个例程很简单,分三步走,实际上就是三个语句,不过我们可以了解一下具体原理:代码不好啃,想长命一点的还是看教程吧。步骤如下:
1、串口初始化
2、登记任务号
3、串口发送
我们打开 Z-stack 目录 Projects\zstack\Samples\ SamplesAPP\CC2530DB里面的 SampleApp.eww 工程。这次试验我们直接基于协议栈的SampleApp 来进行。
打开工程后,可以看到上一节说到 workspace 目录下比较重要的两个文件夹, Zmain 和 App。这里我们主要用到 App,这也是用户自己添加自己代码的地方。
主要在 SampleApp.c 和 SampleApp.h 中就可以了,
第一步:串口初始化
串口初始化很熟悉了,就是配置串口号、波特率、流控、校验位等等。以 前都 是 配 置 好 寄存 器 然 后 使 用 。
现 在 我 们 在 workspace 下 找 到HAL\Target\CC2530EB\drivers 的 hal_uart.c 文件,我们可以看到里面已经包括了串口初始化、发送、接收等函数, 很是方便
浏览一下关于串口的操作函数还是挺全的,但是好的东西还在后面!!!workspace 上的 MT 层,发觉有很多基本函数,前面带 MT。包括 MT_UART.C,我们打开这个文件。
看到 MT_UartInit()函数,这里也有一个串口初始化函数的,Z-stack 上有一个 MT 层,用户可以选用 MT 层配置和调用其他驱动。进一步简化了操作流程。然后在 SampleApp 的文件下面加入初始化函数。
打开 APP目录下的 OSAL_SampleApp.C 文件,找到上节提到的 osalInitTasks()任务初始化函数中的 SampleApp_Init ()函数,
进入这个函数,发现原来在 SampleApp.c文件中。在这里加入串口初始化代 码
/**********串口初始化***************/ MT_UartInit ();
进入 MT_UartInit();,修改自己想要的初始化配置,代码如下。
/*************************************************************************************************** * @fn MT_UartInit * * @brief Initialize MT with UART support * * @param None * * @return None ***************************************************************************************************/ void MT_UartInit () { halUARTCfg_t uartConfig; /* Initialize APP ID */ App_TaskID = 0; /* UART Configuration */ uartConfig.configured = TRUE; uartConfig.baudRate = MT_UART_DEFAULT_BAUDRATE; uartConfig.flowControl = MT_UART_DEFAULT_OVERFLOW; uartConfig.flowControlThreshold = MT_UART_DEFAULT_THRESHOLD; uartConfig.rx.maxBufSize = MT_UART_DEFAULT_MAX_RX_BUFF; uartConfig.tx.maxBufSize = MT_UART_DEFAULT_MAX_TX_BUFF; uartConfig.idleTimeout = MT_UART_DEFAULT_IDLE_TIMEOUT; uartConfig.intEnable = TRUE; #if defined (ZTOOL_P1) || defined (ZTOOL_P2) uartConfig.callBackFunc = MT_UartProcessZToolData; #elif defined (ZAPP_P1) || defined (ZAPP_P2) uartConfig.callBackFunc = MT_UartProcessZAppData; #else uartConfig.callBackFunc = NULL; #endif /* Start UART */ #if defined (MT_UART_DEFAULT_PORT) HalUARTOpen (MT_UART_DEFAULT_PORT, &uartConfig); #else /* Silence IAR compiler warning */ (void)uartConfig; #endif /* Initialize for ZApp */ #if defined (ZAPP_P1) || defined (ZAPP_P2) /* Default max bytes that ZAPP can take */ MT_UartMaxZAppBufLen = 1; MT_UartZAppRxStatus = MT_UART_ZAPP_RX_READY; #endif }
uartConfig.baudRate = MT_UART_DEFAULT_BAUDRATE; 是配置波特率,我们 go to definition of MT_UART_DEFAULT_BAUDRATE,可以看到:
#define MT_UART_DEFAULT_BAUDRATE HAL_UART_BR_38400
默认的波特率是 38400bps,现在我们修改成 115200bps,修改如下:
#define MT_UART_DEFAULT_BAUDRATE HAL_UART_BR_115200
uartConfig.flowControl = MT_UART_DEFAULT_OVERFLOW; 语句是配置流控的,我们进入定义可以看到:
#define MT_UART_DEFAULT_OVERFLOW TRUE
默认是打开串口流控的,如果你是只连了 TX/RX 2 根线的方式务必关流控,像功能底板一样。
#define MT_UART_DEFAULT_OVERFLOW FALSE
注意: 2 根线的通讯连接务必关流控,不然是永远收发不了信息的。
根据预先定义的 ZTOOL 或者 ZAPP 选择不同的数据处理函数。后面的 P1 和 P2 则是串口 0 和串口 1。我用ZTOOL,串口 0。
可以在 option——C/C++ 的CompilerPreprocessor 里面看到,已经默认添加 ZTOOL_P1 预编译。
第二步:登记任务号
在 SampleApp_Init();刚添加的串口初始化语句下面加入语句:
MT_UartRegisterTaskID(task_id);//登记任务号
意思就是把串口事件通过 task_id 登记在 SampleApp_Init();
第三步:串口发送
经过前面两个步骤,现在串口已经可以发送信息了。我们在刚刚添加初始化代码后面加入一条上电提示 Hello World 的语句。
HalUARTWrite(0,”Hello World\n”,12); (串口 0, ‘字符’,字符个数。)
提示:需要在 SampleApp.c 这个文件里加入头文件语句: #include “MT_UART.h
连接仿真器和 USB 转串口线,选择 CoordinatorEB,点解下载并调试。全速运行,可以看到串口助手收到信息。
但是我们发现 Hello World 后面有一小段乱码。这是 Z-stack MT 层定义的串口发送格式,还有液晶提示信息。解决办法为:
在预编译地方把 MT 和 LCD 相关内容注释。如:
ZTOOL_P1
xMT_TASK
xMT_SYS_FUNC
xMT_ZDO_FUNC
xLCD_SUPPORTED=DEBUG
xMT_TASK:表示没有定义 MT_TASK,也就是不定义了。 其他几项也用这种方法,我们把改好的重新编译再下载,按复位键,观察串口已经没有乱码了。
拓展:
我们在协议栈里再做一个测试,在 osal_start_system()函数里 for(;;)里加入:HalUARTWrite(0,”Hello,WeBee\n”,12);如图 3.37,下载运行后发现串口不停地接收到 Hello WeBee。
这就证明了前一节的协议栈运行后会在这个函数里不停地循环查询任务、执行任务。注意这只是一个演示用的方法,实际应用中可千万不能有把串口发送函数弄到这个位置然后给 PC 发信息的想法,
因为这破坏了协议栈任务轮询的工作原则,相当于我们普通单片机不停用 Delay 延时函数一样,是极其低效的。