当前位置:   article > 正文

解决nrf52832串口蓝牙4.0传输大量数据断开蓝牙的问题_52832传输大数据断开

52832传输大数据断开

使用nordic官网的串口蓝牙时,若传输大量数据,会使单片机复位,从而蓝牙断开。

原因:在串口服务函数里发送蓝牙的数据,导致中断响应不及时,系统复位。

解决方法:串口服务函数不要发送蓝牙数据,只接受串口数据,使用定时器发送数据。

为了防止不同的数据帧粘在同一包,串口传输时定义通信协议,再使用fifo缓存将要发送的数据。fifo尽量大,5K没有问题。

定义了一个简单的协议:

  Head        Length        Data 
  2字节        2字节      不定长度

0x11 0x22   0xxx

Head  数据包头
Length Data长度
Data  具体数据

具体代码如下:

  1. uint8_t uart_readF = 0; //命令接收标志
  2. uint16_t uart_len = 0; //命令总长度
  3. uint16_t uart_cnt = 0; //命令已接收长度
  4. void uart_event_handle(app_uart_evt_t * p_event)
  5. {
  6. uint8_t dat;
  7. switch (p_event->evt_type)
  8. {
  9. case APP_UART_DATA_READY:
  10. UNUSED_VARIABLE(app_uart_get(&dat));
  11. switch(uart_readF){
  12. case 0:
  13. if(dat == 0x11){
  14. uart_readF = 1;
  15. }
  16. break;
  17. case 1:
  18. if(dat == 0x22){
  19. uart_readF = 2;
  20. }
  21. break;
  22. case 2:
  23. uart_len = dat << 8;
  24. uart_readF = 3;
  25. break;
  26. case 3:
  27. uart_len += dat;
  28. if(uart_len > Fifo_Empty_Size(ffs)){
  29. uart_readF = 0; //fifo不足以写入本次数据帧,抛弃该数据帧
  30. }else{
  31. Fifo_Push(ffs,uart_len>>8);
  32. Fifo_Push(ffs,(uint8_t)uart_len);//将本次数据帧长度写入fifo
  33. uart_readF = 4;
  34. uart_cnt = 0;
  35. }
  36. break;
  37. case 4:
  38. Fifo_Push(ffs,dat); //将数据写入fifo
  39. if(++uart_cnt == uart_len){
  40. uart_readF = 0;
  41. }
  42. break;
  43. }
  44. break;
  45. case APP_UART_COMMUNICATION_ERROR:
  46. APP_ERROR_HANDLER(p_event->data.error_communication);
  47. break;
  48. case APP_UART_FIFO_ERROR:
  49. APP_ERROR_HANDLER(p_event->data.error_code);
  50. break;
  51. default:
  52. break;
  53. }
  54. }

在定时器每隔10ms(这个时间根据实际情况修改,测试10ms传输数据没有问题)去读取fifo里面的数据,通过蓝牙发送出去。发送数据时,一帧数据大于20个字节(蓝牙一包最多可以发送20个字节的用户数据),每一包都要发足20个字节,最后一包可以不用发足20字节。这是为了防止,写上位机软件的人员老是认为每一包数据都是有20个字节的,没有严格按照通信协议解析数据,造成通信存在问题(经常遇到这样的人,对接起来真累)。

  1. uint8_t CMDDat[250] = {0};
  2. uint16_t CMDLen = 0;
  3. uint16_t CMDOff = 0;
  4. static void TIME_update(void)
  5. {
  6. uint8_t dat = 0;
  7. uint16_t len = 0;
  8. if(CMDF==0){
  9. if(Fifo_GetLen(ffs) > 1){ //协议中,一帧数据的长度为两个字节
  10. Fifo_Pop(ffs,&dat);
  11. CMDLen = dat << 8;
  12. Fifo_Pop(ffs,&dat);
  13. CMDLen += dat; //获取一帧数据的长度
  14. CMDF = 1;
  15. }
  16. }
  17. if(CMDF==1){
  18. if(Fifo_GetLen(ffs) >= CMDLen){
  19. Fifo_Pop_More(ffs,CMDDat,CMDLen); //获取一帧数据
  20. CMDOff = 0;
  21. CMDF = 2;
  22. }
  23. }
  24. if(CMDF==2){
  25. len = 20 < CMDLen ? 20 : CMDLen; //长度多余20个字节,每次发送20个字节
  26. // uart_send(CMDDat+CMDOff,len);
  27. ble_nus_string_send(&m_nus, CMDDat+CMDOff, len);
  28. CMDLen -= len;
  29. CMDOff += len;
  30. if(CMDLen == 0){
  31. CMDF = 0;
  32. }
  33. }
  34. }

 

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号