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

关于TI的CC2541的程序解读(5)

来源:网络收集 时间:2019-03-16 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

我们发现这个打印老是出错,怎样让这个打印在消息中处理?即我们需要打印时,就发送一个消息给任务,在任务中在有空时才去打印这个消息中的内容,等打完后才去重新打印,即打印完了后,(这个可能要用一个函数来决定,再去打印下一个)这样就能把所有的消息都打印好了。打印队列中还有东西未打完,我们就不会去处理这个打印消息。只有打完了才去处理。这个要用消息队列去处理吧。消息本来就是一个队列的。 好象有点麻烦。

先看一下,我们打印时如何知道缓冲区的内容已经打印完了呢? HalUARTBusyDMA()这个函数也不知是不是?

还有一个办法是每次打印后都加一个延时才去处理下一个。但怎样加延时呢?OSAL中没有这个。只有延时发事件。

我们产生一个周期性的事件,在这个周期性的事件中,去处理打印消息,因为一个周期设为10ms,则10ms我们肯定打印完了。

这样,我们先设计一个周期性的事件,在这个事件中,我们去处理

原来的定时闪灯的方法是这样的,在我们自已定义的任务中,每隔一段时间,就去给

Hal_TaskID这个任务,发送一个事件,这个任务发现这个事件后,就调用一个Test_Send() 在这个Test_Send中,我们给消息分配了一个内存,然后,将这个系统消息发给我们的定义的任务,在我们的任务中,在系统消息处理中,将处理这个消息(闪灯)然后,将这段消息内存删除。

现在,我们要打印时,就生成一个消息,且发送给我们自已定义的任务,在这个任务中,我们处理系统消息,但这个系统消息每次只处理一条

注意到键改变这个事件它是 typedef struct {

osal_event_hdr_t hdr; //事件头,这个很重要,它包含有下列第6行部分 uint8 state; // shift 状态 uint8 keys; // keys 键值 } keyChange_t;

typedef struct {

uint8 event; ///事件,这个与上面的相呼应。 uint8 status; } osal_event_hdr_t;

在系统信息处理中,本来这个我们发过来的是一个指针keyChange_t。这个指针有比较多的成员变量。但是后来在任务中进行处理时,即变更为osal_event_hdr_t类型的指针 simpleBLECentral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );这就说明,系统信息处理中,只处理我们这个指针的前面几个字节,后面的直接忽略了,但是在调用这个处理函数时,可不能忽略,因为按键值是在后面的。

21

这个有点奇怪的是:

从队列中收消息时,它是返回的是 osal_msg_hdr_t 这是一个消息队列。 收到消息后,要读取其中的事件时,这个指针却变成 osal_event_hdr_t 在具体处理函数中,即要将同一个指针变成 keyChange_t 去处理。

以上的原因是keyChange_t的第一个指针,指向的就是osal_event_hdr_t,而消息得到的第一个数处,它是keyChange_t,这个在osal_msg_push()函数中可以看得出来。

了解了以上现象后,我们先仿这个 typedef struct {

osal_event_hdr_t hdr;

uint8 state; // shift uint8 keys; // keys } keyChange_t;

定义一个新的结构 typedef struct {

osal_event_hdr_t hdr; ///不想含这个事件 可以吗? uint8 printf_num; //我们要打印的字节的长度 uint8 printf_data[32]; ///我们最多打印32个字节 }printf_t;

我们发一个消息给它,每次我们只处理一个消息,处理完这个消息后,就将这个消息清除掉。消息中并不含事件可以吗?看来是不行的,因为发送消息时,必须是系统事件才可以。

我们这样做,串口打印发的是系统消息,这个系统消息队列中,如果时间未到,我们并不处理它,只有当时间到了,我们才将这个消息删除掉,这样,这些打印消息都会留在这个系统队列中。等待下一次又会去处理。处理一个消息串口消息就将这个计数器保留下来,看是否相同,如果不同才去处理串口消息。程序不做大的修改。还是每隔一段时间会有时间到的系统消息到来。不过这样做显然不行,因为每次运行到此时,系统消息可能都是哪个串口消息,而这个时间消息却永运等不来了。

只有这样,将这个系统消息给串口独占了。该任务的系统消息只有一个。我们先改一下,将原来的部分删除掉看一下。先让这个任务自已产生一个周期性的调用。然后加一个静态的全局变量作为计数值。

接下来,修改关键的部分,想打印时,我们就生成一个系统消息给我们自已的任务。

显然,我们在打印文档中修改它,先在npi.h中定义这个新结构。 typedef struct {

22

osal_event_hdr_t hdr; ///不想含这个事件 可以吗? uint8 printf_num; //我们要打印的字节的长度 uint8 printf_data[32]; ///我们最多打印32个字节 }printf_t;

然后生成一个新的虚拟打印语句,我们先打的是ASCII部分。如果外部要打印必须先将要打印的东西换成它才可以。而且每次打印不能超过32个字符。 Virtual_printf(char*,uint8 len)

另外写三个函数

Virtual_printf_srting(char*p) Virtual_printf_data(int data)

先简单一点的吧。Virtual_printf(char*,uint8 len)

将结构定义到npi.c中。加上这个函数。构想如下: 处理这个消息,在自已定义的任务中。

每条打印语句,转化为系统事件+消息给我们的任务。这个消息由系统事件引起。我们的任务在得到系统事件后,去找到这个消息去处理,当这个消息存在时,就看是否是打印消息,如果是,则看时间更新到否,如果到就打印,且将此消息清除,如果不到,则该消息还存在消息队列中。只要还有消息,这个系统事件就存在,没有清除掉,如果消息队列为空,则将这个系统事件清除掉。结果发现只打印了第一句就死机了。而且也不再运行到我们的事件处理程序中去了。此时就有可能是消息队列溢出了?

我们只发一条消息试一下。可以打印,但是发2条就不能打印了。

原因是第1条执行后,再执行第2条的消息处理时,开始3次还能进到处理程序中(由于时间没到不处理),但是后面就直接读消息队列时却为空了。没找到原因。暂时放一下。 发现这个从机的广播信息不符合规定的,所以一直找不到下位机,现在可以发现一个下位机了。

现在发现一个设备,可以开始下一步了。现在下位机我们用它的一个特征值

建立连接后,有一个事件会发生,就是建立连接事件会发生,于它在这个回调函数中,会直接会发送一个START_DISCOVERY_EVT给本任务,于是本任务会调用: simpleBLECentralStartDiscovery( );函数,看下位机有什么样的服务。 注意到在建立连接完成后,这个值被得到了:simpleBLEConnHandle 然后,调用发现服务后就去发现服务回调函数中处理一些事宜。

我们打算用CHAR6来做一些事情,上位机会发一个helloworld下去,下位机通过此口回一个0x01 0x02 0x03 0x04回来

怎样得以char6的句柄呢?

在发现服务中的回调函数中,我们发现了simpleBLECharHdl。这个就是通讯特征的句柄。如果要发现多个特征的句柄,估计是在这个子程序中多循环几次。一直得到最后一个。

23

得么这个句柄后,看在UP键中是如何写的?

status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId ); 但是怎么没发现simpleBLECharHdl呢?发现了,就在。。。

发现发送后,主机返回一个ERROR 再看从机,它没有设下面这个:

SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR6, SIMPLEPROFILE_CHAR6_LEN, charValue6 );

我们在初始化时将这个设一下看。

设完后,可以打印helloworld了。接下来,我们反向打印一下HELLOWORLD.即上位机发一个读命令,下位机就返回这个HELLOWORLD这10个字符。

先看一下,上位机如何读,我们想通过同一个特征值char6来读一下看。

原来的怎么读的。原来上位机按一个键(手机上按一个键)可以读温度和湿度。现在我们首先在从机中先改动一下。我们知道,原来我们是将传感器的温湿度是每隔一段时间,进行一个周期性的数据采集,放到SensorValue[i]中。 在读配置这个函数中,它将会调用:

uint8 simpleProfileReadConfig(uint16 uuid, uint8 *newValue)特别注意到这个函数返回值为len.如果我们要读10个字符串,则返回的值就是10。于是我们要将这个newValue的定义改为较长才行。还有读配置其实可能并不是一个妥当的办法,因为读配置只能读一次。每次可能只能读23个字符,这样字符多的话就要读好几次。先这样读10个看一下。最好是主动发100来个字符过去。

这里4个字节还没有改,接下来要改的。先没改,先看如何调用这个函数的。看到了,是在 static uint8 simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,

uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen ) 中调用这个函数的。

但又是谁在什么时候调这个回调的呢?特别是这个maxLen这个参数好象没有用到。

这样下位机差不多改好了,下面看一下主机该如何改呢?主机要读char6和东西。读过来有多长,再打印出来。 以下是主机部分。

先看读成功后的回调函数,它将读来的东西打印了一下,原来只打印一个字节的。现在要打印多少字节。中间有一个长度,也有一个值,其最长的长度定义为23,我们不要超过它就是了。 接下来,我们怎么知道这个char6 的特征值要读呢?我们按了一个键就是去读下位机的配置的。

在按下键中,我们没有找到有关的部分。因为它是一个外部函数,我们只执行了下列: attReadReq_t req;

req.handle = simpleBLECharHdl; ///这个就是指定的要读的特征值

status = GATT_ReadCharValue( simpleBLEConnHandle, &req, simpleBLETaskId ); 大功初成!双向都可以通过char6来进行了。主机按UP键,发送一个helloworld到下位机,再按一次UP键,则主机发一个读下位机的char6信息,下位机的char6信息它就是大写的HELLOWORLD.来回都正确了。

时间已经指向用了一个多月,从11月25日到12月29日,太长了,也许自已太笨。

24

25

26

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库关于TI的CC2541的程序解读(5)在线全文阅读。

关于TI的CC2541的程序解读(5).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/528230.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: