PS:这篇文章记录笔者TI ble协议栈的学习串口的笔记。欢迎各位评论讨论,也希望有大牛解答文末的问题。

  前些日子CC2540模块没到,就捣鼓CC2530。深深的感受到,ZigBee就是个坑啊。然后果断玩BLE了。BLE,TI的栈给的文档,project这回看起来好点,然后找了其他一些资料。这里介绍《蓝牙4.0BLE开发完全手册-物联网开发技术实战》。看起来还行吧。不过我照着他的串口例子做,没看到效果(可能是协议栈版本问题)。于是,一怒之下,自己啃。

  最后再说一下,CC2530和CC2540除了RF不同外,51内核是一样的。因为栈中使用的HAL是一样的。

  说下自己的装备。如下图。手焊跳线o(∩_∩)o。主要可以用的IO有串口0,定时器1的通道0~3,定时器的IO映射到了位置2。和两个按键。

  先来看看HAL都给了啥。我个人认为key、led、lcd就是多余的。这个硬件相关性实在是太强了。所以先从串口开始看起,我想各位看官的串口也都在位置1吧。

HAL里面默认串口使用的DMA。这个就不管它了。我建议先简单的看下APP Group下面的几个c文件。和OSAL.C中的osal_init_system和osal_run_system两个函数,其它最好也浏览一下。在开始写我们自己的串口函数前先看看项目的配置情况。请注意下,函数中用很多预编译,看的时候仔细点。

左上角,选择CC2540,关掉POWER_SAVING,在defined symbols中的POWER_SAVING前面加个x就可以了。关于POWER_SAVING,在函数osal_run_system中可以看到,这里我们x掉,不然编译会出现一个警告,说什么串口和key的中断被重复的啥啥啥的。至于LCD,因为我的板是没用LCD的干脆也x了。

  现在开始来看看怎么来串口打印出信息来。找到SimpleBLEPeripheral.c中的SimpleBLEPeripheral_Init函数,添加如下代码,注意{}中才是我添加的。另外要添加hal_uart.h这个头文件。

 1 void SimpleBLEPeripheral_Init( uint8 task_id )
 2 {
 3   simpleBLEPeripheral_TaskID = task_id;
 4
 5     {    //add
 6         halUARTCfg_t halUARTCfg;
 7         halUARTCfg.configured            =    TRUE;
 8         halUARTCfg.baudRate                = HAL_UART_BR_115200;
 9         halUARTCfg.flowControl        =    HAL_UART_FLOW_OFF;
10
11         HalUARTOpen(HAL_UART_PORT_0, &halUARTCfg);
12         HalUARTWrite(HAL_UART_PORT_0, "Hello CC2540!\n", 14);
13     }

添加串口

来看看串口配置这个结构体。注意到,这个结构体是没有关于配置停止位,校验位的。也就是全是默认。其他没用到的先不理会是用来干嘛的。

 1 typedef struct
 2 {
 3   bool                configured;
 4   uint8               baudRate;
 5   bool                flowControl;
 6   uint16              flowControlThreshold;
 7   uint8               idleTimeout;
 8   halUARTBufControl_t rx;
 9   halUARTBufControl_t tx;
10   bool                intEnable;
11   uint32              rxChRvdTime;
12   halUARTCBack_t      callBackFunc;    //回调函数
13 }halUARTCfg_t;

halUARTCfg_t

顺便吐槽一下,TI给的HAL api文档里面关于串口的宏定义有错,所以还是看源码靠谱点。

到这里,编译烧录,应该就可以看到串口出来的信息了。附图,注意一下右边的配置情况。


华丽的分割线


  上面讲了一下,如何使用Hal给的API来调用串口。也实现了串口信息打印功能。但这并不具有实际意义。在OSAL中,会对系统中的各种事件进行扫描,若事件发生,则会回调相应的函数去执行对应的功能。比如串口接收到信息。笔者尝试着halUARTCfg_t结构体中的callBackFunc成员赋予回调函数。并使用HAL的串口API来实现这个函数——发送串口接收到的内容。

 1 //类似于这样子
 2
 3 halUARTCfg_t a
 4
 5 a.callBackFunc = funcA
 6
 7
 8 static void funcA (uint8 port, uint8 event)
 9 {
10     HalUARTRead(, , );
11     HalUARTWrite(, ,);
12 }

上面是省略了的形式,但有个很怪的问题。就是串口接收一次数据后,这个回调函数就一直被调用,一直打印数据出来。经过各种尝试之后也没找出个所以然。可能是对整个协议栈的了解太少了。折腾了一个下午后,使用了npi.c提供的API函数。npi是Network Processor Interface的简称。

  来看看npi里面到底都是些什么

 1 //初始化串口配置
 2 void NPI_InitTransport( npiCBack_t npiCBack )
 3 {
 4   halUARTCfg_t uartConfig;
 5
 6   // configure UART
 7   uartConfig.configured           = TRUE;
 8   uartConfig.baudRate             = NPI_UART_BR;
 9   uartConfig.flowControl          = NPI_UART_FC;
10   uartConfig.flowControlThreshold = NPI_UART_FC_THRESHOLD;
11   uartConfig.rx.maxBufSize        = NPI_UART_RX_BUF_SIZE;
12   uartConfig.tx.maxBufSize        = NPI_UART_TX_BUF_SIZE;
13   uartConfig.idleTimeout          = NPI_UART_IDLE_TIMEOUT;
14   uartConfig.intEnable            = NPI_UART_INT_ENABLE;
15   uartConfig.callBackFunc         = (halUARTCBack_t)npiCBack;
16
17   // start UART
18   // Note: Assumes no issue opening UART port.
19   (void)HalUARTOpen( NPI_UART_PORT, &uartConfig );
20
21   return;
22 }
23
24 //读数据
25 uint16 NPI_ReadTransport( uint8 *buf, uint16 len )
26 {
27   return( HalUARTRead( NPI_UART_PORT, buf, len ) );
28 }
29
30 //写数据
31 uint16 NPI_WriteTransport( uint8 *buf, uint16 len )
32 {
33   return( HalUARTWrite( NPI_UART_PORT, buf, len ) );
34 }
35
36 //长度R
37 uint16 NPI_RxBufLen( void )
38 {
39   return( Hal_UART_RxBufLen( NPI_UART_PORT ) );
40 }
41
42 //R缓冲区大小
43 uint16 NPI_GetMaxRxBufSize( void )
44 {
45   return( NPI_UART_RX_BUF_SIZE );
46 }
47
48 //T缓冲区大小
49 uint16 NPI_GetMaxTxBufSize( void )
50 {
51   return( NPI_UART_TX_BUF_SIZE );
52 }

 1 #ifndef NPI_H
 2 #define NPI_H
 3
 4 #ifdef __cplusplus
 5 extern "C"
 6 {
 7 #endif
 8
 9 /*******************************************************************************
10  * INCLUDES
11  */
12
13 #include "hal_types.h"
14 #include "hal_board.h"
15 #include "hal_uart.h"
16
17 /*******************************************************************************
18  * MACROS
19  */
20
21 /*******************************************************************************
22  * CONSTANTS
23  */
24
25 /* UART port */
26 #if !defined NPI_UART_PORT
27 #if ((defined HAL_UART_SPI) && (HAL_UART_SPI != 0))
28 #define NPI_UART_PORT                  HAL_UART_PORT_1
29 #else
30 #define NPI_UART_PORT                  HAL_UART_PORT_0
31 #endif
32 #endif
33
34 #if !defined( NPI_UART_FC )
35 #define NPI_UART_FC                    FALSE    //add ->true
36 #endif // !NPI_UART_FC
37
38 #define NPI_UART_FC_THRESHOLD          48
39 #define NPI_UART_RX_BUF_SIZE           128
40 #define NPI_UART_TX_BUF_SIZE           128
41 #define NPI_UART_IDLE_TIMEOUT          6
42 #define NPI_UART_INT_ENABLE            TRUE
43
44 #if !defined( NPI_UART_BR )
45 #define NPI_UART_BR                    HAL_UART_BR_115200
46 #endif // !NPI_UART_BR
47
48 /*******************************************************************************
49  * TYPEDEFS
50  */
51
52 typedef void (*npiCBack_t) ( uint8 port, uint8 event );
53
54 //
55 // Network Processor Interface APIs
56 //
57
58 extern void   NPI_InitTransport( npiCBack_t npiCBack );
59 extern uint16 NPI_ReadTransport( uint8 *buf, uint16 len );
60 extern uint16 NPI_WriteTransport( uint8 *, uint16 );
61 extern uint16 NPI_RxBufLen( void );
62 extern uint16 NPI_GetMaxRxBufSize( void );
63 extern uint16 NPI_GetMaxTxBufSize( void );
64
65 /*******************************************************************************
66 */
67
68 #ifdef __cplusplus
69 }
70 #endif
71
72 #endif /* NPI_H */

可以看出来,npi就是对Hal中的串口API做了一层封装。

之后SimpleBLEPeripheral_Init函数

1 void SimpleBLEPeripheral_Init( uint8 task_id )
2 {
3   simpleBLEPeripheral_TaskID = task_id;
4
5     {    //add
6         NPI_InitTransport(UartEventChange);    //Network Processor Interface 初始化
7     }
8 ………… //省略
9 }

添加UartEventChange回调函数

 1 static void UartEventChange(uint8 port, uint8 event)    //add
 2 {
 3     VOID    port;
 4     uint8 temp;
 5
 6     if(event & HAL_UART_RX_TIMEOUT)    //接收完成事件
 7     {
 8         temp = NPI_RxBufLen();
 9         if(temp)
10         {
11             NPI_ReadTransport(uartbuf, temp);
12             NPI_WriteTransport(uartbuf, temp);
13             osal_memset(uartbuf, 0, sizeof(uartbuf));
14         }
15     }
16 }

对SimpleBLEPeripheral.c文件做上面的修改,然后编译、烧录,就可以看到想要的现象了。CC2540在接收完串口信息后,返回接收到的内容。仅返回一次。而不像使用Hal的串口API那样,接收到之后就一直发送不停。

  注意要关闭串口的流控制和power saving

  尽管通过npi实现了串口的收发。但还是有些问题没搞懂。

 1 /*
 2  *
 3  *1、为何使用Hal中的串口api就无法产生上述效果。是我那些地方没有注意
 4  *到了吗??
 5  *
 6  *2、系统是如何知道串口接收完毕的。在调试过程中发现,串口事件有是有
 7  *定时器的。真的吗?
 8  *
 9  *3、默认使用了DMA,那这个缓冲区在那里,文件中并没有声明出来这个数
10  *组,只声明了DMA的大小。东西到底存哪里去了。
11  *
12  *4、系统的事件到底是怎么运作的?
13  *
14  *……
15  *
16  */

先记录下这些问题。等熟悉了BLE栈之后在慢慢找答案。一开始就纠结这些问题的话,可能到头来就啥都没搞懂了。

转载于:https://www.cnblogs.com/xiemm/p/3902942.html

CC2540-BLE4.0 学历笔记1之串口体验相关推荐

  1. zigbee3.0@学习笔记@TI STACK@串口接收

    1.串口初始化 MT_UartInit()位于MT_UART.c /****************************************************************** ...

  2. zigbee3.0@学习笔记@TI STACK@串口发送

    1.串口初始化 MT_UartInit()位于MT_UART.c /****************************************************************** ...

  3. IoT:BLE4.0教程一 蓝牙协议连接过程与广播分析

    IoT:BLE4.0教程一 蓝牙协议连接过程与广播分析 1.蓝牙简介 什么是蓝牙4.0 蓝牙无线技术是使用范围最广泛的全球短距离无线标准之一,蓝牙4.0版本涵盖了三种蓝牙技术,即传统蓝牙.高速蓝牙和低 ...

  4. iOS蓝牙BLE4.0通信功能

    概述 iOS蓝牙BLE4.0通信功能,最近刚学的苹果,为了实现蓝牙门锁的项目,找了一天学习了下蓝牙的原理,亲手测试了一次蓝牙的通信功能,结果成功了,那么就把我学习的东西分享一下. 详细 代码下载:ht ...

  5. E104-BT01超低功耗蓝牙模块BLE4.0协议的片载系统解决方案

    1.E104-BT01简介 E104-BT01 是亿佰特设计生产的一款小体积的蓝牙模块,贴片型(引脚间距 1.27mm),自带高性能 PCB 板载天线.支持 BluetoothV4.0 标准,简单配置 ...

  6. CC2541蓝牙BLE4.0主从透传工程

    .前言 小弟初来乍到,这是小弟的第一篇博客,暂时还在上学,没有什么工作经验,本篇博客主要记录我在这几天学习BLE协议协议栈的一点心得体会,并用一个主从透传的实验来记录过程,如有错误之处,还望各位大佬多 ...

  7. mysql5.0镜像_Mysql5.0学习笔记(一)

    Mysql5.0学习笔记(一) -基本sql语句与支持字符集 1.登录 mysql -h localhost -u root 2.创建用户firstdb(密码firstdb)和数据库,并赋予权限于fi ...

  8. html5.0笔记,动易sf5.0标签笔记.doc

    动易sf5.0标签笔记 网站首页标签调用 动易SiteFactory 文章模型标签作者:动易网络 文章来源:灯火 点击数:1617 更新时间:2011-4-16 20:20:52标签名: {PE.La ...

  9. 第64节:Java中的Spring Boot 2.0简介笔记

    Java中的Spring Boot 2.0简介笔记 spring boot简介 依赖java8的运行环境 多模块项目 打包和运行 spring boot是由spring framework构建的,sp ...

最新文章

  1. Enhanced-RCNN: 一种高效的比较句子相似性的方法 |​WWW 2020
  2. Opengl-基本概念-着色器(都是固定的)
  3. questasim linux安装包,Ubuntu16.04下Questasim10.7安装(64bit)全攻略
  4. php xingnengfenxi_PHP 性能分析与实验:性能的微观分析
  5. 消息中间件系列(六):什么是流量削峰?如何解决秒杀业务的削峰场景
  6. python实现点击按钮_python实现点击按钮修改数据的方法
  7. Chome 浏览器,您的连接不是私密连接
  8. Spring JDBC 【继承JdbcDaoSupport】
  9. 如何 运行WRF模型 天气预报 数据后处理
  10. esxcli software vib 命令为 ESXi 5.x/6.x 主机安装补丁程序 (2008939)
  11. IT行业十大热门职位
  12. Swift vs. Kotlin 漫谈之扩展篇
  13. html5如何快速选择工具,Photoshop教程:在PS中如何使用快速选择工具建立有效选区...
  14. python cgi
  15. 红蓝对抗-红队打点的那些事
  16. 云更新怎么远程连接服务器,云更新YGX主副服务器互相切换方法
  17. 分享tiny4412,emmc烧录u-boot, 支持fastboot模式烧写emmc
  18. 卸载WPS后,安装OFFICE2013问题
  19. android 百度地址转经纬度,百度地图经纬度和地址的相互转换
  20. 2-1.2.2 Simulink数据类型

热门文章

  1. iphone 使用自定义字体
  2. ISD1820语音模组的使用
  3. 客户关系管理咨询 - 获取最佳CRM解决方案
  4. Python实现抖音表白软件
  5. 个人收集的java精品网站
  6. 鲁大师性能测试要装什么软件吗,比鲁大师还好用的硬件检测软件,鲁大师再见!...
  7. 软考 信息系统项目管理师备考指南
  8. Vue - 渲染函数render
  9. S3C6410移植linux4.17内核(一)
  10. matlab励磁电路图,发电机的励磁方法及工作原理