热度 22
2015-9-21 16:03
3224 次阅读|
1 个评论
TI BLE 协议栈提供的例程里面有一个 TimeApp ,从文档 TI_BLE_Software_Developer's_Guide.pdf 的第 16 章介绍来看,是使用了类似 RTC 的时钟来实现一个蓝牙手表功能。这两天研究了一下,另外在网上也找到了一篇写得还算详尽的博文(参考文献 1 ),发现 TI BLE 协议栈已经封装好一个 RTC ,在 OSAL_ClockBLE.c 文件中,该文件在文后的附件中供参考,也可以去参考文献 1 ( http://blog.csdn.net/xiaoleiacmer/article/details/42458351 )中,里面有博主的一些中文注释,可以帮助大家更好的理解。 OSAL_ClockBLE.c 中的主要函数及功能: 1 ) void osalTimeUpdate( void ); 更新时间 2 ) void osal_setClock( UTCTime newTime ); 设定时间,输入参数为秒数,指的是从 2000 年 1 月 1 日 0 时 0 分 0 秒开始的秒数。 UTCTime 的定义如下: // number of seconds since 0 hrs, 0 minutes, 0 seconds, on the // 1st of January 2000 UTC typedef uint32 UTCTime; 3 ) UTCTime osal_getClock( void ); 获取当前时间,返回的是秒数, UTCTime 的定义见 2 ),秒数也是从 2000 年 1 月 1 日 0 时 0 分 0 秒开始的秒数。 4 ) void osal_ConvertUTCTime( UTCTimeStruct *tm, UTCTime secTime ); 将秒数转换成 UTCTimeStruct 结构。 UTCTimeStruct 结构的定义如下: typedef struct { uint8 seconds; // 0-59 uint8 minutes; // 0-59 uint8 hour; // 0-23 uint8 day; // 0-30 uint8 month; // 0-11 uint16 year; // 2000+ } UTCTimeStruct; 5 ) UTCTime osal_ConvertUTCSecs( UTCTimeStruct *tm ); 将 UTCTimeStruct 结构转换成秒数。 简单来说, BLE 协议栈中的 RTC 是从 2000 年 1 月 1 日 0 时 0 分 0 秒开始定时的,获取和设定时间时都用的这个秒数,对于用户来说,转换成 UTCTimeStruct 最方便。所以要获取当前时间,要调用 osal_getClock( ) 后再调用 osal_ConvertUTCTime( ) ,将秒数转成 UTCTimeStruct ;要修改设定时间,可以将新的时间填充到 UTCTimeStruct 中,再调用 osal_ConvertUTCSecs( ) ,然后调用 osal_setClock( ) ,这样就重新更新了时间。 测试的步骤可以参考如下: 1 )添加一个 Time Profile ,定义一个 Time Service 和一个 Time Characteristic ,该特征值是 6 字节的的数组,用来更新时间,可以理解为手机 App 通过蓝牙来同步时间。数据用来保存年月日时分秒的信息,年只保存后两位,即,如 2015 年,只用 15 来表示,毕竟一个字节最大只能到 255. 2 )定义一个 UTCTimeStruct 变量,用来保存蓝牙更新过来的时间,同时调用相关函数来设定时间。 3 )定义一个周期事件,如 30s ,获取当前时间,通过 LCD 或通过 UART 到 PC 上来显示时间。 下面是一段通过特征值来设定时间并显示的代码片段。这里只显示了时和分,如 15 : 57 UTCTimeStruct *Time; uint8 TimeDisplayBuf ; uint8 newValue ; UTCTimeStruct TimeTemp; UTCTime newTime; TIME_GetParameter(TIME_CHAR, newValue); TimeTemp.year = 2000 + newValue ; TimeTemp.month = newValue ; TimeTemp.day = newValue ; TimeTemp.hour = newValue ; TimeTemp.minutes = newValue ; TimeTemp.seconds = newValue ; newTime = osal_ConvertUTCSecs( TimeTemp ); osal_setClock( newTime ); osalTimeUpdate(); osal_ConvertUTCTime( Time, osal_getClock() ); TimeDisplayBuf = (Time-hour) / 10 + '0'; TimeDisplayBuf = (Time-hour) % 10 + '0'; TimeDisplayBuf = (Time-minutes) / 10 + '0'; TimeDisplayBuf = (Time-minutes) % 10 + '0'; TimeDisplayBuf = ‘:’; LCD_ShowString(0,4, TimeDisplayBuf); CC2541 的 RTC 是通过外部或内部晶振来计时,误差会比较大,所以最好在连接到蓝牙时就校时,并且最好设定为比如每隔几个小时来校时,以使时间显示得比较准确。 参考文献: 1. http://blog.csdn.net/xiaoleiacmer/article/details/42458351