ZigBee组网-基于协议栈的UART实验(实现收发)(保姆级)

news/2024/11/8 0:45:30/

目录

基于协议栈的UART实验

前言

协议栈中的TI自带UART的使用实验

UART配置基本步骤

串口初始化

串口发送

串口接收回显

实验效果

拓展

移植我们自己UART串口

移植配置过程

实验效果


基于协议栈的UART实验

前言

        与之前的Zigbee裸机实验不同,我们既可以使用CC2530的裸机串口实验的UART作为BSP支持包移植到我们的Zstack协议栈中来使用,也可以使用TI协议栈自带的UART。但这两种方法都需要进行配置。

        我今天在做Zigbee单播实验的过程中就想把前面学习的裸机串口直接改改来过来用,结果发现根本用不了,不仅串口收发不了数据,还导致CC2530模块卡死,连协议栈的其它功能也被毁掉了。

        后来通过查阅资料和自己一晚上的琢磨,成功实现了协议栈中UART的使用,实现了串口与电脑上位机的收发通信。

        接下来进行Zigbee协议栈中的UART的两种使用方法的讲解。

注:本文参考于:

https://www.cnblogs.com/sjsxk/p/5365705.html

ZigBee组网学习笔记(三 )--协议栈串口实验_协议栈 ztool_p1_李国冬的博客-CSDN博客

学习记录 | ZigBee协议栈实践——串口收发数据_keil zigbee_智慧益力多的博客-CSDN博客

协议栈中的TI自带UART的使用实验

UART配置基本步骤

我们裸机使用串口功能的步骤是:

        (1) 串口初始化;

        (2) 执行任务(发送/接收)。

其实,跟裸机实验里的串口实验一样,本实验也是按照同样的步骤来进行的,第(1)步不变;在第(1)步和第(2)步之间需要多做了一步,就是:给它登记一下;第(2)步照样执行。所以,本实验使用串口的具体步骤是:

        (1) 串口初始化;

        (2) 登记任务号;

        (3) 执行任务。

下面分别介绍各个步骤。

串口初始化

        以前,配置串口号、波特率、流控、校验位,配置好寄存器,然后使用。

        现在,在workspace下找到HAL\Target\CC2530EB\drivers的hal_uart.c文件,可以看到里面已经包括了串口初始化、发送、接收等函数。

        workspace上的MT层,发觉有很多基本函数,前面带MT。包括MT_UART.C,我们打开这个文件。看到MT_UartInit()函数,这里也有一个串口初始化函数,没错Z-stack上有一个MT层,用户可以选用MT层配置和调用其他驱动。进一步简化了操作流程。

        跟裸机的实验一样,我们也要配置串口号、波特率、流控,校验位等,以前我们要配置相关的寄存器,现在我们可以直接通过库函数来控制。打开MT_UART.c。然后找到MT_UartInit ()函数。

MT_UartInit ()函数如下面的代码所示

        我们可以看出,这跟我们普通的串口配置没有太大区别,都是要配置串口所需要的初始化,在这个实验中,我们要修改的就是波特率和流控制,波特率要修改和配置成115200,和连接串口的上位机保持一致,流控制也要关闭,赋值false,因为我们只需要用到RX、TX 两根线,所以不需要额外的流控制。

通过定位跳转,我们可以发现波特率有以下选择

同样定位发现TRUE是1,FALSE是0,所以放心修改。


注意:

#define MT_UART_DEFAULT_BAUDRATE HAL_UART_BR_38400 默认的波特率是 38400bps,波特率不能设置太低,会导致收发数据出现过高延时。

#define MT_UART_DEFAULT_OVERFLOW TRUE

默认是打开串口流控的,如果你是只连了 TX/RX 2 根线的方式务必关流控,本功能底板只连了 TX/RX 2 根线,要改为FALSE

#define MT_UART_DEFAULT_OVERFLOW FALSE

此外再次强调:2 根线的通讯连接务必关流控,不然是永远收发不了信息的。


修改完之后,我们在SampleApp_Init( uint8 task_id )函数调用配置好的MT_UartInit ()函数;然后,记得在SampleApp.c 文件开头的地方将图所示的头文件include 进去。

(由于我的Zstack被我移植过了,所有的SampleApp都被我修改成了StarryApp)

登记任务号

这也是跟裸机串口发送有所区别的地方,只有登记了任务号,系统才会执行这个函数的功能,相当于去旅店住房要去登记一样,服务员会根据客房情况给你安排房间。登记任务号我们是用MT_UartRegisterTaskID(task_id)函数,来登记串口方面的任务号。

串口发送

使用语句: HalUARTWrite(0,”Hello World\n”,12); //(串口 0,‘字符’,字符个数(不包括'\0')。)

也可以写成 HalUARTWrite(0,”Hello World\n”,sizeof("Hello World\n")-1);

我这里再main函数中调用

该函数在hal_uart.c中被定义

注意:发现烧入程序后,串口打印出来的 Hello World 后面有一小段乱码。这是 Z-stack MT 层定义的串口发送格式,还有液晶提示信息。

我们可以在预编译地方把 MT 和 LCD 相关内容 注释掉(IAR 与 KEIL 中的STM32的预定义宏有些类似)。如下:

ZTOOL_P1

xMT_TASK

xMT_SYS_FUNC

xMT_ZDO_FUNC

xLCD_SUPPORTED=DEBUG

xMT_TASK:表示没有定义 MT_TASK,也就是不定义了。

修改前:

修改后:

用 ZTOOL,串口 0。我们可以在 option——C/C++ 的 CompilerPreprocessor 里 面看到,已经默认添加 ZTOOL_P1 预编译。

(其中ZTOOL_P1 --- 串口0 ZTOOL_P2 --- 串口1 )

改好的重新编译再下载,按复位键,观察串口已经没有乱码了。

串口接收回显

下面我们继续来实现将串口收到的数据发送回给发送方上位机。

首先这里需要自己写一个串口接收回调函数,函数名可以自定义

void My_UART_RxReturn( uint8 port, uint8 event )
{unsigned char buf[30];unsigned char len;len = HalUARTRead(0,  buf, 30);//读取串口数据,返回数据长度if(len){HalUARTWrite(0, buf, len);//通过串口原样返回数据 也可以修改数据返回用于区分数据len = 0;}
}

然后将其定义在hal_uart.c中,还要注意要在头文件声明

最后一定要记得把MT_UartInit中的串口回调函数改成自己刚刚定义的串口接收回调函数

实验效果

拓展

我们在协议栈里再做一个测试,在 osal_start_system()函数里 for(;;)里加入:

HalUARTWrite(0,”Hello,World\n”,12);

下载运行后发现串口不停地接收到 Hello,World。

这就证明了前一节的协议栈运行后会在这个函数里不停地循环查询任务、执行任务。

这只是一个演示用的方法,实际应用中你可 千万不能有把串口发送函数弄到这个位置,然后给 PC 发信息。

因为这 破坏了协议栈任务轮询的工作原则,相当于我们普通单片机不停用 Delay 延时函数一样,是极其低效的。

移植我们自己UART串口

移植配置过程

我们将自己的串口BSP文件拷贝并添加到工程中来,以便于与上面的TI串口收发做区分,我们自己的串口初始化使用9600波特率。

starry_uart.h

#ifndef _STARRY_UART_H
#define _STARRY_UART_H
#include <iocc2530.h>void delay_us(void);
void Init32M(void);
void delay_ms(int ms);
void Uart_Config(void);
void String_Print(unsigned char *str);
#endif

 starry_uart.c

#include "starry_uart.h"
void delay_us(void)
{char k=63;while(k--);
}
void Init32M(void)
{SLEEPCMD &= ~(0x01<<1); //1111 1110 寮€鍚袱涓珮棰戞椂閽熸簮while(SLEEPSTA & 0x40==0);//0100 0000 绛夊緟32M绋冲畾delay_us();CLKCONCMD &= 0xF8;//浣?浣嶆竻闆?涓嶅垎棰戣緭鍑?  CLKCONCMD &= 0xBF; //1011 1111 璁剧疆32M涓虹郴缁熶富鏃堕挓while(CLKCONSTA & 0x40); //0100 0000 绛夊緟32M鎴愬姛閰嶇疆涓哄綋鍓嶇郴缁熶富鏃堕挓
}void delay_ms(int ms)
{int i,j;for(i=ms;i>0;i--)for(j=587;j>0;j--);
}
void Uart_Config()
{//Baud :9600PERCFG &= 0xFE;//1111 1110 P0SEL |= 0x0C; //0000 1100  U0CSR |= 0xC0;U0GCR = 8;U0BAUD = 59; //9600EA=1;URX0IE=1;
}
void String_Print(unsigned char *str)
{for(;*str!='\0';str++){U0DBUF=*str;while(UTX0IF==0);UTX0IF=0;}
}#pragma vector=URX0_VECTOR
__interrupt void UART0_IRQ(void)
{char ch;URX0IF = 0;ch = U0DBUF;U0DBUF = ch;while(UTX0IF == 0);UTX0IF = 0;
}

将串口初始化在main函数末尾调用,并调用我们自己扳机支持包里的串口字符串发送函数

进入main函数中的HalDriverInit驱动初始化函数中

找到TI串口配置的宏定义

将宏定义改为FALSE,从而取消TI默认对串口的配置

最后下载程序即可

实验效果


http://www.ppmy.cn/news/699028.html

相关文章

商用密码产品认证-智能IC卡

商用密码产品认证-智能IC卡 产品概述相关标准规范应用要点 产品概述 智能IC卡是将一个或多个集成电路芯片嵌装于塑料基片上制成的卡片&#xff0c;卡内的集成电路具有数据存储、运算和判断功能&#xff0c;并能与外部进行数据交换。智能IC卡可以封装成卡式&#xff0c;或者是标…

Python深度学习-张量运算

神经网络中的大部分操作都涉及到张量运算&#xff08;tensor operations&#xff09;。张量是多维数组&#xff0c;可以看作是向量或矩阵的扩展&#xff0c;因此可以描述和处理更加复杂的数据结构&#xff0c;如图像、音频等。 在神经网络中&#xff0c;张量运算通常涉及以下几…

如何读取社保卡基本信息?即无需验证密码的信息!

社会保障&#xff08;个人&#xff09;卡规范 //更多请阅读 《社会保障&#xff08;个人&#xff09;卡规范》 //cls in const unsigned char Coco_MF[2] { 0x3f,0x00 };//MF 主文件const unsigned char Coco_Response[2] { 0x00,0xC0 };//取得响应数据 ISO const unsigned …

用户卡的发展变革

摘要&#xff1a;全球手机用户总数接近30亿&#xff0c;用户卡在其中扮演着举足轻重的角色。作为一类特殊的智能卡&#xff0c;用户卡现已集中了智能卡领域的多项先进技术&#xff0c;推动着技术和标准化的发展&#xff0c;丰富着移动用户的生活。随着多应用、非接触智能卡技术…

IBC密码技术分析研究

一、传统的PKI系统 PKI(公开密钥基础设施&#xff0c;Public Key Infrastructure)是以不对称密匙加密技术为基础&#xff0c;以数据机密性、完整性、身份认证和行为不可抵赖性为安全目的&#xff0c;来实施和提供安全服务的具有普适性的安全基础设施。其内容包括数字证书、…

CPU卡片结构

CPU卡卡片结构 非接触CPU卡芯片&#xff0c;产品支持ISO14443-A协议&#xff0c;CPU指令兼容通用8051指令&#xff0c;内置硬件DES协处理器&#xff0c; 数据存储器为8Kbyte的EEPROM。该芯片符合中国人民银行PBOC2.0电子存折/电子钱包规范&#xff0c;建设事业CPU卡芯片规范。 …

IC卡

本词条由 “科普中国”百科科学词条编写与应用工作项目 审核 。 IC卡 (Integrated Circuit Card&#xff0c;集成电路卡)&#xff0c;也称智能卡(Smart card)、智慧卡(Intelligent card)、微电路卡(Microcircuit card)或微芯片卡等。它是将一个 微电子 芯片嵌入符合ISO 7816标准…

社保系列6《账户划入交易》

通过账户划入交易&#xff0c;持卡人可将其在基本医疗保险个人账户上的资金划入卡内基本医疗保险个人账户中。 特点&#xff1a; 1) 终端上联网进行 2) 提交个人密码&#xff08;PIN&#xff09;&#xff08;如持卡人设置&#xff09; 步骤&#xff1a; 1) …