[N32WBxxx] 如何避免频繁的中断影响外部数据采集

[复制链接]
Steppenwolf 发表于 2025-8-18 15:15 | 显示全部楼层 |阅读模式
在使用WB031芯片做开发时,外接了10个温度芯片,通过单总线协议one-wire与MCU进行通信。使用官方SDK进行开发的,但是我发现采集的温度数据有时候会出现为0等错误情况,我目前猜测是任务调度过程中,频繁中断会打断单总线协议的时序,有没有大佬提供一点思路啊?

//main函数

int main(void)
{
    //for hold the SWD before sleep
    delay_n_10us(200*1000);
       
                OW_Init();
                OW_RecallE2();
//                Serial_Init();
                    
    app_ble_init();

    // periph init
//    LedInit(LED1_PORT,LED1_PIN);  // power led
//    LedInit(LED2_PORT,LED2_PIN);  //connection state
//    LedOn(LED1_PORT,LED1_PIN);   

    while (1)
    {
        /*schedule all pending events*/
                               
        rwip_schedule();
                               
        ns_sleep();

    }
}
////////////////////////////


///////app_htps.c部分函数

void app_htpt_temp_timeout_handler(void)
{
    // 1. 采集所有传感器温度
                GetTemp();

    // 2. 发所有传感器数据
    for (uint8_t i = 0; i < app_htpt_env.sensor_count; i++) {
//                                Serial_SendString("\r\n");
//                                Serial_SendString("Sensor");
//                                Serial_SendNumber(i, 1);
//                                Serial_SendString(":");
//                                Serial_SendFloat(g_TempValue);
//                                Serial_SendString("\r\n");
        app_htpt_temp_send(g_TempValue, i);
    }
   
    // 3. 仅当通知启用时重启定时器
//    if (app_htpt_env.ntf_cfg & HTPT_CFG_INTERM_MEAS_NTF) {
        ns_timer_cancel(health_thermometer_timer_id);
        health_thermometer_timer_id = ns_timer_create(
            HEALTH_THERMOMETER_SEND_DELAY,
            app_htpt_temp_timeout_handler
        );
//    }
}



// 依次发送每个通道的数据,间隔500ms
void app_htpt_temp_send(float temp_celsius, uint8_t sensor_id)
{
    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
    );

    // 使用正确的 IEEE 11073 浮点格式
    int32_t mantissa = (int32_t)(temp_celsius * 100); // 转换为 0.01°C 单位
    req->temp_meas.temp = (uint32_t)mantissa & 0x00FFFFFF; // 24位尾数
    req->temp_meas.temp |= (0xFE << 24); // 指数 -2 (0xFE = -2的补码)
   
    // 设置标志位:包含温度类型
    req->temp_meas.flags = HTP_FLAG_TYPE_BIT;
    req->temp_meas.type = sensor_id + 1; // 温度类型 (1-9)
   
    // 关键:设置为非稳定测量(使用中间温度特性)
    req->stable_meas = FALSE;
   
    ke_msg_send(req);
}

//////////////////////////////////////////

qeeuly 发表于 2025-8-18 17:44 | 显示全部楼层
放到定时中断去嘛,当然不是说在定时中断里做delay
 楼主| Steppenwolf 发表于 2025-8-18 18:16 | 显示全部楼层
qeeuly 发表于 2025-8-18 17:44
放到定时中断去嘛,当然不是说在定时中断里做delay

但是我gettemp函数就是调用软件模拟的one-wire通信协议,内部有延时
 楼主| Steppenwolf 发表于 2025-8-18 18:28 | 显示全部楼层
Steppenwolf 发表于 2025-8-18 18:16
但是我gettemp函数就是调用软件模拟的one-wire通信协议,内部有延时

目前连接了10个传感器,数据读取的整个过程大概是400-450ms,后期如果继续加传感器,这个持续时间会更长
qeeuly 发表于 2025-8-19 09:20 | 显示全部楼层
Steppenwolf 发表于 2025-8-18 18:16
但是我gettemp函数就是调用软件模拟的one-wire通信协议,内部有延时

就是要把函数改到定时中断里啊,函数的内部延时也改成由定时中断控制。
当然啦,如果可以忍受错误率的话,不改函数也可以,用单线通信的CRC校验字节来丢弃错误的数据。
 楼主| Steppenwolf 发表于 2025-8-20 10:03 | 显示全部楼层
qeeuly 发表于 2025-8-19 09:20
就是要把函数改到定时中断里啊,函数的内部延时也改成由定时中断控制。
当然啦,如果可以忍受错误率的话 ...

感谢,我试试
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

5

帖子

0

粉丝

1

主题

5

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部