打印
[AIROC™ 蓝牙]

【英飞凌CYW20829测评】6.通过ADC+NTC电阻测量温度

[复制链接]
116|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tc, dc, NTC, ADC, AD
ADC是模拟到数字转换器(Analog-to-Digital Converter)缩写,主要用于将连续传输的模拟信号转换为数字信号,便于数字系统(如中央处理器CPU、微控制器MCU等)对传输信息进行快速处理和分析。模拟信号是指用连续变化的物理量所表达的信息,如温度、湿度、压力、电压、电流等。ADC模块所采集的模拟信号是连续变化的电压信号,其数值在一定范围内连续变化。
CYW20829内部集成12位的ADC,开发板上能用作模拟量输入的是这几个

先用个可调电阻器实现简单的分压

电阻两端连接VCC和GND,中间连接ADC输入引脚,用ADC测量一下分压后的电压值,初始化ADC,使用单次测量模式
cyhal_adc_t adc_obj;
cyhal_adc_channel_t adc_ch_obj;
void APP_AdcInit(void)
{
    cyhal_adc_config_t adc_cfg = {
            .continuous_scanning = false,
            .resolution = 12,
            .average_count = 1,
            .ext_vref_mv = 0,
            .vneg = CYHAL_ADC_VNEG_VSSA,
            .vref = CYHAL_ADC_REF_VDDA,
            .ext_vref = NC,
            .bypass_pin = NC,
    };
    cyhal_adc_channel_config_t channel_cfg = {
            .enable_averaging = false,
            .enabled = true,
            .min_acquisition_ns = 1000,
    };
    cyhal_adc_init(&adc_obj, CYBSP_A1, NULL);
    cyhal_adc_channel_init_diff(&adc_ch_obj, &adc_obj, CYBSP_A1, CYHAL_ADC_VNEG, &channel_cfg);
    cyhal_adc_configure(&adc_obj, &adc_cfg);
}

在主循环中每隔1秒读取一次电压值,cyhal_adc_read_uv这个方法获取到的是转换好的电压值单位是微伏,除以1000后以mV打印
int main(void)
{
    cy_rslt_t result;
    int32_t adc_mv;
    result = cybsp_init();
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }
    APP_LEDInit();
    app_uart_init();
    APP_AdcInit();
    printf("APP Start\n");
    /* Enable global interrupts */
    __enable_irq();

    for (;;)
    {
        Cy_SysLib_Delay(1000);
        adc_mv = cyhal_adc_read_uv(&adc_ch_obj)/1000;
        printf("printf adc volt %dmv\n",adc_mv);
        cyhal_gpio_toggle(CYBSP_USER_LED1);
    }
}

输出结果

用万用表实测电压,ADC测量结果还是比较准的


NTC热敏电阻是负温度系数热敏电阻器,它是以锰、钴、镍和铜等金属氧化物为主要材料,采用陶瓷工艺制造而成的,随着温度升高它的阻值会降低,利用这一特性就可以通过ADC采集到的电压推算当前的温度,接下来就用NTC热敏电阻实现温度测量,电路设计如图

使用10K的上拉电阻,电压反推电阻的公式为R(ntc)=R(10k)*V(ADC)/(VCC-V(ADC))
NTC的阻值与温度对应关系可用过查表的方式获得,数据太多,这里只放一部分,需要注意的是不同的探头会有不同的对照表,使用时需要注意


每100ms读一次ADC值,使用平均值进行简单滤波,每秒输出一次温度值通过串口进行打印,代码如下
uint16_t adc_values[ADC_VALUE_NUM];
uint8_t adc_value_index = 0;
#define NTC_TEMP_MIN 0
#define NTC_TEMP_MAX 45
const float ntc_res[] = {
    32.040, 30.490, 29.022, 27.633, 26,317, 25.071, 23.889, 22.769, 27.707, 20.700,
    19.788, 18.838, 17.977, 17.160, 16.383, 15.646, 14.945, 14.280, 13.647, 13.045,
    12.472, 11.928, 11.409, 10.916, 10.447, 10.000,  9.574,  9.168,  8.781,  8.413,
     8.062,  7.727,  7.407,  7.103,  6.812,  6.534,  6.270,  6.017,  5.775,  5.545,
     5.324,  5.114,  4.913,  4.720,  4.536,  4.360};
float NTC_GetTempFromRes(float res)
{
    uint8_t i = 1;
    if(res < ntc_res[NTC_TEMP_MAX - NTC_TEMP_MIN])
        return NTC_TEMP_MAX;
    if(res > ntc_res[0])
        return NTC_TEMP_MIN;
    while(i < NTC_TEMP_MAX - NTC_TEMP_MIN + 1)
    {
        if(res > ntc_res[i])
            break;
        i += 1;
    }
    return NTC_TEMP_MIN+i-(res-ntc_res[i])/(ntc_res[i-1]-ntc_res[i]);
}
int main(void)
{
    cy_rslt_t result;
    float ntc_res = 0;
    uint32_t adc_sum = 0;
    result = cybsp_init();
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }
    APP_LEDInit();
    app_uart_init();
    APP_AdcInit();
    printf("APP Start\n");
    __enable_irq();

    for (;;)
    {
        Cy_SysLib_Delay(100);
        adc_values[adc_value_index] = cyhal_adc_read_uv(&adc_ch_obj)/1000;
        adc_value_index += 1;
        if(adc_value_index == ADC_VALUE_NUM)
        {
            adc_value_index = 0;
            adc_sum = 0;
            while(adc_value_index < ADC_VALUE_NUM)
            {
                adc_sum += adc_values[adc_value_index];
                adc_value_index += 1;
            }
            adc_sum/=ADC_VALUE_NUM;
            if(adc_sum < 0xFFFF)
                ntc_res = 10.0*adc_sum/(3300-adc_sum);
            else
                ntc_res = 999;
            printf("NTC res:%.3f temp %.1f\n",ntc_res,NTC_GetTempFromRes(ntc_res));
            adc_value_index = 0;
            cyhal_gpio_toggle(CYBSP_USER_LED1);
        }
    }
}

测量结果



使用特权

评论回复
沙发
caoyunhj2301| | 2024-6-30 13:59 | 只看该作者
zzzzzz

使用特权

评论回复
板凳
gaonaiweng| | 2024-6-30 16:25 | 只看该作者
在主循环中每隔1秒读取一次电压值,cyhal_adc_read_uv这个方法获取到的是转换好的电压值单位是微伏

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

122

主题

612

帖子

5

粉丝