2020-10-17

CC2640蓝牙5.1学习(3)
观看升润科技的视频,升润科技的学习资料在上篇文章里面有分享。
升润科技视频学习地址http://t.elecfans.com/v/2307.html。
消息的接收与发送
按键按下触发按键回调,按键回调确认按键按下,启用一个定时器,发送消息,进入主线程之后接收消息,然后进行一个处理,处理完后比较发送与接收的内容是否匹配,如果匹配通过翻转IO口进行演示。
代码分析:
static PIN_Handle ioTestHandle; //GPIO引脚句柄
static PIN_State ioTestState;
IO的句柄和状态,初始化IO的时候用到。
static Clock_Struct keyChangeClock; //定时任务
构建一个定时任务的句柄

static u8 keysPressed; //键值

static keysPressedCB_t appKeyChangeHandler = NULL;

appKeyChangeHandler是一个函数指针,指向按键的处理函数,

PIN_Config ioTestConfig[] = {
IOID_0 | PIN_GPIO_OUTPUT_EN | PIN_INPUT_DIS | PIN_GPIO_LOW| PIN_HYSTERESIS,
IOID_1 | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLUP| PIN_HYSTERESIS,
IOID_2 | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLDOWN| PIN_HYSTERESIS,
IOID_3 | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLUP| PIN_HYSTERESIS,
IOID_5 | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLDOWN| PIN_HYSTERESIS,
IOID_6 | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLUP| PIN_HYSTERESIS,
PIN_TERMINATE
};
IO配置的一个数组,IOID_0做LED翻转输出,IOID_1做按键的输入

Event_Handle pTTCSDKKeyEvent;
Queue_Handle pTTCSDKKeyQueueHandle;
一个事件的句柄,一个消息的句柄。

#pragma optimize=none //表示不优化下面的函数
void TTCDriverDemoIOInit(keysPressedCB_t appKeyCB,
Event_Handle eventHandle,
Queue_Handle queueHandle )
{
uint8 state;

pTTCSDKKeyEvent = eventHandle;
pTTCSDKKeyQueueHandle = queueHandle;
// 设置按键处理函数(消抖处理)
Util_constructClock(&keyChangeClock,
TTCDriverDemoIOChangeClockHandler,
100, //200mS
0, //循环的周期为0(即不循环定时)
false, //先不启动这个定时器
0); //不需要传输参数

state = TTCDriverIOOpen(&ioTestHandle,&ioTestState,(const PIN_Config *)ioTestConfig);

state = TTCDriverIORegisterIntCallBack(&ioTestHandle,TTCDrierDemoIOIsrCallback);

state = TTCDriverIOSetConfig(&ioTestHandle,PIN_BM_IRQ,IOID_1 | PIN_IRQ_NEGEDGE);//配置IOID_1的中断功能 

appKeyChangeHandler = appKeyCB;                                             //注册用户的按键处理函数  消抖处理之后就可以正常使用按键值了

}
按键的初始化函数,appKeyCB是一个回调函数,typedef void (*keysPressedCB_t)(u8 keysPressed);appKeyCB的参数是按键的值,eventHandle是事件句柄,queueHandle 是消息句柄,TTCDriverDemoIOInit会被放到主线程的初始化之中,并把主线程的事件句柄和消息句柄代入,主线程的事件句柄和消息句柄会被存入到本地的事件句柄和消息句柄pTTCSDKKeyEvent 和pTTCSDKKeyQueueHandle 之中,Util_constructClock构建一个定时函数用于按键的消抖,TTCDriverIOOpen开启IO并对IO进行配置,TTCDriverIORegisterIntCallBack注册一个IO的回调函数,当IO中断触发以后,会调用TTCDrierDemoIOIsrCallback,TTCDriverIOSetConfig是IO中断功能的配置,appKeyChangeHandler = appKeyCB; 指向代入的函数处理函数。

【函 数】 TTCDrierDemoIOIsrCallback(PIN_Handle handle, PIN_Id pinId)
【概 述】 io中断回调函数
【入口参数】 无
【返回参数】 无
【说 明】 无
*******************************************************************************/
static void TTCDrierDemoIOIsrCallback(PIN_Handle handle, PIN_Id pinId){
Util_startClock(&keyChangeClock); //开启这个软件定时器(相当于延时)
}
按下按键会触发按键中断,回调按键中断处理函数TTCDrierDemoIOIsrCallback,TTCDrierDemoIOIsrCallback里面回启动构建好的定时函数Util_startClock,定时函数Util_startClock的作用是延时100MS,100MS后进入定时回调函数TTCDriverDemoIOChangeClockHandler
【函 数】 TTCDriverDemoIOChangeClockHandler(UArg a0)
【概 述】 定时任务回调
【入口参数】 无
【返回参数】 无
【说 明】 无
*******************************************************************************/
static void TTCDriverDemoIOChangeClockHandler(UArg a0){
if(TTCDriverIOGetInputValue(IOID_1) == 0){ //判断io的电平
keysPressed |= 0x01;
}else{
keysPressed &= ~0x01;
}
if (appKeyChangeHandler != NULL){
(*appKeyChangeHandler)(keysPressed); //调用 用户的处理函数
}
}
TTCDriverDemoIOChangeClockHandler函数是读入IO_1的状态看按键是否按下如果按下就等于0 按键键值赋予0X01,如果没有按下按键为1,则赋予按键键值0,以上的作用是对按键进行消抖,按键处理函数appKeyChangeHandler值如果不为空,就把处理的按键键值代入
【函 数】 KeyPressHandler(uint8_t keys)
【概 述】 用户的按键处理函数
【入口参数】 按键码
【返回参数】 无
【说 明】 无
*******************************************************************************/
void KeyPressHandler(u8 keys){
if(keys & 0x01){
//取反IOID_0脚的状态
// TTCDriverIOSetOutputVaule(&ioTestHandle,IOID_0,!TTCDriverIOGetOutputValue(IOID_0));
static uint8 buffer[3]={0x11,0x22,0x33};
static uint8 len = 3;
TTCMsg_t *pMsg;
if(pTTCSDKKeyEvent == NULL) {
return;
}

    if ((pMsg = ICall_malloc( sizeof(TTCMsg_t) + sizeof(u8)*len ))) {
        
        pMsg->hdr.event = TTCSDK_MSG_DRIVER_KEY_EVENT;
        pMsg->hdr.state = len;
        pMsg->pValue    = (u8*)(&pMsg->pValue + 1);
        memcpy(pMsg->pValue, buffer, len);
        Util_enqueueMsg(pTTCSDKKeyQueueHandle, 
                        pTTCSDKKeyEvent,
                        (u8*)pMsg);
    }  
}

}
这个就是按键处理函数,按键键值代入,如果键值为1就是按键按下了,那么
static uint8 buffer[3]={0x11,0x22,0x33};
static uint8 len = 3;
定义一个长度为3的常量数组
TTCMsg_t pMsg;
定义一个消息结构体
if(pTTCSDKKeyEvent == NULL) {
return;
}
判断一下主线程代入的事件句柄是否为空,如果为空就返回不进行发送,如果不为空,就先开辟一个缓存ICall_malloc( sizeof(TTCMsg_t) + sizeof(u8)len ),缓存的大小为消息结构体本身的大小以及一段len个U8型的长度,用pMsg 消息结构体指针指向缓存,如果开辟成功, pMsg->hdr.event = TTCSDK_MSG_DRIVER_KEY_EVENT;
pMsg->hdr.state = len;
pMsg->pValue = (u8
)(&pMsg->pValue + 1);
对消息结构体进行赋值,TTCSDK_MSG_DRIVER_KEY_EVENT使我们定义的一个事件,定义的方法是在TTCSDKconfig.h的头文件里面定义
//自己定义一个事件
#define TTCSDK_MSG_DRIVER_KEY_EVENT 0x000F //TTCSDK驱动事件 KEY
pMsg->pValue = (u8
)(&pMsg->pValue + 1);缓存的地址怎么弄的没搞懂
然后把buffer里面的内容赋值到pMsg->pValue,长度为3,
然后调用把消息纳入队列函数
Util_enqueueMsg(pTTCSDKKeyQueueHandle,
pTTCSDKKeyEvent,
(u8*)pMsg);
pTTCSDKKeyQueueHandle和pTTCSDKKeyEvent是主函数传入的消息句柄和事件句柄,(u8*)pMsg是消息结构体装载完成后的结构体。

在主线程初始化完成后,会进入主线程的处理函数
【函    数】  TTCBlePeripheralTaskFxn(UArg a0, UArg a1)

【概 述】 线程处理
【入口参数】 a0,a1 参数
【返回参数】 无
【说 明】 无
******************************************************************************/
static void TTCBlePeripheralTaskFxn(UArg a0, UArg a1){
TTCBlePeripheralTaskInit();

for (;;){
    uint32_t events;
    events = Event_pend(syncEvent,                                          \
                        Event_Id_NONE,                                      \
                        TTC_ALL_EVENTS,                                     \
                        ICALL_TIMEOUT_FOREVER);
    
    if (events) {
        
        #ifdef TTCBLE_IBEACON
              TTCBeaconProcessStack(&selfEntity); 
        #else
              TTCBlePeripheralProcessStack(&selfEntity);    
        #endif                         
        if (events & TTC_QUEUE_EVT) {
            while (!Queue_empty(appMsgQueue)){                              //接收消息
                TTCMsg_t *pMsg = (TTCMsg_t *)Util_dequeueMsg(appMsgQueue);
                if (pMsg){                    
                    TTCBlePeripheralTaskProcessAppMsg(pMsg);                //处理消息                    
                    ICall_free(pMsg);                                       //释放内存
                }
            }
        }
        
#ifdef TTC_DEBUG
        TTCDebugEvent();       
#endif                                                                             
#ifdef TTCBLE_WECHAT
       TTCBleWechatEvent();
#endif                                                                      //TTCBLE_WECHAT        
#ifdef TTCBLE_IBEACON
        TTCBeaconEvent();                                                   //Ibeacon事件
#endif
    } 
}

}
然后再到消息处理函数 if (pMsg){
TTCBlePeripheralTaskProcessAppMsg(pMsg); //处理消息

【函 数】 TTCBlePeripheralTaskProcessAppMsg(TTCMsg_t *pMsg)
【概 述】 线程消息处理函数
【入口参数】 pMsg : 消息数据
【返回参数】 无
【说 明】 请注意内存的释放
******************************************************************************/
static void TTCBlePeripheralTaskProcessAppMsg(TTCMsg_t *pMsg){
switch (pMsg->hdr.event){
case TTCSDK_MSG_GET_BLE_STATE_EVENT:{

#ifdef TTCBLE_IBEACON
TTCBeaconProcessStateChangeEvt( (gaprole_States_t)pMsg->hdr.state );
#else
TTCBlePeripheralProcessStateChangeEvt( (gaprole_States_t)pMsg->hdr.state );
#endif //TTCBLE_IBEACON

#ifdef TTCBLE_WECHAT
if( (gaprole_States_t)pMsg->hdr.state != GAPROLE_CONNECTED &&
(gaprole_States_t)pMsg->hdr.state != GAPROLE_CONNECTED_ADV ){
TTCBleWechatStateClear();
}
#endif
#ifdef TTC_DEBUG
TTCDebugLogPrintBLEState((gaprole_States_t)pMsg->hdr.state);
#endif//TTCBLE_WECHAT
}break;

    case TTCSDK_MSG_GET_BLE_DATA_EVENT:{ 
        TTCBlePeripheralTaskGetBleData( (TTCMsg_t *)pMsg );
    }break; 
    
    case TTCSDK_MSG_REFRESH_RSSI_EVENT:{
        TTCBlePeripheralTaskRefreshRSSI( (s8 *)pMsg->pValue );
    }break;
    
    case TTCSDK_MSG_GET_BLE_PARAM_EVENT:{
        TTCBlePeripheralTaskGetBleParam( (TTCBleParamUpdate_t *)pMsg->pValue );
    }break;

#ifdef TTCDRIVER_UTC
case TTCSDK_MSG_DRIVER_UTC_EVENT:{
}break;
#endif //TTCDRIVER_UTC

#ifdef FEATURE_OAD
case TTCSDK_MSG_OAD_EVENT:{
TTCBlePeripheralTaskOADProcess( (oadTargetWrite_t *)pMsg->pValue );
}break;
#endif //FEATURE_OAD

#ifdef TTCBLE_WECHAT
case TTCSDK_MSG_BLE_WECHAT_EVENT:{
TTCDemoWechatProcess(pMsg);
}break;
#endif //TTCBLE_WECHAT

#ifdef TTC_DEBUG
case TTCSDK_MSG_DRIVER_UART_EVENT:{
TTCDriverUartProcess(pMsg);
}break;
#endif

    default:break;
}

}
添加事件号和对应的事件处理函数
#endif
case TTCSDK_MSG_DRIVER_KEY_EVENT:{
TTCDriverKeyProcess(pMsg);
}break;
default:break;

事件处理函数

【函 数】 TTCDriverKeyProcess(TTCMsg_t * TTCMsg)
【概 述】 处理UART
【入口参数】 TTCMsg : 处理按键发上来的消息
【返回参数】 无
【说 明】 无
******************************************************************************/
#pragma optimize = none //不优化下列函数
void TTCDriverKeyProcess(TTCMsg_t * TTCMsg) {
u16 len = TTCMsg->hdr.state;
u8 buf[3];
memset(buf,NULL,3);
asm(“nop”);
memcpy(buf, TTCMsg->pValue, TTCMsg->hdr.state);
// if((buf[0] == 0x11)&&(buf[1] == 0x22)&&(buf[2] == 0x33))
// {
// TTCDriverIOSetOutputVaule(&ioTestHandle,IOID_0,!TTCDriverIOGetOutputValue(IOID_0));
// }
static bool power_test_flag=0;
if(power_test_flag == 0)
{
power_test_flag = 1;
Power_setConstraint(PowerCC26XX_SB_DISALLOW);
Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
}
else
{
power_test_flag = 0;
Power_releaseConstraint(PowerCC26XX_SB_DISALLOW);
Power_releaseConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
}
asm(“nop”);
}
是对消息的解析, u16 len = TTCMsg->hdr.state;是吧消息长度提取出来,
memcpy(buf, TTCMsg->pValue, TTCMsg->hdr.state);把消息的内容复制到buf中,然后判断buf中内容是否与发送的内容相等,如果相等就进行一个IO口翻转的动作// if((buf[0] == 0x11)&&(buf[1] == 0x22)&&(buf[2] == 0x33))
// {
// TTCDriverIOSetOutputVaule(&ioTestHandle,IOID_0,!TTCDriverIOGetOutputValue(IOID_0));
// }

在主线程初始化中要调用TTCDriverDemoIOInit,对IO初始化, TTCDriverDemoIOInit(KeyPressHandler,
syncEvent,
appMsgQueue );
其中KeyPressHandler是按键处理函数,

【函 数】 KeyPressHandler(uint8_t keys)
【概 述】 用户的按键处理函数
【入口参数】 按键码
【返回参数】 无
【说 明】 无
*******************************************************************************/
void KeyPressHandler(u8 keys){
if(keys & 0x01){
//取反IOID_0脚的状态
// TTCDriverIOSetOutputVaule(&ioTestHandle,IOID_0,!TTCDriverIOGetOutputValue(IOID_0));
static uint8 buffer[3]={0x11,0x22,0x33};
static uint8 len = 3;
TTCMsg_t *pMsg;
if(pTTCSDKKeyEvent == NULL) {
return;
}

    if ((pMsg = ICall_malloc( sizeof(TTCMsg_t) + sizeof(u8)*len ))) {
        
        pMsg->hdr.event = TTCSDK_MSG_DRIVER_KEY_EVENT;
        pMsg->hdr.state = len;
        pMsg->pValue    = (u8*)(&pMsg->pValue + 1);
        memcpy(pMsg->pValue, buffer, len);
        Util_enqueueMsg(pTTCSDKKeyQueueHandle, 
                        pTTCSDKKeyEvent,
                        (u8*)pMsg);
    }  
}

}

第二个和第三个参数是主线程的定义的事件句柄和消息句柄
static ICall_SyncHandle syncEvent;
static Queue_Struct appMsg; //消息结构
static Queue_Handle appMsgQueue; //消息句柄
不要忘了把头文件包括在MAIN.C文件上,然后下载到板子上演示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值