这是本文档旧的修订版!
// 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); }