// main.c
#include "stm32f10x.h" // Device header
#include "math.h"
#include "Delay.h"
#include "OLED.h"
#include "ADC.h"
int main()
{
// rawvolt: 读取到的电压值. R_NTC: 用rawvolt和实际电路计算NTC电阻阻值. accTemp: 用公式通过阻值来计算实际温度.
// 公式: NTC热敏电阻的电阻-温度关系通常使用Steinhart-Hart方程或其简化形式(Beta公式)来表示.
uint16_t rawVolt = 0, R_NTC = 0, xiaoshu = 0;
double accTemp = 0;
OLED_Init();
ADC_Init_PB1();
OLED_ShowString(1, 1, "NTC TEMPRATURE!");
while(1)
{
// 用函数读取ADC的电压值.
rawVolt = ADC_Get_PB1_Value();
// 我才用的NTC25摄氏度标准电阻为10K, 将其串联到10K定值电阻上, 接到0-3.3V电源, 中点接出引线接到ADC in.
R_NTC = (rawVolt * 10000) / (4096 - rawVolt);
// 下用的就是Beta公式用电阻值计算实际温度.
accTemp = 1.0 / (1.0 / 298.15 + 1.0 / 3950.0 * log(R_NTC / 10000.0)) - 273.15;;
// 由于我的OLED显示函数不能显示小数, 这里取accTemp的小数部分, 精度小数点后2位.
xiaoshu = (int)(accTemp*100)%100;
OLED_ShowString(2, 1, "12ADC:");
OLED_ShowNum(2, 10, rawVolt, 4);
OLED_ShowString(3, 1, "R_NTC:");
OLED_ShowNum(3, 10, R_NTC, 6);
OLED_ShowString(4, 1, "accTemp:");
OLED_ShowNum(4, 10, accTemp, 2);
OLED_ShowChar(4, 12, '.');
OLED_ShowNum(4, 13, xiaoshu, 2);
OLED_ShowString(4, 15, "C");
Delay_ms(1000);
}
}
// ADC.c
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h"
// 修改GPIO/PIN可能需要改动的地方:
// ADC[x]
// GPIO[x]
// GPIO_Pin_[x]
// RCC时钟分频 RCC_PCLK2_Div[x]
// 采样时间 ADC_SampleTime_[x]Cycles5
void ADC_Init_PB1(void)
{
// 初始化ADC的5大步骤:
// 1. 开启RCC时钟, 包括GPIO和ADC的时钟. 配置ADCCLK的分频器.
// 2. 配置要用的GPIO pin为模拟输入.
// 3. 配置选择ADC-IN到ADC转换器的通道, 把通道加入规则组里.
// 4. 配置ADC转换器, 包括模式, 通道, 触发源, 数据对齐等等. 并开启ADC电源.
// 5. (可选, 建议) 校准ADC.
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 1, ADC_SampleTime_239Cycles5);
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC2, &ADC_InitStructure);
ADC_Cmd(ADC2, ENABLE);
ADC_ResetCalibration(ADC2);
while (ADC_GetResetCalibrationStatus(ADC2) == SET);
ADC_StartCalibration(ADC2);
while (ADC_GetCalibrationStatus(ADC2) == SET);
}
uint16_t ADC_Get_PB1_Value(void)
{
ADC_SoftwareStartConvCmd(ADC2, ENABLE);
while (ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET);
// 72/6 = 12Mhz, * 239.5T(采样周期)+12.5T(转换周期) = 252T = 5.6微秒.
return ADC_GetConversionValue(ADC2);
}