rt_adc_device_t adc_device = RT_NULL;
adc_device = (rt_adc_device_t)rt_device_find("adc1");
rt_adc_enable(adc_device,ADC_CHANNEL_TEMPSENSOR);
ad = rt_adc_read(adc_device,ADC_CHANNEL_TEMPSENSOR)/4095.0f*3.3f; // 电压
temp = (ad-0.76f)/0.0025f + 25.0f; //转换为温度值
以上代码直接运行会出现 "ADC channel must be between 0 and 18."
我已经尝试了把ADC_CHANNEL_TEMPSENSOR改为18 ,结果是:temp = -189.71 ℃,显然不对。
ADC_CHANNEL_TEMPSENSOR的宏定义是:
#define ADC_CHANNEL_TEMPSENSOR ((uint32_t)ADC_CHANNEL_18 | ADC_CHANNEL_DIFFERENCIATION_TEMPSENSOR_VBAT)
这里发现 《drv_adc.c 》中 static rt_uint32_t stm32_adc_get_channel(rt_uint32_t channel)
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4)
case 18:
stm32_channel = ADC_CHANNEL_18;
break;
很显然,RT-Thread的团队并没有考虑你会用ADC读取MCU内部温度这个问题,
简单粗暴的办法是在是把宏定义ADC_CHANNEL_TEMPSENSOR改为18,(使用18通道),把上面的代码改为
case 18:
stm32_channel = ADC_CHANNEL_18 | ADC_CHANNEL_DIFFERENCIATION_TEMPSENSOR_VBAT;
break;
另一种方法是在上述代码之后加入:
case ADC_CHANNEL_TEMPSENSOR:
stm32_channel = ADC_CHANNEL_TEMPSENSOR;
break;
在static rt_err_t stm32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
函数中把原来的 if (channel <= 18)改为
if (channel <= 18 || channel== ADC_CHANNEL_TEMPSENSOR)
改好之后测试 temp = 30.13 ℃
不知道各位还有没有更好的办法。 |