我按照CH573的BLE UART例程,的确能够实现与手机收发。
但是找了半天没找到串口3打印的接收数据是在哪个变量?
发送数据又在哪个变量?
是在app_uart_process()里面吗? 具体在哪?
我按照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, ¬i, 0);//发送数据 if(result != SUCCESS)//发送失败 { PRINT("R1:%02x\r\n", result); send_to_ble_state = SEND_TO_BLE_SEND_FAILED; GATT_bm_free((gattMsg_t *)¬i, 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?
疑问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,如图
多了一个字符7,
如果我发的是hello的话,后面还多了几个字符,乱码
这是为啥?怎么才能抓取手机某次发过来的数据? 接收的数据只打印当前的消息内容,不打印之前已经收到的
上面的程序不是单一一个例程,而是我把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
当我把串口线都接到板子各自的UART3口,从573发1234出去,并没有在582的串口3收到1234,从582发abcd出去,也没有在573的串口3收到abcd这是为什么呢? 是我漏改什么了吗?
您好,默认主机例程是和Peripheral例程通信的,无法与BLE UART例程直接通讯,枚举服务需要做出修改,可以发送邮件至邮箱hy@wch.cn,可以给你发送一个在ch582上已经修改好主机的例程参考。
邮件已发,期待你的回复。谢谢!
您好,邮件已回复,注意查收。
我想问一下#2那里,那段代码的作用是芯片从串口接收到数据,然后通过蓝牙发送到手机APP吗?
我看这个进入的条件 是说BLE发送失败了才会执行下面的代码,请问为什么是这样的呢
是的,不过与你截图中的case不一样,将串口收到的数据通过蓝牙发送到app是在SEND_TO_BLE_TO_SEND中,如果发送失败了,才会进入SEND_TO_BLE_SEND_FAILED.
好的谢谢 我还想问一下就是下面这个代码 具体是哪一行通过蓝牙将数据发送给手机APP呢
可以看下二楼的截图注释,先申请内存,再赋值数据,最后发送数据,
result = ble_uart_notify(peripheralConnList.connHandle, ¬i, 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, ¬i, 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, ¬i, 0); //数据发送 if(result != SUCCESS) { PRINT("R1:%02x\r\n", result); send_to_ble_state = SEND_TO_BLE_SEND_FAILED; GATT_bm_free((gattMsg_t *)¬i, 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,再通过串口发送出去吗?