【BLE

【BLE

本篇博文最后修改时间:2017年06月02日,21:49。


一、简介

本文以SimpleBLEPeripheral工程为例,介绍如何通过app的指令对设备进行设置时间、读取时间。


二、实验平台

协议栈版本:ble_cc26xx_2_01_00_44423

编译软件:IAR Embedded Workbench for ARM Version 7.40

硬件平台:CC26xxDK开发板

仿真器:XDS100V3(香瓜)

手机平台:小米4S

APP:BLE读写器


、版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:.NET/feilusia

联系方式:897503845@qq

香瓜BLE之CC2541群:127442605

香瓜BLE之CC2640群:557278427

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667
香瓜单片机之Linux群:512598061
香瓜单片机之职场交流群:450154342
甜甜的大香瓜的小店(淘宝店):/?spm=2013.1.1000126.d21.hd2o8i
四、 实验前提 1、在进行本文步骤前,请先 阅读 以下博文: 暂无


2、在进行本文步骤前,请先 实现以下博文:
1)《CC2640之添加自定义服务》:

五、基础知识

1、什么是RTC? 答:RTC(Real-time clock),也就是实时时钟。它常被用于设备端的时钟计时。
2、手机端已经有时间了,为何还要能通过app设置设备端时间、读取设备端时间? 答:例如智能保温杯项目,商家想根据用户的喝水习惯,在app端给用户合适的健康建议。 这时在智能保温杯中增加RTC时间功能,即可记录下用户一天内喝水的时间,当app连接时将喝水时间上报给app,app即可给出建议“喝水较少,建议多喝水”。
3、CC2640中如何使用RTC? 答:协议栈中已有RTC驱动,使用流程如下: 1)设置RTC时间 ①启动RTC计数:调用UTC_init函数。 ②填写时间 ( 年、月、日、时、分、秒 ):填写UTCTimeStruct结构体的数据。 ③ 转换时间 ( 秒 ):通过UTC_convertUTCSecs函数,将UTCTimeStruct时间(年、月、日、时、分、秒)转换为UTCTime时间(秒)。 ④更新时间:调用UTC_setClock函数,参数是③中转换所得的UTCTime时间。
2)读取RTC时间 ①获取RTC时间:调用UTC_convertUTCTime函数。 ②转换时间( 年、月、日、时、分、秒):将上面获得的 UTCTime时间(秒),转换为UTCTimeStruct时间(年、月、日、时、分、秒)。
4、CC2640中使用RTC时需要注意什么? 答: 1)一天下来,RTC的时钟计数有个几秒误差是正常的,因此尽量每次app连接时能更新一下最新的时间。 2)特别注意协议栈中的月、日、时三个数据,是从0开始,而不是我们通常习惯的1开始。
typedef struct
{uint8_t seconds;  // 0-59uint8_t minutes;  // 0-59uint8_t hour;     // 0-23uint8_t day;      // 0-30uint8_t month;    // 0-11uint16_t year;    // 2000+ 
} UTCTimeStruct;

5、既然协议栈中已有RTC的驱动,为何香瓜要再封装一个驱动文件? 答:为了简化使用、并且解决上述第3点的第2)小点注意事项的问题,香瓜自己封装了一个RTC驱动文件。 该文件中一共3个函数,初始化、读、写,读出来的便是最终可直接拿来使用的转换好的时间数据,非常方便使用。 PS:相信你用过之后会觉得协议栈的原始RTC驱动真TMD的难用。
六、实验步骤 1、添加协议栈的RTC驱动 1)添加UTC_clock.c和UTC_clock.h(文件路径在“……\ble_cc26xx_2_01_00_44423\Projects\ble\common\cc26xx\Time”)

2)IAR设置中增加协议栈RTC文件的路径
$PROJ_DIR$/../../../../../../../Projects/ble/common/cc26xx/Time

3)修改UTC_Clock.h

#include <stdint.h>
不增加这个头文件的话,会报错,缺少uint8等数据类型的定义。

2、编写并添加香瓜RTC驱动 1)写一个香瓜RTC驱动源文件GUA_RTC.c(存放在“……\ble_cc26xx_2_01_00_44423\Projects\ble\SimpleBLEPeripheral\CC26xx\Source\Application\GUA”路径下)
//******************************************************************************        
//name:         GUA_RTC.c        
//introduce:    香瓜自定义的RTC驱动   
//author:       甜甜的大香瓜      
//email:        897503845@qq   
//QQ group      香瓜BLE之CC2640(557278427) 
//changetime:   2016.09.04
//******************************************************************************
#include "GUA_RTC.h"//******************************************************************************        
//name:             GUA_RTC_Init       
//introduce:        香瓜的RTC初始化      
//parameter:        none      
//return:           none     
//author:           甜甜的大香瓜             
//email:            897503845@qq 
//QQ group          香瓜BLE之CC2640(557278427)              
//changetime:       2016.09.04                 
//******************************************************************************
void GUA_RTC_Init(void)
{//初始化UTC.UTC_init(); 
}
//******************************************************************************        
//name:             GUA_RTC_Set       
//introduce:        香瓜的RTC设置时间函数      
//parameter:        pGUA_Timer:传入的时间      
//return:           none     
//author:           甜甜的大香瓜             
//email:            897503845@qq 
//QQ group          香瓜BLE之CC2640(557278427)              
//changetime:       2016.09.04                 
//******************************************************************************
void GUA_RTC_Set(UTCTimeStruct *pGUA_Timer)
{UTCTimeStruct SetTime; UTCTime SetTime_seconds;  //转换数据SetTime.year = pGUA_Timer->year;              SetTime.month = pGUA_Timer->month - 1;        SetTime.day = pGUA_Timer->day - 1;           SetTime.hour = pGUA_Timer->hour - 1;          SetTime.minutes = pGUA_Timer->minutes;       SetTime.seconds = pGUA_Timer->seconds; //将时间转换为秒SetTime_seconds = UTC_convertUTCSecs(&SetTime);//设置时间UTC_setClock(SetTime_seconds);  
}//******************************************************************************        
//name:             GUA_RTC_Get       
//introduce:        香瓜的RTC获取时间函数      
//parameter:        pGUA_Timer:传入的时间      
//return:           none     
//author:           甜甜的大香瓜             
//email:            897503845@qq 
//QQ group          香瓜BLE之CC2640(557278427)              
//changetime:       2016.09.04                 
//******************************************************************************
void GUA_RTC_Get(UTCTimeStruct *pGUA_Timer)
{UTCTimeStruct GetTime;//获取当前数据UTC_convertUTCTime(&GetTime, UTC_getClock());//抓换数据pGUA_Timer->year = GetTime.year;                      pGUA_Timer->month = GetTime.month + 1;                pGUA_Timer->day = GetTime.day + 1;                    pGUA_Timer->hour = GetTime.hour + 1;                  pGUA_Timer->minutes = GetTime.minutes;                pGUA_Timer->seconds = GetTime.seconds;                
}

2)写一个香瓜RTC驱动头文件GUA_RTC.h(存放在“……\ble_cc26xx_2_01_00_44423\Projects\ble\SimpleBLEPeripheral\CC26xx\Source\Application\GUA”路径下)
//******************************************************************************        
//name:         GUA_RTC.h        
//introduce:    香瓜自定义的RTC驱动头文件    
//author:       甜甜的大香瓜      
//email:        897503845@qq   
//QQ group      香瓜BLE之CC2640(557278427) 
//changetime:   2016.09.04 
//******************************************************************************
#ifndef _GUA_RTC_H_
#define _GUA_RTC_H_/*********************头文件************************/ 
#include "UTC_Clock.h"/*********************函数声明************************/ 
extern void GUA_RTC_Init(void);
extern void GUA_RTC_Set(UTCTimeStruct *pGUA_Timer);
extern void GUA_RTC_Get(UTCTimeStruct *pGUA_Timer);#endif

3)工程中添加GUA_RTC.c和GUA_RTC.h

4)在IAR设置中添加服务的文件路径
$PROJ_DIR$/../../../Source/Application/GUA     
如果已添加过,就不用添加了。

3、在应用层中添加RTC相关的代码 1)添加GUA_RTC头文件(SimpleBLEPeripheral.c中)
#include "GUA_RTC.h"

2)香瓜RTC初始化(SimpleBLEPeripheral.c的SimpleBLEPeripheral_Init中)
  //香瓜RTC初始化GUA_RTC_Init();  
初始化RTC,否则时钟不会计数。
3)添加app的处理指令(替换SimpleBLEPeripheral.c的GUA_CharValueChangeEvt函数)
//******************************************************************************            
//name:             GUA_CharValueChangeEvt           
//introduce:        应用层香瓜服务的处理函数         
//parameter:        paramID:特征值ID                  
//return:           none         
//author:           甜甜的大香瓜                 
//email:            897503845@qq     
//QQ group          香瓜BLE之CC2640(557278427)                  
//changetime:       2016.09.04                   
//****************************************************************************** 
#define GUA_COMMAND_GET_TIME    0x01
#define GUA_COMMAND_SET_TIME    0x02
static void GUA_CharValueChangeEvt(uint8_t paramID)
{  uint16 notify_Handle;     uint8 bBuf[20] = {0};   uint8 *p = bBuf;  UTCTimeStruct GUA_Timer;switch(paramID)  {  //char1case GUAPROFILE_CHAR1:   {                  //读出特征值数据GUAProfile_GetParameter(GUAPROFILE_CHAR1, p);//根据通信协议进行事件分发,功能码+年(2字节)+月+日+时+分+秒switch(p[0]){//读当前时间case GUA_COMMAND_GET_TIME:{//获取当前时间GUA_RTC_Get(&GUA_Timer);//整理发送缓冲区memset(p, 0xff, GUAPROFILE_CHAR1_LEN); p[0] = GUA_COMMAND_GET_TIME;p[1] = GUA_Timer.year >> 8;p[2] = GUA_Timer.year & 0xff;          p[3] = GUA_Timer.month;          p[4] = GUA_Timer.day;p[5] = GUA_Timer.hour;  p[6] = GUA_Timer.minutes;p[7] = GUA_Timer.seconds;     //发送GAPRole_GetParameter(GAPROLE_CONNHANDLE, &notify_Handle); GUAprofile_Notify(GUAPROFILE_CHAR1, notify_Handle, p, 20); break;}//设置当前时间case GUA_COMMAND_SET_TIME:{//读出要设置的时间GUA_Timer.year = p[1];GUA_Timer.year <<= 8;GUA_Timer.year |= p[2];          GUA_Timer.month = p[3];          GUA_Timer.day = p[4];GUA_Timer.hour = p[5];  GUA_Timer.minutes = p[6];GUA_Timer.seconds = p[7];//设置当前时间           GUA_RTC_Set(&GUA_Timer);//获取当前时间GUA_RTC_Get(&GUA_Timer);//整理发送缓冲区memset(p, 0xff, GUAPROFILE_CHAR1_LEN); p[0] = GUA_COMMAND_SET_TIME;p[1] = GUA_Timer.year >> 8;p[2] = GUA_Timer.year & 0xff;          p[3] = GUA_Timer.month;          p[4] = GUA_Timer.day;p[5] = GUA_Timer.hour;  p[6] = GUA_Timer.minutes;p[7] = GUA_Timer.seconds;     //发送GAPRole_GetParameter(GAPROLE_CONNHANDLE, &notify_Handle); GUAprofile_Notify(GUAPROFILE_CHAR1, notify_Handle, p, 20); break;}   //其他default:break;        }break;        }default:break;  }  
}  
利用香瓜服务的char1,增加了两条指令:读RTC时间指令、设置RTC时间指令。
七、指令 指令使用简单的通信协议: 功能码(1字节)+年(2字节)+月(1字节)+日(1字节)+时(1字节)+分(1字节)+秒(1字节)+补齐字节(n字节)。
1)读RTC时间指令
01ffffffffffffffffffffffffffffffffffffff 
注: ①0x01:功能码( 读RTC时间指令)。 ②其余0xff:补齐字节,补齐至20字节,也就是19个0xff。

2)设置RTC时间指令
0207e00904102d1effffffffffffffffffffffff( 2016年09月04日  16点45分30秒)
注: ①0x02: 功能码( 设置RTC时间指令 )。 ②0x07e0:2016(年) ③0x09:9(月) ④0x04:4(日) ⑤ 0x10:16(时) ⑥ 0x2d:45(分) ⑦ 0x1e:30(秒) ⑧其余0xff:补齐字节,补齐至20字节,也就是13个0xff。

八、实验结果 1、读一下RTC默认时间 1)发送读RTC时间指令

2)读到返回的默认的RTC时间
如果去解析,就会发现它是2000年1月1日1时2分28秒。 其实RTC默认是从 2000年1月1日1时0分0秒开始计算的,只是我发送指令读取时是在计数开始的2分28秒之后了。
2、更新RTC时间 1) 发送设置RTC时间指令(2016年09月04日  16点45分30秒)

2)读到返回的默认的RTC时间

跟我们发送的指令一样,是 2016年09月04日  16点45分30秒。
3、两分钟后,再次读RTC时间 1)发送读RTC时间指令

2)读到返回的默认的RTC时间

解析后发现它是2016年09月04日16时47分52秒。
比上一次读取的时间多了2分钟,实验结果基本正确。
香瓜未做更为精确的测试去计算误差,大家自行测试吧。 至此,实验结束。




发布者:admin,转转请注明出处:http://www.yc00.com/news/1710054316a1692522.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信