【经验】无线蓝牙SoC EFR32BG22串口接收长数据出错问题的分析与解决
SILICON LABS无线蓝牙SoC EFR32BG22串口是一个常用的驱动,可以输出调试信息,也可以进行数据传输。EFR32BG22的串口数据传输功能,在平台上可以参考:https://www.sekorm.com/news/54167305.html。本文主要针对EFR32BG22串口接收长数据出错问题进行分析并解决。
通过串口,调用app_log进行信息打印,如果需要对数据进行接收,那么需要启动串口的数据接收功能,在工程的autogen目录下,可以找到相关的发送和接收入口,如下:
如果采用系统自动生成的串口接收入口,在进行较长的数据包发送的时候,经常会出现问题,实际测试200个字节,情况如下:
在第11个字节的时候就已经丢失数据了,出现这个问题的根本原因是串口在进行数据接收的时候,会被BLE协议栈打断,所以需要添加LDMA功能,来实现串口数据的接收。
步骤如下:
1.关掉工程里面的低功耗管理功能:
2. 如果安装了串口插件,需要屏蔽接收函数入口:
3.初始化UART和LDMA,接收部分开启LDMA通道
// Receive data buffer
uint8_t buffer[255];
// Current position ins buffer
uint32_t inpos = 0;
uint32_t outpos = 0;
// True while receiving data (waiting for CR or BUFLEN characters)
bool receive = true;
// LDMA channel for receive and transmit servicing
#define RX_LDMA_CHANNEL 0
#define TX_LDMA_CHANNEL 1
// LDMA descriptor and transfer configuration structures for USART TX channel
LDMA_Descriptor_t ldmaRXDescriptor;
LDMA_TransferCfg_t ldmaRXConfig;
bool rx_done;
/**************************************************************************//**
* @brief
* LDMA initialization
*****************************************************************************/
void initLdma(void)
{
// Enable clock (not needed on xG21)
CMU_ClockEnable(cmuClock_LDMA, true);
// First, initialize the LDMA unit itself
LDMA_Init_t ldmaInit = LDMA_INIT_DEFAULT;
LDMA_Init(&ldmaInit);
ldmaRXDescriptor = (LDMA_Descriptor_t)LDMA_DESCRIPTOR_SINGLE_P2M_BYTE(&(USART1->RXDATA), buffer, 210);
// Transfer a byte on receive data valid
ldmaRXConfig = (LDMA_TransferCfg_t)LDMA_TRANSFER_CFG_PERIPHERAL(ldmaPeripheralSignal_USART1_RXDATAV);
LDMA_StartTransfer(RX_LDMA_CHANNEL, &ldmaRXConfig, &ldmaRXDescriptor);
}
/**************************************************************************//**
* @brief LDMA IRQHandler
*****************************************************************************/
void LDMA_IRQHandler()
{
uint32_t flags = LDMA_IntGet();
/*
* Clear the receive channel's done flag if set and change receive
* state to done.
*/
if (flags & (1 << RX_LDMA_CHANNEL))
{
LDMA_IntClear(1 << RX_LDMA_CHANNEL);
rx_done = true;
LDMA_StartTransfer(RX_LDMA_CHANNEL, &ldmaRXConfig, &ldmaRXDescriptor);
sl_bt_external_signal(1); //这里添加蓝牙外部中断时事件
}
// Stop in case there was an error
if (flags & LDMA_IF_ERROR)
__BKPT(0);
}
/**************************************************************************//**
* @brief
* GPIO initialization
*****************************************************************************/
void initGpio(void)
{
// Configure PA5 as an output (TX)
GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 0);
// Configure PA6 as an input (RX)
GPIO_PinModeSet(gpioPortA, 6, gpioModeInput, 0);
}
/**************************************************************************//**
* @brief
* CMU initialization
*****************************************************************************/
void initCmu(void)
{
// Enable clock to GPIO and USART1
CMU_ClockEnable(cmuClock_GPIO, true);
CMU_ClockEnable(cmuClock_USART1, true);
}
/**************************************************************************//**
* @brief
* USART1 initialization
*****************************************************************************/
void initUsart1(void)
{
// Default asynchronous initializer (115.2 Kbps, 8N1, no flow control)
USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
// Route USART1 TX and RX to PA5 and PA6 pins, respectively
GPIO->USARTROUTE[1].TXROUTE = (gpioPortA << _GPIO_USART_TXROUTE_PORT_SHIFT)
| (5 << _GPIO_USART_TXROUTE_PIN_SHIFT);
GPIO->USARTROUTE[1].RXROUTE = (gpioPortA << _GPIO_USART_RXROUTE_PORT_SHIFT)
| (6 << _GPIO_USART_RXROUTE_PIN_SHIFT);
// Enable RX and TX signals now that they have been routed
GPIO->USARTROUTE[1].ROUTEEN = GPIO_USART_ROUTEEN_RXPEN | GPIO_USART_ROUTEEN_TXPEN;
// Configure and enable USART1
USART_InitAsync(USART1, &init);
NVIC_ClearPendingIRQ(USART1_TX_IRQn);
NVIC_EnableIRQ(USART1_TX_IRQn);
}
4. 在app.c里面添加蓝牙事件
case sl_bt_evt_system_external_signal_id:
if (evt->data.evt_system_external_signal.extsignals == 1) // 1 = UART RX data finish
{
// app_UartTxTest();
for (i = 0; i < 200; i++) {
USART_Tx(USART1, buffer[i]);
}
// USART_Tx(USART1, inpos);
memset(buffer,0,sizeof(buffer));
inpos = 0;
}
break;
实际测试如下:
这个操作也是蓝牙数据透传的基础,在这个工程上增加
sl_bt_gatt_server_send_notification(connHandle,gattdb_Notify_chara,
evt->data.evt_gatt_server_attribute_value.value.len,
(const uint8_t * )&evt->data.evt_gatt_server_attribute_value.value.data[0]);
就可以进行数据透传了。
- |
- +1 赞 0
- 收藏
- 评论 1
本文由蜡笔小芯提供,版权归世强硬创平台所有,非经授权,任何媒体、网站或个人不得转载,授权转载时须注明“来源:世强硬创平台”。
相关推荐
【经验】芯科科技EFR32BG22系列蓝牙SOC修改自定义广播包的思路与具体实例
在蓝牙的实际应用中,往往需要自定义的蓝牙广播包来适应不同的应用环境,本文主要介绍基于SILICON LABS的EFR32BG22蓝牙SOC实现自定义广播数据包的方法。
【经验】SiliconLabs EFR32BG22芯片如何实现BLE连接并进行数据收发
不少首次接触BLE的开发者不太清楚如何实现BLE数据的交互,本文以Silicon Labs的EFR32BG22芯片平台为例,指导如何通过建立BLE连接并进行数据交互。硬件:SLTB010A开发板软件。
【经验】STUDIO V5中蓝牙SoC EFR32BG22添加串口LOG打印的方法
在调试Silicon Labs蓝牙SoC EFR32BG22时,一般需要添加LOG打印信息,通过串口的方式来判断代码运行是否正常。由于使用RTT功能在打印信息时无法再次在线调试和代码下载,所以直接采用串口的方式更加便捷。
BLE Connection Roles Central/Master vs. Peripheral/Slave
Title: BLE Connection Roles: Central / Master vs. Peripheral / SlaveKeywords: BLE connection, Central vs Peripheral, bluetooth master module, bluetooth master slave,bluetooth master vs slaveDescription: Learn the nuances between Central and Peripheral roles in BLE devices to optimize energy efficiency and functionality for your projects. Unlock how to select the most suitable BLE modules based on your specific needs. In the world of Bluetooth Low Energy (BLE), BLE devices are designed to play specific roles that dictate how they interact within the BLE ecosystem.
【应用】EFR32BG22蓝牙SoC用做CGM连续血糖仪主控,单芯片集成MCU和蓝牙5.2
CGM连续血糖仪为了用户体验更好,要做到小而轻,续航时间长,可以通过手机蓝牙连接获取血糖测量数据。Silicon Labs的蓝牙SoC EFR32BG22在单芯片中集成了MCU和蓝牙5.2,可以作为CGM的主控芯片并实现蓝牙数据收发,有丰富的外设。
silicon labs EFR32BG22蓝牙固件OTA升级流程解析
介绍EFR32BG22蓝牙程序在非备份方式OTA时的详细操作流程,应用代码会跳转到AppLoader 中运行蓝牙功能,实现新固件的传输和写入。
【经验】Simplicity Studio v5如何创建和配置EFR32BG22 LED Server
本文以Silicon Labs的蓝牙SoC EFR32BG22 Thunderboard模块为例,介绍Simplicity Studio v5软件如何创建和配置EFR32BG22 LED Server,并使用手机APP控制EFR32BG22蓝牙模块上LED的方法。
【经验】Silicon Labs蓝牙Soc芯片EFR32BG22的蓝牙广播功率设置及注意事项
用户在使用Silicon Labs的蓝牙Soc芯片EFR32BG22实现蓝牙广播功能时,在不同的应用场景中要设置广播的发射功率,有的是为了降低产品的功耗,有的是为了增加或缩短通信的距离。那要如何设置广播时的功耗以及在设置时有哪些需要注意的事项?
【经验】低功耗蓝牙SoC EFR32BG22系列如何从软硬件两方面实现低功耗设计?
EFR32BG22是Silicon Labs公司主打的低功耗蓝牙SoC系列,对于新手工程师来说,如何控制好功耗,以延长电池类产品的寿命,有很多需要关注的地方。本文将从硬件和代码底层两方面分析SoC低功耗实现的关键点。
【经验】EFR32BG22系列蓝牙SOC电池电压与VDD供电电压检测ADC的方法
EFR32BG22作为低功耗蓝牙SOC方案,经常应用于电池供电的方案中,一般采用内部的ADC作为采集通道,内部的输入源作为输入接口,来测试VDD供电电压。本文将讲解电池电压与VDD供电电压检测ADC的方法。
【经验】无线SOC EFR32BG22带安全功能的OTA怎么实现?
本文介绍实现SECURE OTA DFU的操作步骤,实现蓝牙SoC OTA的安全功能
【经验】无线蓝牙SoC EFR32BG22用户自定义数据存取接口NVM使用指导
在使用EFR32BG22开发应用时,大部分应用需要保存一些参数,很多开发者不清楚BG22对数据进行存取的接口是哪个,本文将介绍Silicon Labs无线蓝牙SoC EFR32BG22上对数据进行存取的接口——NVM的使用。
【经验】芯科科技EFR32BG22系列蓝牙SOC低功耗优化的相关配置
本文主要介绍Silicon Labs(芯科科技)EFR32BG22系列蓝牙SOC目前所有的低功耗优化的相关配置,实现目标: VDD=3V,VSCALE0=0.9V,温度25℃,EM2模式下深度休眠为1.4μA。
【经验】如何解决Silicon Labs EFR32B22在开启一次ADC转换后,功耗变高的问题?
在使用芯科科技EFR32BG22蓝牙SoC开发低功耗应用时,可能会使用到ADC这个外设,但在ADC转换后,会出现芯片在休眠时功耗比较高的情况。本文将介绍如何解决EFR32B22在开启一次ADC转换后,功耗变高的问题?
电子商城
品牌:SILICON LABS
品类:Wireless Gecko SoC
价格:¥8.1764
现货: 103,878
品牌:SILICON LABS
品类:Mighty Gecko Multi-Protocol Wireless SoC
价格:¥27.0929
现货: 90,767
现货市场
品牌:SILICON LABS
品类:Switch Hall Effect Magnetic Position Sensor
价格:¥2.2924
现货:126,000
服务
可根据用户的wifi模块,使用无线连接测试仪MT8862A,测试IEEE802.11a/b/g/n/ac (2.4Ghz和5Ghz)设备的TX、RX射频特征,输出测试报告。支持到场/视频直播测试,资深专家全程指导。
实验室地址: 深圳 提交需求>
支持Bluetooth SIG最新的测试规范,支持2.0(EDR), 2.1(EDR), 3.0(HS), 4.0(LE)规范, 并且能完整覆盖BR/EDR/HS/BLE的所有射频测试项目。测试标准:RF.TS/4.03 ;RF-PHYTS/40.3。
实验室地址: 深圳 提交需求>
登录 | 立即注册
提交评论