- 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);
- }
- }
- }
测量结果