(本人为电子学生小白,以下是个人学习过程中的归纳总结)
最近看过一篇文章了解到二极管1N4148的平均灵敏度是-2mV/℃,可以理解为每升高1摄氏度1N4148两端正向导通电压降低2mV,图1中有3个模块,分别为恒流源,仪表放大器电路,减法电路,其中按照个人想法,减法电路用于检测0摄氏度以下的温度,一般情况下只需要采用恒流源和仪表放大器电路即可。
恒流源
为什么要使用到恒流源?基于我个人的想法,高中生物学过“控制变量法”,也就是说,温度可以影响到1N4148正向导通两端的电压,参照数据手册可以发现电流也可以影响1N4148两端电压的变化,因此为了减少干扰因素,采取恒流源来尽量保持电路不随着温度的变化而变化。整体电路采用一个LM324运放(不考虑减法电路)及双电源供电,采用TL431输出2.5V电压,根据虚短得D2的K极(阴极)电位为2.5V,调节电位器RP1控制流过1N4148的电路
仪表放大器
参考下图,Vout=(Vin2-Vin1)(1+R5/R6)(R2/R1)
三运放组成的仪表放大器
图1 设计电路及仿真
图2 原理图
图3 PCB
本人设计两个USB口目的是使用STM32开发板进行ADC采样来显示具体的温度信息
实物显示:
图4 测试图
图5 测试图
图2原理图下载,使用阿里云盘https://www.aliyundrive.com/s/1eoCVNgzb5K
阿里云盘分享不了压缩包,代码就贴在下面了
基于野火STM32F103VET6指南者的ADC采样,使用PC5引脚
adc.c文件
#include "adc.h"
/**********************************************************
功 能:ADC1初始化配置函数
参 数:无
返回值:无
**********************************************************/
void ADC_Hardware_Init(void)
{
GPIO_InitTypeDef GPIO_TypeDefStructure;
ADC_InitTypeDef ADC_TypeDefStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,ENABLE);
GPIO_TypeDefStructure.GPIO_Pin = GPIO_Pin_5;//选择端口
GPIO_TypeDefStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入
GPIO_Init(GPIOC,&GPIO_TypeDefStructure);//初始化配置
// 配置中断优先级
NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/***************** ADC设置 ******************/
// 配置ADC时钟为PCLK2的8分频,即9MHz
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
ADC_TypeDefStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
ADC_TypeDefStructure.ADC_ScanConvMode = DISABLE;// 禁止扫描模式,多通道才要,单通道不需要
ADC_TypeDefStructure.ADC_ContinuousConvMode = ENABLE;//连续转换
ADC_TypeDefStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//禁止触发检测
ADC_TypeDefStructure.ADC_DataAlign = ADC_DataAlign_Right;//转换结果右对齐
ADC_TypeDefStructure.ADC_NbrOfChannel = 1;//1个转换在序列规则中
ADC_Init(ADC1,&ADC_TypeDefStructure);//初始化配置
ADC_Cmd(ADC1,ENABLE);//ADC使能
}
/**********************************************************
功 能:ADC采集函数
参 数:无
返回值:最近一次的转换结果
**********************************************************/
uint16_t ADC_Collect(void)
{
ADC_RegularChannelConfig(ADC1,ADC_Channel_15,1,ADC_SampleTime_55Cycles5);//ADCX,ADC通道,规则序列, 采样时间
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件ADC1功能
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//等待转换结束
return ADC_GetConversionValue(ADC1);//返回最近一次转换结果
}
/**********************************************************
功 能:通过LCD显示转换结果
参 数:无
返回值:无
**********************************************************/
void Display_result(void)
{
float temp,vol;
adcx = ADC_Collect();
temp = adcx/50.0;
vol = adcx*3.3/4096;
sprintf(show,"Test T:%4d %.1f",adcx,temp);
ILI9341_DispStringLine_EN(LINE(4),show);
sprintf(show,"Test VOL:%.3f V",vol);
ILI9341_DispStringLine_EN(LINE(5),show);
Delay_ms(500);
Delay_ms(500);
}
adc.h文件
#ifndef __ADC_H_
#define __ADC_H_
#include "stm32f10x.h"
#include <stdio.h>
#include "bsp_ili9341_lcd.h"
#include "delay.h"
static uint16_t adcx = 0; //采样值
static char show[70]= {0}; //用于存放打印数据的数组
void ADC_Hardware_Init(void); //ADC初始化配置函数
uint16_t ADC_Collect(void); //ADC采集函数
void Display_result(void); //显示结果
#endif
ILI9341电阻屏参考野火官方例程即可