BLE UART的例程蓝牙接收和发射的变量是哪个?

我按照CH573的BLE UART例程,的确能够实现与手机收发。

但是找了半天没找到串口3打印的接收数据是在哪个变量?

发送数据又在哪个变量?

是在app_uart_process()里面吗? 具体在哪?

您好,主循环里的app_uart_process()一直在查询uart_rx_flag,uart_rx_flag为1时会调用tmos_start_task(Peripheral_TaskID, UART_TO_BLE_SEND_EVT, 2);任务将串口接收到的数据通过蓝牙发送出去,uart_rx_flag在串口中断中置1。

串口接收的数据会放到app_uart_rx_fifo,

最终的蓝牙发送函数是下面这段:

 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);
           }
 }

十分感谢二楼详细的回答。我还有这些疑问:

疑问1、我用BLE UART发现了一个问题:我先用手机跟573连接,然后手机往573发了6个hi,然后,当然573的串口3也接收到了。接着我从573的串口3往手机发了3次123,手机收到的内容却是这样的“hihihihihihi123123123”,就是手机收到的数据不是3个123,而是包含之前发出去的6个hi,这是为什么呢? 是因为收发之前没有清空FIFO? 还是说收发都是共用一个FIFO?

image.pngimage.png



疑问2、我尝试将从手机发到串口3的hi在串口1打印出来。

//ble?uart?service?callback?handler
void?on_bleuartServiceEvt(uint16_t?connection_handle,?ble_uart_evt_t?*p_evt)
{
????switch(p_evt->type)
????{
????????case?BLE_UART_EVT_TX_NOTI_DISABLED:
????????????PRINT("%02x:bleuart_EVT_TX_NOTI_DISABLED\r\n",?connection_handle);
????????????break;
????????case?BLE_UART_EVT_TX_NOTI_ENABLED:
????????????PRINT("%02x:bleuart_EVT_TX_NOTI_ENABLED\r\n",?connection_handle);
????????????break;
????????case?BLE_UART_EVT_BLE_DATA_RECIEVED:
????????????PRINT("BLE?RX?DATA?len:%d\r\n",?p_evt->data.length);

????????????//for?notify?back?test
????????????//to?ble
????????????uint16_t?to_write_length?=?p_evt->data.length;
????????????app_drv_fifo_write(&app_uart_rx_fifo,?(uint8_t?*)p_evt->data.p_data,?&to_write_length);//串口接收的数据会放到app_uart_rx_fifo
????????????tmos_start_task(Peripheral_TaskID,?UART_TO_BLE_SEND_EVT,?2);
????????????//end?of?nofify?back?test

????????????//ble?to?uart
????????????app_uart_tx_data((uint8_t?*)p_evt->data.p_data,?p_evt->data.length);
????????????PRINT("%s\r\n",?p_evt->data.p_data);
????????????break;
????????default:
????????????break;
????}
}

以上在原例程中,我多加了一句话,

PRINT("%s\r\n", p_evt->data.p_data);

将从手机发到串口3的hi在串口1打印出来

但是打印出来的却是hi7,如图

image.png

多了一个字符7,

如果我发的是hello的话,后面还多了几个字符,乱码

image.png

这是为啥?怎么才能抓取手机某次发过来的数据? 接收的数据只打印当前的消息内容,不打印之前已经收到的


上面的程序不是单一一个例程,而是我把BLE UART跟Centperi这两个例程合起来了,所以串口1还有其他的打印内容


问题1:

默认程序收到手机发送数据后会通过蓝牙回给app,如果不需要可以屏蔽下面这段代码:

  uint16_t to_write_length = p_evt->data.length;
            app_drv_fifo_write(&app_uart_rx_fifo, (uint8_t *)p_evt->data.p_data, &to_write_length);
            tmos_start_task(Peripheral_TaskID, UART_TO_BLE_SEND_EVT, 2);

问题2:不要打印输出字符串,遇0才停止,你并不知道0在什么位置,如果要打印字符,可以根据长度写for循环打印字符,



好的 谢谢。


另外,现在有2个开发板,分别是573和582,

573下载了57x例程的CentPeri和BLE UART融合的工程代码这里称之为CentPeri_UART工程

582下载了58x例程里面的BLE UART的工程代码

用手机分别对这2个开发板都能实现收发,UART3能看见收发的数据。

我在CentPeri_UART工程里面将582板子的蓝牙地址设为了白名单,2个板上电后,能连接上对方,如下图UART1口能显示RSSI

image.png


当我把串口线都接到板子各自的UART3口,从573发1234出去,并没有在582的串口3收到1234,从582发abcd出去,也没有在573的串口3收到abcd这是为什么呢? 是我漏改什么了吗?

image.png


您好,默认主机例程是和Peripheral例程通信的,无法与BLE UART例程直接通讯,枚举服务需要做出修改,可以发送邮件至邮箱hy@wch.cn,可以给你发送一个在ch582上已经修改好主机的例程参考。


邮件已发,期待你的回复。谢谢!


您好,邮件已回复,注意查收。


      我想问一下#2那里,那段代码的作用是芯片从串口接收到数据,然后通过蓝牙发送到手机APP吗?
      5PF(PYY($T{UDB1RA1IT)@O.png

     我看这个进入的条件 是说BLE发送失败了才会执行下面的代码,请问为什么是这样的呢


是的,不过与你截图中的case不一样,将串口收到的数据通过蓝牙发送到app是在SEND_TO_BLE_TO_SEND中,如果发送失败了,才会进入SEND_TO_BLE_SEND_FAILED.



     好的谢谢 我还想问一下就是下面这个代码   具体是哪一行通过蓝牙将数据发送给手机APP呢 

    image.png


 


可以看下二楼的截图注释,先申请内存,再赋值数据,最后发送数据,

  result = ble_uart_notify(peripheralConnList.connHandle, &noti, 0);



      这个我知道 但是你刚刚不是说  将串口收到的数据通过蓝牙发送到app是在SEND_TO_BLE_TO_SEND中,如果发送失败了,才会进入SEND_TO_BLE_SEND_FAILED.

      但是我先进入的这个SEND_TO_BLE_TO_SEND没有找到其是如何发送数据的,只有在SEND_TO_BLE_SEND_FAILED中才能找到你说的这一条语句

 result = ble_uart_notify(peripheralConnList.connHandle, &noti, 0);

      

       如果我一开始就从SEND_TO_BLE_TO_SEND中发送数据成功了 那我就不会进入到SEND_TO_BLE_SEND_FAILED中了呀
但是现在问题就是我在SEND_TO_BLE_TO_SEND没有找到其发送数据语句




 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));
                    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;



      好的感谢!!!


我想问一下#2蓝牙接收是通过哪里实现的?蓝牙接收后是通过write写入tx_fifo,然后readtosameaddr读取tx_fifo,再通过串口发送出去吗?


只有登录才能回复,可以选择微信账号登录