Analog Digital Convert

// 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);
}