CH579实现一个最小外围设备(Peripheral)
本文基于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)相关推荐
- 60v5g无刷电机矢量控制器_完成一个最小FOC矢量控制系统所需的基本模块和功能配置...
当我们读懂 FOC 矢量控制的基本原理之后,便迫不及待的想动手尝试,去实现一个矢量控制系统,让电机先转起来,有一个直观的感受. 因此,我们需要设计实现一个矢量控制的最小系统,具备矢量控制的基本功能,满 ...
- 安装 PyTorch C++ API libtorch 及一个最小例子
安装 PyTorch C++ API libtorch 及一个最小例子 翻译自:https://pytorch.org/cppdocs/installing.html 我们提供依赖 PyTorch 所 ...
- 如何创建一个最小的串口、TTY设备包括虚拟控制台,串口以及伪终端设备的驱动程序
来源:LINUX设备驱动程序第三版配套源码 Table of Contents tiny_serial.c tiny_tty.c makefile tiny_serial.c /** Tiny Ser ...
- 最小的linux内核代码,带你阅读linux内核源码:下载源码、编译内核并运行一个最小系统...
要学习linux内核,先要能够编译内核,还需要了解内核如何启动根文件系统.这样你才能在修改linux内核代码之后,完成验证的过程. 本文教你完成下列过程: 1.下载linux并编译linux内核源码 ...
- 任意给定一个正整数N,求一个最小的正整数M(M1),使得N*M的十进制表示形式里只含有1和0。...
题目:任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0. 解法一:暴力求解.从1开始查找M,然后判断M*N=X这个数字是否只含有0,1. 解法二:由 ...
- div设置一个最小高度和最大高度,但是中间可以靠内容撑开
div设置一个最小高度和最大高度,但是中间可以靠内容撑开,很简单,给div对应的css加两个代码: 1.min-height:100px;(内容不足100px时候,高度会有100px). 2.max- ...
- Linux 系统裁剪--制作一个最小化的Linux iso镜像
1.前言 一直以来都想制作一个最小化的Linux系统,这个小系统需要有常用的Linux 命令,以及定制化的某些功能.可是由于种种原因一直没能实现,最近终于有时间把它做了出来. 本文所说的精简的Linu ...
- 数字黑洞:任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到 * 一个最大的数:65432,一个最小的数23456。
/** 任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到* 一个最大的数:65432,一个最小的数23456.* 求这两个数字的差,得:41976,把这个数字再次重复上述过程( ...
- lingo求一个直角三角形内接一个最小的正方形
lingo求一个直角三角形内接一个最小的正方形 受给定一个直角三角形,求包含该三角形的最小正方形这道题的启发 model: sets: object/1-3/: f; endsets data: a, ...
最新文章
- PingCode 3.0 发布,开启国产研发自动化时代
- [大话数据结构-读书笔记] 栈
- “赶上热词热概念,是我们不幸的一面” | 对话小冰公司CEO李笛
- CentOS 6.5 64位 安装Nginx, MySQL, PHP
- vue组件父子组件之间传递数据
- 接口与继承动手动脑整理
- 泛化,过拟合,欠拟合素材(part2)--机器学习入门之道
- Android BLE学习(一): Android搜索BLE设备
- oracle中execute函数,oracle Execute Immediate(sql语句)
- Java 开源企业信息化建设平台 O2OA 入选码云 GVP 项目
- 解决Macbook网络连接成功但是图标一直显示正在查找网络问题
- ZStack实践汇 | ZStack平台的使用心得
- Bat 无限弹窗(慎用)
- JXSE 2.5 : What's Cool #5 -- java.util.concurrent
- 小米air2se耳机只有一边有声音怎么办_小米蓝牙耳机Air2 SE,169元是否值得购买?值...
- java计算机毕业设计高校墨香文学社管理系统源码+mysql数据库+系统+lw文档+部署
- CIE1931标准色度系统
- Linux系统上没有scp命令,Linux scp命令没反应
- Chrome游览器下载
- 自定义EL表达式的函数