rt-thread nano stm32f103cbt6 蓝牙模块的通信(有整个工程的代码仓库)

本文档记录了一位开发者使用STM32实现蓝牙数据存储与删减的项目,包括蓝牙初始化、数据解析及结构体设计。开发者通过Gitee分享了代码仓库,并详细介绍了代码编写思路,包括数据结构设计、蓝牙模块初始化和数据处理逻辑。项目虽因疫情无法实际测试硬件,但已实现基本功能,可直接下载到开发板运行。
摘要由CSDN通过智能技术生成

本项目代码仓库的网页:董昊旻/rt_nano_bluetoothhttps://gitee.com/donghaomin/rt_nano_bluetooth

目录

一,任务来源

二,任务描述

三,代码编写思路

(一)数据存储,删减

(二)蓝牙初始化,蓝牙发送过来的数据进行解析

四,总结


一,任务来源

清明节在家呆着无聊就看了一个猪八戒发布的一个简单的任务,但是不会操作那些程序外包的东西,就把这个任务作为一个练手的小项目,打发一下时间,代码的思考,撰写和调试应该花了12个小时,昨天晚上5点到半夜1点(代码写到兴奋的睡不着觉,在地上站着玩了一个半小时手机才睡着),第二天的早上8点到12点。很大一部分时间花在了调试stm32的引脚,中断和串口上了,大学毕业之后就没用过stm32了,也没用过stm32clubMx,所以学习这个工具花了一点时间。

蓝牙模块我手里没有,因为长春疫情的原因我也没办法买,啥时候疫情结束我也不知道,就对着大夏龙雀的蓝牙文档盲写了。

硬件如下

二,任务描述

下边这个图就是他发布的任务,这个东西仁者见仁智者见智,我感觉难度还行,就是比较费时间。

三,代码编写思路

这个要是我大学的时候写,也就是三个小时之内,现在至少需要20个小时,哈哈。不是能力下降了,就是思考的问题不一样了。大学的时候一切以能用主义,写上去能用就OK,现在开始思考代码的可读性,可维护性,稳定性等等...

言归正传,既然思考的问题不一样,所以我们就先分割一下这个项目的功能。

1.带id的数据存储,还可以删除数据(我的理解是不用存储到norflash上,暂存到sram即可)

2.一个下降沿中断的GPIO

3.一路串口(我用的是UART2)

这个是硬件上的基础需求,然后我们聊一下软件的代码逻辑:

(一)数据存储,删减

我没有采取链表的结构来存储数据,第一是没必要这么复杂,它只要几十个数据用不了那么多,写着也麻烦。我就用一个机构体存储了温度数据和连接状态。DATA_SUM是40,这么一写的话就能存储40条数据了,还能存储蓝牙硬件初始化的完成状况和蓝牙连接的状态。

数据增加,你一按动按键的时候就将中断中的flag置1,在主循环的while(1)将数据加进去一个结构体中,将结构体中的useDataCount加一,超出40就报错,让他清空。

删除的话就更简单了,直接让这个大结构体memset为0,就OK了。

typedef enum UsrState {
    DATA_UN_USED_Sta = 0x00,               // 温度值不正确(不存在)
    DATA_USED_Sta    = 0x01,               // 温度值正确(存在)
    DATA_SUM_Sta
}usrsta;

typedef struct D_USR_DATA{
    unsigned char id;                      // 计数标签
    float value;                           // 温度值
    usrsta state;                          // 状态值,温度值是否正确
}d_data;

typedef struct Dong_BLUE_TEMP{
    unsigned int  blueTooth_state;         // 蓝牙启动的状态位
    unsigned int  blueTooth_connect_state; // 蓝牙连接的状态位,是否断了连接
    unsigned char usedDataCount;           // 当前存储了多少个温度数据
    d_data data[DATA_SUM];                 // 温度数据
}d_bule_temp;

(二)蓝牙初始化,蓝牙发送过来的数据进行解析

蓝牙模块初始化:蓝牙模块是通过"AT"指令进行配置的,为了避免有人用没配置过的蓝牙模块进行连接,所以我们就需要每次初始化的时候初始化,避免出现蓝牙模块配置的问题出现的BUG。

蓝牙数据解析:蓝牙发过来的数据是串口发送与接收的,我设置串口的缓冲BUFFER为10Byte,对这10Byte进行解析我们就能知道要做的事情。我用一个结构体来存储这10个Byte。代码里有注释,我就不详细描述了。

有了这个结构体,我们就可以做一个类似于"诊断"的接口,因此代码运行的逻辑就是,接收到串口的数据,在主函数中判断结构体的第一个数据really是不是0x01,是0x01的话就判断function id,在进入到不同得一级分支,在根据sub function id进入到二级分支,再根据datalenght来判断data的6Byte用了几个。具体这个6个Byte表达了那些内容就由,二级分支自己决定了。

/**
 * 一级主功能ID
 * */
typedef enum FUNCTION_ID {
    BLUE_TOOTH_IMG   = 0x00,               // 蓝牙信息获取
    TEMP_DATA_OPT    = 0x01,               // 温度信息获取,删除
    DIAG_CODE_OPT    = 0x02,               // 诊断ID
    FUNCTION_ID_SUM                        // ID总数
}d_function_id;

typedef struct Dong_BLUETOOTH_RECIVE_CMD{
    unsigned char  really;                 // 判断是否当前有数据(你也可以理解为器件ID),有数据的话就是0x01,没有就是0x00,也就是说蓝牙发送数据的时候第一位必须是0x01
    d_function_id  function_id;            // 蓝牙接收数据的主功能id
    unsigned char  sub_function_id;    // 蓝牙接收数据的二级功能id
    unsigned char  datalenght;             // 蓝牙发送过来的数据长度
    unsigned char  data[6];                // 蓝牙发送过来的数据6个byte
}d_bule_revcmd;

蓝牙模块AT指令的判断我写了一个代码觉得很有趣下边贴出来,加了一个超时的处理。

// 蓝牙状态运行检测
errornum bluetooth_AT_OK(void) {
    errornum ret = DIAG_OK;
    unsigned int overtime = 0;
    while(d_revbuffer.really == 0x00) {
        HAL_UART_Transmit_IT(&huart2,(uint8_t *)AT_OK_ACK,strlen(AT_OK_ACK));
        rt_thread_mdelay(500);
        overtime++;
        if(overtime > OVERTIME_TIMES) {
            ret = DIAG_OVERTIM_ERR;
            rt_kprintf("AT_OK time out\n");
            return ret;
        }
    }
    memcpy(locat_data,&d_revbuffer,sizeof(locat_data));
    int dong = memcmp(locat_data,AT_OK_ANS,strlen(AT_OK_ANS));
    if(dong!=0){
        rt_kprintf("AT False\n");
        ret = DIAG_BLUE_ERR;
    }
    else {
        rt_kprintf("AT OK\n");
        ret = DIAG_OK;
    }
    return ret;
}

运行的LOG,用串口模拟蓝牙,主机主动发AT,从机在10次请求内发OK,主机就认为蓝牙没问题。

我的代码结构如下图:

diag负责分析和处理蓝牙接收的串口数据。

bluetooth负责蓝牙模块的初始化,检测蓝牙信号强度,连接状态等的函数(连接状态函数我会放到一个一秒周期的task中,连接上了blueTooth_connect_state就置0x01,掉了就0x00),蓝牙模块正不正常的话我就用AT指令测试,能回OK就将blueTooth_connect_state置0x02,不能就0x03,类似于这个意思推之后的逻辑。

hardware就是硬件初始化相关的函数,我初始化了UART2,PC13(LED),PA11(KEY)。

urs_data就是存储温度和其他基础结构体的头文件,初始化函数。

四,总结

代码目前还没写完,目前处于一个初版本demo的状况,但是能用!你可以直接把代码下载下来,用RT Thread Studio编译下载到你的开发板,你也不用担心,开发板不兼容,因为我用的是核心板。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式吴彦祖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值