简介
通过stm32与ntc热敏电阻进行对水温的检测,测温范围为0~60℃,当温度超过60℃时,led闪烁,采用6针的OLED(spi通信协议)显示ntc的ad值和水温。
功能
1、温度测量范围:室温~60°,需在屏幕上显示;
2、温度测量精度:±2°;
3、超温提示,设定温度大于 60°时报警。
简易电路图
实物图
思路
1.A0口采用模拟输入(ADC专用)对ntc进行ad采集,将采集到的AD值在OLED显示
2.ntc与10k电阻在3.3V下串联分压,将ntc所在的温度与对应的ad值(通过电压进行计算)进行比对,用excel进行简单的拟合,即可求出温度与ad的对应关系进而在OLED上显示
3.通过代码控制gpio口使其在>60摄氏度时led闪烁,
代码部分(含解析)
1.AD采集(AD.C)
#include "stm32f10x.h" // Device header
void AD_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
//开启时钟,ADC都是APB2上的设备
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//开启GPIOA的时钟(要用到A0口)
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
//分频ADCCLK=72/6
GPIO_InitTypeDef GPIO_Initstructure;
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_AIN;
//模拟输入ADC专用
//断开GPIO防止GPIO输入输出对模拟电压造成干扰
GPIO_Initstructure.GPIO_Pin = GPIO_Pin_0;//即A0口
GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;//输入速度
GPIO_Init (GPIOA, &GPIO_Initstructure);
//GPIO初始化
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5);
//ADCx,指定通道,规则组里的次序(序列),
//指定通道的采样时间,参数小转换快不稳定
ADC_InitTypeDef ADC_InitStructure;//定义结构体
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
//对齐方式:右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1;
//扫描模式下通道数目:1
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
//扫描模式: 单次模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
//外部触发转换选择:软件触发
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
//转换模式(连续/单次):连续
ADC_Init(ADC1, &ADC_InitStructure);
//初始化结构体
ADC_Cmd(ADC1, ENABLE);//给ADC供电
ADC_ResetCalibration(ADC1);//复位校准
while (ADC_GetResetCalibrationStatus(ADC1) == SET);//等待复位校准完成
ADC_StartCalibration(ADC1);//开始校准
while (ADC_GetCalibrationStatus(ADC1) == SET);//等待校准完成
}
uint16_t AD_GetValue(void)
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发
while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//规则或注入
return ADC_GetConversionValue(ADC1);//返回ADC的值
}
2.主函数(main.c)
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"
uint16_t ADValue;
uint16_t TEMP;
//分别定义变量
int main(void)
{
OLED_Init();//OLED初始化
AD_Init();//ADC初始化
OLED_ShowString(1, 1, "ADValue:");
OLED_ShowString(2, 1, "TEMP:");
//OLED显示
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//打开时钟
GPIO_InitTypeDef GPIO_Initstructure1;
GPIO_Initstructure1.GPIO_Mode=GPIO_Mode_Out_PP;//输出模式为推挽输出
GPIO_Initstructure1.GPIO_Pin=GPIO_Pin_10;//选中引脚A0
GPIO_Initstructure1.GPIO_Speed=GPIO_Speed_50MHz;//输出速度为50MHz
GPIO_Init(GPIOB,&GPIO_Initstructure1);//用结构体参数来初始化GPIO口
//使用GPIOA
while (1)
{
ADValue=AD_GetValue();
OLED_ShowNum(1,9,ADValue,4);
TEMP=((uint16_t)ADValue-(uint16_t)1002)/(38);
//通过excel拟合的函数从而求得的公式
OLED_ShowNum(2,9,TEMP,2);
Delay_ms(500);//显示时间延时0.5s
GPIO_ResetBits(GPIOB,GPIO_Pin_10);//led默认为灭
if(TEMP>60)//判断是否超过60
{
while (1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_10);//亮
Delay_ms(100);
GPIO_SetBits(GPIOB,GPIO_Pin_10);//灭
Delay_ms(100);
ADValue=AD_GetValue();
if(ADValue<3200)
//若小于60℃,退出循环
break;
}
}
}
}
数据分析
1.求出ntc的ad值
1.通过原ntc温度对应电阻,在3.3v的串联电路下求其分压,与ad值0~4095对应
2.数据拟合
将对应数据转换成温度与NTC的ad值对应的曲线,并求出曲线的近似函数,进而确定温度与adc的对应关系。
视频演示
VID_20230223_095518
//希望对大家有所帮助,需要工程的请留言!!!