本文基于CH579实现一个最小外围设备,在官方历程Peripheral的基础上精简。

1、main函数

int main( void )
{#if (defined (HAL_SLEEP)) && (HAL_SLEEP == TRUE)GPIOA_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU );GPIOB_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU );
#endif
#ifdef DEBUGGPIOA_SetBits(bTXD1);GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA);UART1_DefInit( );
#endif   PRINT("%s\n",VER_LIB);CH57X_BLEInit( );//协议栈相关初始化HAL_Init( );//硬件初始化GAPRole_PeripheralInit( );//GAP角色初始化,初始化为外围设备,协议栈API函数Peripheral_Init( ); //外围设备,自定义参数初始化,自定义函数while(1){TMOS_SystemProcess( );//TMOS系统运行,协议栈API函数}
}

其中函数 GAPRole_PeripheralInit( ),用于GAP角色初始化,初始化为外围设备,属于协议栈提供的API。

2、Peripheral_Init函数

void Peripheral_Init( )
{Peripheral_TaskID = TMOS_ProcessEventRegister( Peripheral_ProcessEvent );//注册事件回调函数,TMOS是基于时间回调的,一个任务下,最多可以有16个事件,1个用于系统,另外15个用于用户// 设置GAP角色参数{uint8 initial_advertising_enable = TRUE;uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;// Set the GAP Role ParametersGAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );//使能广播GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );//扫描回复数据,数据格式要遵循广播数据格式GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );//扫描回复数据,数据格式要遵循广播数据格式GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval );//最小连接间隔GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval );//最大连接间隔}// Set the GAP CharacteristicsGGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName );//GAP特征,设备名称// Set advertising interval{uint16 advInt = DEFAULT_ADVERTISING_INTERVAL;GAP_SetParamValue( TGAP_DISC_ADV_INT_MIN, advInt );//最小广播间隔GAP_SetParamValue( TGAP_DISC_ADV_INT_MAX, advInt );//最大广播间隔}// Initialize GATT attributesGGS_AddService( GATT_ALL_SERVICES );            // GAPGATTServApp_AddService( GATT_ALL_SERVICES );    // GATT attributes//GAP和GATT这两个服务是协议栈自带的,如上调用即可。// Init Connection ItemperipheralInitConnItem( &peripheralConnList );//连接参数初始化// Setup a delayed profile startuptmos_set_event( Peripheral_TaskID, SBP_START_DEVICE_EVT );//启动Peripheral_TaskID任务下的SBP_START_DEVICE_EVT事件,其中tmos_set_event函数用于立刻执行某个事件
}

3、Peripheral_ProcessEvent任务回调函数

注册了任务回调函数之后,通过函数tmos_set_event或者tmos_start_task启动某个事件,会回调到这个函数中,任务中有4个事件,其中SBP_READ_RSSI_EVT是周期性执行的事件,其他事件在特定情况下才会执行。

uint16 Peripheral_ProcessEvent( uint8 task_id, uint16 events )
{//  VOID task_id; // TMOS required parameter that isn't used in this functionif ( events & SYS_EVENT_MSG ){//系统事件uint8 *pMsg;if ( (pMsg = tmos_msg_receive( Peripheral_TaskID )) != NULL ){Peripheral_ProcessTMOSMsg( (tmos_event_hdr_t *)pMsg );// Release the TMOS messagetmos_msg_deallocate( pMsg );}// return unprocessed eventsreturn (events ^ SYS_EVENT_MSG);}if ( events & SBP_START_DEVICE_EVT ){//GAP外围设备启动事假// Start the DeviceGAPRole_PeripheralStartDevice( Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs );return ( events ^ SBP_START_DEVICE_EVT );}if ( events & SBP_PARAM_UPDATE_EVT )//连接参数更新事件{// Send connect param update requestGAPRole_PeripheralConnParamUpdateReq( peripheralConnList.connHandle,DEFAULT_DESIRED_MIN_CONN_INTERVAL,DEFAULT_DESIRED_MAX_CONN_INTERVAL,DEFAULT_DESIRED_SLAVE_LATENCY,DEFAULT_DESIRED_CONN_TIMEOUT,Peripheral_TaskID);return (events ^ SBP_PARAM_UPDATE_EVT);}if ( events & SBP_READ_RSSI_EVT )//读取RSSI事假{GAPRole_ReadRssiCmd(peripheralConnList.connHandle);tmos_start_task( Peripheral_TaskID, SBP_READ_RSSI_EVT, SBP_READ_RSSI_EVT_PERIOD );      return (events ^ SBP_READ_RSSI_EVT);}   // Discard unknown eventsreturn 0;
}

GAPRole_PeripheralStartDevice( uint8 taskid, gapBondCBs_t *pCB,gapRolesCBs_t *pAppCallbacks );用于启动外围设备;
taskid:任务ID;
pCB:绑定回调函数;
pAppCallbacks :Gap角色回调函数;
其中pAppCallbacks本身是一个结构体,包含三个函数指针,如下

typedef struct
{gapRolesStateNotify_t    pfnStateChange;  //!< Whenever the device changes state//设备状态改变函数指针gapRolesRssiRead_t       pfnRssiRead;     //!< When a valid RSSI is read from controller//RSSI读取函数指针gapRolesParamUpdateCB_t  pfnParamUpdate;  //!< When the connection parameteres are updated//连接参数更新函数指针
} gapRolesCBs_t;

4、peripheralStateNotificationCB状态改变回调函数

如果GAP层设备状态发生了变化,协议栈会回调到这个函数中,用于在这个函数里面处理各种状态。

static void peripheralStateNotificationCB( gapRole_States_t newState, gapRoleEvent_t * pEvent )
{switch ( newState ){case GAPROLE_STARTED://启动PRINT( "Initialized..\n" );break;case GAPROLE_ADVERTISING://广播if( pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT ){Peripheral_LinkTerminated( pEvent );PRINT( "Disconnected.. Reason:%x\n",pEvent->linkTerminate.reason );}PRINT( "Advertising..\n" );break;case GAPROLE_CONNECTED://连接if( pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT ){Peripheral_LinkEstablished( pEvent );//在这个函数中启动读取rssi事件、更新连接参数事件}PRINT( "Connected..\n" );break;case GAPROLE_CONNECTED_ADV://连接+广播PRINT( "Connected Advertising..\n" );break;      case GAPROLE_WAITING://等待if( pEvent->gap.opcode == GAP_END_DISCOVERABLE_DONE_EVENT )//等待广播{PRINT( "Waiting for advertising..\n" );}else if( pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT )//连接断开{Peripheral_LinkTerminated( pEvent );//在这个函数在,重新启动广播,关闭读取rssiPRINT( "Disconnected.. Reason:%x\n",pEvent->linkTerminate.reason );}else if( pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT ){if( pEvent->gap.hdr.status != SUCCESS ){PRINT( "Waiting for advertising..\n" );}else{PRINT( "Error..\n" );}}else{PRINT( "Error..%x\n",pEvent->gap.opcode );}break;case GAPROLE_ERROR:PRINT( "Error..\n" );break;default:break;}
}

5、peripheralParamUpdateCB连接参数更新回调

static void peripheralParamUpdateCB( uint16 connHandle, uint16 connInterval, uint16 connSlaveLatency, uint16 connTimeout )
{if( connHandle == peripheralConnList.connHandle ){peripheralConnList.connInterval = connInterval;peripheralConnList.connSlaveLatency = connSlaveLatency;peripheralConnList.connTimeout = connTimeout;PRINT("Update %x - Int %x \n", connHandle, connInterval);}else{PRINT("ERR..\n");}
}

6、peripheralRssiCBRSSI读取回调

static void peripheralRssiCB( uint16 connHandle, int8 rssi )
{PRINT( "RSSI -%d dB Conn  %x \n", -rssi, connHandle);
}

7、手机app连接设备


可以看到,通过以上代码就构成了最小外围设备。

CH579实现一个最小外围设备(Peripheral)相关推荐

  1. 60v5g无刷电机矢量控制器_完成一个最小FOC矢量控制系统所需的基本模块和功能配置...

    当我们读懂 FOC 矢量控制的基本原理之后,便迫不及待的想动手尝试,去实现一个矢量控制系统,让电机先转起来,有一个直观的感受. 因此,我们需要设计实现一个矢量控制的最小系统,具备矢量控制的基本功能,满 ...

  2. 安装 PyTorch C++ API libtorch 及一个最小例子

    安装 PyTorch C++ API libtorch 及一个最小例子 翻译自:https://pytorch.org/cppdocs/installing.html 我们提供依赖 PyTorch 所 ...

  3. 如何创建一个最小的串口、TTY设备包括虚拟控制台,串口以及伪终端设备的驱动程序

    来源:LINUX设备驱动程序第三版配套源码 Table of Contents tiny_serial.c tiny_tty.c makefile tiny_serial.c /** Tiny Ser ...

  4. 最小的linux内核代码,带你阅读linux内核源码:下载源码、编译内核并运行一个最小系统...

    要学习linux内核,先要能够编译内核,还需要了解内核如何启动根文件系统.这样你才能在修改linux内核代码之后,完成验证的过程. 本文教你完成下列过程: 1.下载linux并编译linux内核源码 ...

  5. 任意给定一个正整数N,求一个最小的正整数M(M1),使得N*M的十进制表示形式里只含有1和0。...

    题目:任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0. 解法一:暴力求解.从1开始查找M,然后判断M*N=X这个数字是否只含有0,1. 解法二:由 ...

  6. div设置一个最小高度和最大高度,但是中间可以靠内容撑开

    div设置一个最小高度和最大高度,但是中间可以靠内容撑开,很简单,给div对应的css加两个代码: 1.min-height:100px;(内容不足100px时候,高度会有100px). 2.max- ...

  7. Linux 系统裁剪--制作一个最小化的Linux iso镜像

    1.前言 一直以来都想制作一个最小化的Linux系统,这个小系统需要有常用的Linux 命令,以及定制化的某些功能.可是由于种种原因一直没能实现,最近终于有时间把它做了出来. 本文所说的精简的Linu ...

  8. 数字黑洞:任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到 * 一个最大的数:65432,一个最小的数23456。

    /** 任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到* 一个最大的数:65432,一个最小的数23456.* 求这两个数字的差,得:41976,把这个数字再次重复上述过程( ...

  9. lingo求一个直角三角形内接一个最小的正方形

    lingo求一个直角三角形内接一个最小的正方形 受给定一个直角三角形,求包含该三角形的最小正方形这道题的启发 model: sets: object/1-3/: f; endsets data: a, ...

最新文章

  1. PingCode 3.0 发布,开启国产研发自动化时代
  2. [大话数据结构-读书笔记] 栈
  3. “赶上热词热概念,是我们不幸的一面” | 对话小冰公司CEO李笛
  4. CentOS 6.5 64位 安装Nginx, MySQL, PHP
  5. vue组件父子组件之间传递数据
  6. 接口与继承动手动脑整理
  7. 泛化,过拟合,欠拟合素材(part2)--机器学习入门之道
  8. Android BLE学习(一): Android搜索BLE设备
  9. oracle中execute函数,oracle Execute Immediate(sql语句)
  10. Java 开源企业信息化建设平台 O2OA 入选码云 GVP 项目
  11. 解决Macbook网络连接成功但是图标一直显示正在查找网络问题
  12. ZStack实践汇 | ZStack平台的使用心得
  13. Bat 无限弹窗(慎用)
  14. JXSE 2.5 : What's Cool #5 -- java.util.concurrent
  15. 小米air2se耳机只有一边有声音怎么办_小米蓝牙耳机Air2 SE,169元是否值得购买?值...
  16. java计算机毕业设计高校墨香文学社管理系统源码+mysql数据库+系统+lw文档+部署
  17. CIE1931标准色度系统
  18. Linux系统上没有scp命令,Linux scp命令没反应
  19. Chrome游览器下载
  20. 自定义EL表达式的函数

热门文章

  1. PHP纯手写正则爬取星座屋网站星座运势数据
  2. 四十、Flume自定义MySQLSource
  3. CM-GAN:图像大面积缺失修复,兼顾全局结构和纹理细节
  4. APP-FND-01564: ORACLE error 24345 in fdlget
  5. 如何将数据库中text字段中返回的数据转换成数组的形式,并且将字符串的数字转换成数字的形式显示
  6. H5是什么?个人浅薄说明
  7. 从理解需求到创造需求,解码YUU品牌成功秘诀
  8. 【ybt高效进阶5-6-3】耗费体力(单调队列优化DP)
  9. 用Axure RP 9制作简易网易云首页
  10. URP Lit Shader解析(2)—LitInput.hlsl