基于国民技术低功耗蓝牙芯片N32WB03X芯片的温度计开发

最近项目使用了国民技术的N32WB03X芯片,做了一个温度计。代码是基于国民技术的heart rate例程进行改写的,官方SDK给出了底层代码,这里直接贴上服务端应用层的代码。

头文件:app_htps.h代码


#ifndef APP_HTPS_H_
#define APP_HTPS_H_

/* Includes ------------------------------------------------------------------*/

#include "rwip_config.h"     // SW Configuration

#if (BLE_APP_HTPT)

#include <stdint.h>
#include <htp_common.h>

/* Define ------------------------------------------------------------*/

#define APP_HTPT_FEATURES       (0x04)      //

#define HEALTH_THERMOMETER_SEND_DELAY   1000        

enum htpt_cfg
{
    HTPT_CFG_NTF_EN = 1,				// 启用温度测量通知(Notification)的配置标志
};

//// 温度单位定义
//typedef enum {
//    TEMP_UNIT_CELSIUS    = 0,    // 摄氏度
//    TEMP_UNIT_FAHRENHEIT = 1     // 华氏度
//} temp_unit_t;

/// health thermometer Application Module Environment Structure
#define MAX_SENSOR_NUM  8   // 最大支持8个传感器,按需调整

struct app_htpt_env_tag {
    uint8_t conidx;
    float htpt_values[MAX_SENSOR_NUM]; // 存储多个传感器的温度
    uint8_t sensor_count;              // 当前检测到的传感器数量
};


/// Health Thermometer Application environment
extern struct app_htpt_env_tag app_htpt_env;

//定时器 ID heart_rate_timer_id。用于周期性发送心率数据的定时器。
extern uint16_t health_thermometer_timer_id;

/* Public variables ---------------------------------------------------------*/

/// 消息处理列表,注册心率服务相关的消息处理函数,
///用于响应 BLE 协议栈的事件(如连接、断连、写入请求等)。
extern const struct app_subtask_handlers app_htpt_handlers;

/* Public function prototypes -----------------------------------------------*/

/**
 * @brief Initialize health thermometer Service Application
 **/
void app_htpt_init(void);

void app_htpt_send(float temp, uint8_t sensor_idx);


/**
 * @brief Add a health thermometer Service in the DB
 **/
void app_htpt_add_htpt(void);

/**
 * @brief Enable the health thermometer profile
 **/
void app_htpt_enable_prf(uint8_t conidx, uint8_t cfg);

/**
 * @brief Send health thermometer value
 */
//void app_htpt_send(float temp);

/**
 * @brief Send health thermometer value periodically
 */
void app_htpt_timeout_handler(void);


#endif //BLE_APP_HTPS

/// @} APP

#endif //APP_HTPS_H_

说明:

  1. APP_HTPT_FEATURES:需要根据自身需求来决定,参考蓝牙联盟相关定义。
  2. MAX_SENSOR_NUM:本人使用多个温度传感器,兼容单一和多个传感器使用情况。

源代码:app_htps.c

#include "rwip_config.h"     // SW configuration

#if (BLE_APP_HTPT)
/* Includes ------------------------------------------------------------------*/
#include "ns_ble.h"                     // Application Manager Definitions
#include "app_htps.h"                // Device Information Service Application Definitions
#include "htpt_task.h"               // Device Information Profile Functions
#include "prf_types.h"               // Profile Common Types Definitions
#include "ke_task.h"                 // Kernel
#include "gapm_task.h"               // GAP Manager Task API
#include "ns_ble_task.h"
#include <string.h>
#include "co_utils.h"
#include "htpt.h"
#include "stdio.h"
#include "ns_delay.h"
#include "ns_timer.h"
#include "T117_MTS4_OW.h"
#include "owmy.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/// health thermometer Application environment

/// 温度计应用环境变量
struct app_htpt_env_tag app_htpt_env;

/// 温度发送定时器ID
uint16_t health_thermometer_timer_id;


/**
 * @brief 初始化温度计应用环境
 */
void app_htpt_init(void)
{
		app_htpt_env.sensor_count = OW_SearchROM(ID_Buff);
    // 注册HTPT任务到应用任务
    struct prf_task_t prf;
    prf.prf_task_id = TASK_ID_HTPT;
    prf.prf_task_handler = &app_htpt_handlers;
    ns_ble_prf_task_register(&prf);

    // 注册Profile接口获取函数
    struct prf_get_func_t get_func;
    get_func.task_id = TASK_ID_HTPT;
    get_func.prf_itf_get_func = htpt_prf_itf_get;
    prf_get_itf_func_register(&get_func);

}

/**
 * @brief 添加HTPT服务到GATT数据库
 */
void app_htpt_add_htpt(void)
{
    struct htpt_db_cfg*	db_cfg;
	
	// 创建GAPM消息
    struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(
        GAPM_PROFILE_TASK_ADD_CMD,
        TASK_GAPM, 
        TASK_APP,
        gapm_profile_task_add_cmd, 
        sizeof(struct htpt_db_cfg)
    );
	
    // 配置服务参数
    req->operation    = GAPM_PROFILE_TASK_ADD;
    req->sec_lvl      = PERM(SVC_AUTH, NO_AUTH); // 安全级别
    req->prf_task_id  = TASK_ID_HTPT;
    req->app_task     = TASK_APP;
    req->start_hdl    = 0; // 动态分配句柄

    // 配置数据库特性
    db_cfg = (struct htpt_db_cfg *)req->param;
    db_cfg->features = 0;
//    db_cfg->temp_type = HTP_TYPE_BODY;         // 默认测量位置:腋下
//    db_cfg->meas_intv = 0;                       // 默认间隔5秒
//    db_cfg->valid_range_min = 0;                 // 最小间隔1秒
//    db_cfg->valid_range_max = 0;                // 最大间隔60秒

    // 发送消息
    ke_msg_send(req);

    // 初始化应用环境
    app_htpt_init();
}


/**
 * @brief 启用HTPT服务配置
 * @param conidx 连接索引
 * @param cfg 通知/指示配置
 */
void app_htpt_enable_prf(uint8_t conidx, uint8_t cfg)
{
    app_htpt_env.conidx = conidx;

    struct htpt_enable_req *req = KE_MSG_ALLOC(
																								HTPT_ENABLE_REQ,
																								prf_get_task_from_id(TASK_ID_HTPT),
																								TASK_APP,
																								htpt_enable_req
    );

    req->conidx = conidx;
		
    req->ntf_ind_cfg = cfg;

    ke_msg_send(req);
}

/**
 * @brief 发送温度测量值
 * @param temp 温度值(单位:0.01°C)
 * @param stable 是否为稳定测量
 */
static uint8_t current_sensor_idx = 0;

// 改进后的发送函数
void app_htpt_send_next_sensor(void)
{
    if (current_sensor_idx >= app_htpt_env.sensor_count)
    {
        current_sensor_idx = 0; // 重置索引,等待下个周期
        return;
    }

    float temp = app_htpt_env.htpt_values[current_sensor_idx];

    struct htpt_temp_send_req *req = KE_MSG_ALLOC(
        HTPT_TEMP_SEND_REQ,
        prf_get_task_from_id(TASK_ID_HTPT),
        TASK_APP,
        htpt_temp_send_req
    );

    int32_t mantissa = (int32_t)(temp * 100 + 0.5f);
    int8_t exponent = -2;

    req->temp_meas.temp = ((uint32_t)(mantissa & 0x00FFFFFF)) | (((uint8_t)exponent) << 24);
    req->temp_meas.flags = HTP_FLAG_TYPE_BIT;
    req->temp_meas.type = current_sensor_idx + 1;
    req->stable_meas = TRUE;

    ke_msg_send(req);

    current_sensor_idx++;

    // 设定定时器调用自身,500ms发送下一个传感器的数据
    ns_timer_create(HEALTH_THERMOMETER_SEND_DELAY, app_htpt_send_next_sensor);
}


void app_htpt_temp_timeout_handler(void)
{
    GetTemp(); 
		
		for (uint8_t i = 0; i < app_htpt_env.sensor_count; i++)
    {
        app_htpt_env.htpt_values[i] = g_TempValue[i];
    }

    // 启动发送第一个传感器数据,其他的延迟依次发送
    current_sensor_idx = 0;  // 复位发送索引,开始新一轮发送
		
		ns_timer_cancel(health_thermometer_timer_id);
		
    app_htpt_send_next_sensor();  // 触发首次发送
    
    health_thermometer_timer_id = ns_timer_create(HEALTH_THERMOMETER_SEND_DELAY * app_htpt_env.sensor_count, app_htpt_temp_timeout_handler);
}


/**
 * @brief 处理配置变更事件
 */
static int htpt_cfg_indntf_ind_handler(ke_msg_id_t const msgid,
                                     struct htpt_cfg_indntf_ind const *param,
                                     ke_task_id_t const dest_id,
                                     ke_task_id_t const src_id)
{
    if((param->ntf_ind_cfg & HTPT_CFG_NTF_EN) != 0) 
		{
        app_htpt_enable_prf(0, PRF_CLI_START_NTF);
				health_thermometer_timer_id = ns_timer_create(HEALTH_THERMOMETER_SEND_DELAY,app_htpt_temp_timeout_handler);				
		}
		else
    {
        app_htpt_enable_prf(0, PRF_CLI_STOP_NTFIND);
        ns_timer_cancel(health_thermometer_timer_id);
		}
    return KE_MSG_CONSUMED;
}

/* Public variables ---------------------------------------------------------*/
/// 消息处理列表
const struct ke_msg_handler app_htpt_msg_handler_list[] = {
    {HTPT_CFG_INDNTF_IND, (ke_msg_func_t)htpt_cfg_indntf_ind_handler},
};

/// 应用子任务处理器
const struct app_subtask_handlers app_htpt_handlers = APP_HANDLERS(app_htpt);


#endif //

/// @} APP

说明:

  1. #include "T117_MTS4_OW.h"和#include "owmy.h"是本人所使用的传感器相关代码。
  2. 在app_htpt_init函数种调用了app_htpt_env.sensor_count = OW_SearchROM(ID_Buff);为了获取传感器数量,请删除。
  3. app_htpt_send_next_sensor和app_htpt_temp_timeout_handler函数中改成自己的温度数据进行发送。

其他说明:

记得在app_ble.c中的app_ble_prf_init函数注册htps服务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值