3468|1

79

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【沁恒CH582】 让蓝牙参与到控制中.... [复制链接]

 

上一次我们讨论了通过UART实现的控制代码,我们可以将UART平行变易成由BLE完成的版本。方法仍然同样的简单,我们可以部分修改BLE_UART程序中的一部分。

peripheral_main.c中可以找到这一部分

 __HIGH_CODE
 void Main_Circulation() {
     while (1) {
         TMOS_SystemProcess();
         app_uart_process();
     }
 }

可以定位到uart的处理函数。我们进去观察一下:

 void app_uart_process(void)
 {
     UINT32 irq_status;
     SYS_DisableAllIrq( &irq_status );
     if(uart_rx_flag)
     {
         tmos_start_task( Peripheral_TaskID, UART_TO_BLE_SEND_EVT,2);
         uart_rx_flag = false;
     }
     SYS_RecoverIrq( irq_status );
 ​
     //tx process
     if(R8_UART3_TFC < UART_FIFO_SIZE)
     {
         app_drv_fifo_read_to_same_addr(&app_uart_tx_fifo,(uint8_t *)&R8_UART3_THR,UART_FIFO_SIZE-R8_UART3_TFC);
     }
 }
 ​

与我们预想的并不相同,但是大体上可以理解成当uart_rx_flag标志位被置位之后将会启动进程Peripheral_ProcessEvent特殊的响应任务UART_TO_BLE_SEND_EVT。但是之后我们可以看到UART3的消息响应函数:当消息收到的时候就会设置uart_rx_flag,由实时系统调度实现对这个消息的响应。

 __INTERRUPT
 __HIGH_CODE
 void UART3_IRQHandler(void) {
 ​
     uint16_t error;
     switch( UART3_GetITFlag()) {
         case UART_II_LINE_STAT:
             UART3_GetLinSTA();
             break;
 ​
 ​
         case UART_II_RECV_RDY:
         case UART_II_RECV_TOUT:
             error = app_drv_fifo_write_from_same_addr(&app_uart_rx_fifo,(uint8_t *)&R8_UART3_RBR,R8_UART3_RFC);
             if(error != APP_DRV_FIFO_RESULT_SUCCESS) {
                 for(uint8_t i =0;i<R8_UART3_RFC;i++) {
                     //fifo full,put to fifo black hole
                     for_uart_rx_black_hole = R8_UART3_RBR;
                 }
             }
             uart_rx_flag  = true;
             break;
 ​
         case UART_II_THR_EMPTY:
             break;
         case UART_II_MODEM_CHG:
             break;
         default:
             break;
     }
 }

接下来我们可以找到这个进程的具体定义部分:

 /*********************************************************************
  * @fn      Peripheral_ProcessEvent
  *
  * @brief   Peripheral Application Task event processor.  This function
  *          is called to process all events for the task.  Events
  *          include timers, messages and any other user defined events.
  *
  * @param   task_id - The TMOS assigned task ID.
  * @param   events - events to process.  This is a bit map and can
  *                   contain more than one event.
  *
  * @return events not processed
  */
 uint16 Peripheral_ProcessEvent( uint8 task_id, uint16 events )
 {
     static  attHandleValueNoti_t noti;
 //  VOID task_id; // TMOS required parameter that isn't used in this function
 ​
   if ( events & SYS_EVENT_MSG ){
     uint8 *pMsg;
 ​
     if ( (pMsg = tmos_msg_receive( Peripheral_TaskID )) != NULL ){
       Peripheral_ProcessTMOSMsg( (tmos_event_hdr_t *)pMsg );
       // Release the TMOS message
       tmos_msg_deallocate( pMsg );
     }
     // return unprocessed events
     return (events ^ SYS_EVENT_MSG);
   }
 ​
   if ( events & SBP_START_DEVICE_EVT ){
   // Start the Device
     GAPRole_PeripheralStartDevice( Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs );
     return ( events ^ SBP_START_DEVICE_EVT );
   }
   if ( events & SBP_PARAM_UPDATE_EVT )
   {
     // Send connect param update request
     GAPRole_PeripheralConnParamUpdateReq( peripheralConnList.connHandle,
                                           DEFAULT_DESIRED_MIN_CONN_INTERVAL,
                                           DEFAULT_DESIRED_MAX_CONN_INTERVAL,
                                           DEFAULT_DESIRED_SLAVE_LATENCY,
                                           DEFAULT_DESIRED_CONN_TIMEOUT,
                                           Peripheral_TaskID);
 ​
 ​
 //        GAPRole_PeripheralConnParamUpdateReq( peripheralConnList.connHandle,
 //                                              10,
 //                                              20,
 //                                              0,
 //                                              400,
 //                                              Peripheral_TaskID);
 ​
 ​
     return (events ^ SBP_PARAM_UPDATE_EVT);
   }
 ​
     ///////////////// 这里是关键 /////////////////////////////
   if(events & UART_TO_BLE_SEND_EVT)
   {
       static uint16_t read_length=0;;
       uint8_t result=0xff;
       switch(send_to_ble_state){
           case SEND_TO_BLE_TO_SEND:
 ​
             //notify is not enabled
             if(!ble_uart_notify_is_ready(peripheralConnList.connHandle)){
                 if(peripheralConnList.connHandle == GAP_CONNHANDLE_INIT){
                     //connection lost, flush rx fifo here
                     app_drv_fifo_flush(&app_uart_rx_fifo);
                 }
                 break;
             }
              read_length = ATT_GetMTU(peripheralConnList.connHandle)-3;
 ​
              if(app_drv_fifo_length(&app_uart_rx_fifo)>= read_length){
                   PRINT("FIFO_LEN:%d\r\n",app_drv_fifo_length(&app_uart_rx_fifo));
                  // 这里得到具体的数据,保存在to_test_buffer
                   result = app_drv_fifo_read(&app_uart_rx_fifo,to_test_buffer,&read_length);
                   uart_to_ble_send_evt_cnt = 0;
                }else{
 ​
                   if(uart_to_ble_send_evt_cnt>10){
                       result = app_drv_fifo_read(&app_uart_rx_fifo,to_test_buffer,&read_length);
                       uart_to_ble_send_evt_cnt =0;
                   }else{
                       tmos_start_task( Peripheral_TaskID, UART_TO_BLE_SEND_EVT,4);
                       uart_to_ble_send_evt_cnt ++;
                       PRINT("NO TIME OUT\r\n");
                   }
                }
 ​
                 if(APP_DRV_FIFO_RESULT_SUCCESS == result){
                     noti.len = read_length;
                     noti.pValue = GATT_bm_alloc( peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0 );
                     if(noti.pValue != NULL){
                         tmos_memcpy( noti.pValue, to_test_buffer, noti.len );
                         result = ble_uart_notify( peripheralConnList.connHandle, &noti,0 );
                         if( result != SUCCESS )
                         {
                             PRINT("R1:%02x\r\n",result);
                             send_to_ble_state = SEND_TO_BLE_SEND_FAILED;
                             GATT_bm_free( (gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI );
                             tmos_start_task( Peripheral_TaskID, UART_TO_BLE_SEND_EVT,2);
                         }else{
                             send_to_ble_state = SEND_TO_BLE_TO_SEND;
                             //app_fifo_write(&app_uart_tx_fifo,to_test_buffer,&read_length);
                             //app_drv_fifo_write(&app_uart_tx_fifo,to_test_buffer,&read_length);
                             read_length = 0;
                             tmos_start_task( Peripheral_TaskID, UART_TO_BLE_SEND_EVT,2);
                         }
                     }else{
                             send_to_ble_state = SEND_TO_BLE_ALLOC_FAILED;
                             tmos_start_task( Peripheral_TaskID, UART_TO_BLE_SEND_EVT,2);
                     }
               }else{
                   //send_to_ble_state = SEND_TO_BLE_FIFO_EMPTY;
               }
               break;
           case SEND_TO_BLE_ALLOC_FAILED:
           case SEND_TO_BLE_SEND_FAILED:
 ​
                 noti.len = read_length;
                 noti.pValue = GATT_bm_alloc( peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0 );
                 if(noti.pValue != NULL){
                     tmos_memcpy( noti.pValue, to_test_buffer, noti.len );
                     result = ble_uart_notify( peripheralConnList.connHandle, &noti,0 );
                     if( result != SUCCESS )
                     {
                         PRINT("R2:%02x\r\n",result);
                         send_to_ble_state = SEND_TO_BLE_SEND_FAILED;
                         GATT_bm_free( (gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI );
                         tmos_start_task( Peripheral_TaskID, UART_TO_BLE_SEND_EVT,2);
                     }else{
                         send_to_ble_state = SEND_TO_BLE_TO_SEND;
                         //app_drv_fifo_write(&app_uart_tx_fifo,to_test_buffer,&read_length);
                         read_length = 0;
                         tmos_start_task( Peripheral_TaskID, UART_TO_BLE_SEND_EVT,2);
                     }
                 }else{
                         send_to_ble_state = SEND_TO_BLE_ALLOC_FAILED;
                         tmos_start_task( Peripheral_TaskID, UART_TO_BLE_SEND_EVT,2);
                 }
               break;
           default:
               break;
       }
       return (events ^ UART_TO_BLE_SEND_EVT);
   }
   // Discard unknown events
   return 0;
 }

在响应事件的时候将会进入if(events & UART_TO_BLE_SEND_EVT)分支,可以看到首先从fifo中读取到当前输入的内容保存在to_test_buffer中,然后使用GATT_bm_alloc构建数据包,并使用ble_uart_notify发送数据。

那么按照这个思路,我们有两种响应方式,第一种,直接在中断响应函数中响应输入的信息,另一种则是在此处的程序中另加一个分支来响应输入的消息。

一般地,我们希望对于输入等通信消息的接收响应尽可能简短,而将更加细节的任务放在任务或者事件响应中,那么我们可以改动其中部分代码:为了保证逻辑的清晰性,我只是摘取了主要框架部分,能够让大家更好地看清逻辑关系:

                if(APP_DRV_FIFO_RESULT_SUCCESS == result){
                     noti.len = read_length;
                     noti.pValue = GATT_bm_alloc( peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0 );
                     if(noti.pValue != NULL){
                         tmos_memcpy( noti.pValue, to_test_buffer, noti.len );
                         for(int i = 0; i< noti.len;i++)
                         {
                             switch(noti.pValue)
                             {
                                 case 'A':
                                     //...
                             }
                         }
                         result = ble_uart_notify( peripheralConnList.connHandle, &noti,0 );

下面给出上文中//...部分应当写明的代码:

                  case 'A':case 'B':case 'C':case 'D':
                 state |= 1<<(RxBuff - 'A');
                  break;
               case 'E':case 'F':case 'G':case 'H':
                     state &= 0xFF^1<<(RxBuff - 'A');
                 break;
               default:
                 break;

这样我们就快速实现了一个蓝牙控制的开关设备!

理论上来说还可以通过新建任务等完成更加复杂的功能,对于其中使用的抢占式实时系统以及蓝牙的一些具体细节,且听下回分解。

最新回复

整得有条有理,值得借鉴与学习,也期待你的精彩下回!  详情 回复 发表于 2022-4-12 13:54
点赞 关注(1)
 
 

回复
举报

7090

帖子

11

TA的资源

版主

沙发
 
整得有条有理,值得借鉴与学习,也期待你的精彩下回!
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表