加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

蓝牙开发的一点心得

04/25 09:11
362
阅读需 8 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

最近在使用芯海的蓝牙芯片开发一个小项目,功能其实很简单,类似于防丢器,只不过这个项目中的主机也是蓝牙芯片,而不是手机。这就不得不去学习更多的协议栈相关的东西。然而,最让人头疼的并不是蓝牙协议本身的学习,毕竟这是SIG发布的通行的一套协议栈,无论谁家的蓝牙都应遵守。最让人头疼的是,每一家做蓝牙芯片的厂家,都有一套自己实现SIG BLE协议栈的源代码,这时候可是真的看出条条大路通罗马了。

硬件来比喻的话,就相当于SIG 出了一个原理图,各家厂家按照原理图画了各自的线路板,学蓝牙开发就像是看那个乱七八糟PCB gerber图纸,各家都不一样。

我最早接触蓝牙用的是nordic,天天缠着FAE折腾了一个月才熟悉了它的那套代码,后来还直接把它的DFU重构了一下,适应了自己公司的OTA协议。后来开发泰凌微,又是一套新东西,不但整套源代码框架不同,就连IDE也是换了,用起来就像从现代文明一下进入刀耕火种一样。以至于从那以后,但凡有人给我推荐蓝牙,我都先问问能不能在MDK上开发,工具还是用顺手的好,已经不是调戏各种工具的年纪了。

还有一个点,就是这些蓝牙的协议栈都需要跑在一个小型的操作系统上,严格意义上来说,这只是一个稍微复杂的调度系统,这又是一个非标的东西,所以各家系统层的接口又不一样,比如磐启微的蓝牙是基于一个开源的Zephyr系统,我刚一拿到厂家的SDK都不知道从哪入手,第一个函数去哪里找都费劲,所以说为啥MDK用的人多,即便是企业用盗版的都不愿用那些开源的五花八门的东西,简单意味着综合成本低。

昂瑞微的蓝牙和nordic有点类似,杰里的开发起来工具就又得费点劲儿了,现在我弄得这个芯海的蓝牙,不确定是借鉴的哪一家的协议栈,log信息虽然很多,也是绕了一个星期才将将绕明白从开机启动到广播,再从发起Connect到向从机发数据,真的是绕来绕去,一会处理osal的message,一会有处理某一个应用的message,都是从底层一个消息队里取出来的,不同的地方都有相同的事件,再在回调函数里面处理一遍,真的晕。所以,蓝牙这东西,选择两三个平台就足够折腾了。去年我在推广方案的时候,销售的同事三天能给整俩蓝牙进来,根本学不过来,关键在于学习这些不重样的个性协议栈没啥意义,我本身更想关注的是应用怎么写。

这么看来,当年GD把寄存器地址设计成和ST一模一样真的是有远见,从推广上来说,这起到了决定性作用。但是蓝牙没办法,这个行业没有一家独大的的情况,即便是Nordic,TI,赛普拉斯,NXP等在市场上也只能算是平分秋色吧。回到应用开发上,协议栈真的是折腾的我眼花缭乱,整得我整个人都不好了,基本没心情好好写应用。这不,RSSI数据又出问题了,本来都在-30dbm左右,中间总是突然窜出一个-90来,这必须得加一个滤波才行。思来想去选择了滑动窗口滤波器,在窗口内把最大最小值去掉。原来写过,根本不想去翻了(我必须自己写一个算法库,可以随手拖到工程就能用的那种),正着急的时候,想起来GPT,现在还是不太习惯身边有这么个大神啊。我便向他请教:

#include <stdio.h>
#include <limits.h>

#define WINDOW_SIZE 10

int window[WINDOW_SIZE];
int num_elements = 0;

void update_window(int new_value) {
    if (num_elements < WINDOW_SIZE) {
        window[num_elements++] = new_value;
    } else {
        // 窗口已满,滑动窗口,丢弃最旧的值
        for (int i = 1; i < WINDOW_SIZE; i++) {
            window[i-1] = window[i];
        }
        window[WINDOW_SIZE-1] = new_value;
    }
}

double compute_filtered_output() {
    if (num_elements == 0) return 0.0; // 没有数据

    int max = INT_MIN;
    int min = INT_MAX;
    int sum = 0;
  
    for (int i = 0; i < num_elements; i++) {
        if (window[i] > max) max = window[i];
        if (window[i] < min) min = window[i];
        sum += window[i];
    }
  
    // 减去最大值和最小值,再计算平均
    sum -= (max + min);
    return (double)sum / (num_elements - 2);
}

int main() {
    // 模拟输入数据
    int data[] = {5, 10, 8, 12, 20, 1, 30, 25, 15, 50, 45, 20, 25, 10, 5};
    int n = sizeof(data) / sizeof(data[0]);

    for (int i = 0; i < n; i++) {
        update_window(data[i]);
        if (num_elements > 2) {
            printf("Filtered output: %.2fn", compute_filtered_output());
        }
    }

    return 0;
}

它还贴心的给了个说明:

真是暖心极了!

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
KSZ8463FMLI 1 Microchip Technology Inc DATACOM, MANCHESTER ENCODER
暂无数据 查看
KSZ8873MLLI 1 Microchip Technology Inc DATACOM, LAN SWITCHING CIRCUIT, PQFP64
$6.1 查看
KSZ8851SNLI 1 Microchip Technology Inc DATACOM, ETHERNET TRANSCEIVER, PQCC32
$5.06 查看

相关推荐

电子产业图谱

多年硬件从业经验,专注分享从研发到供应链,再到精益制造过程中的经验和感悟!