搞完了ADC的基本配置步驟,下面就是ADC配合一些外設的應用了,首先就是stm32f1內部的溫度傳感器通過adc采集獲得溫度;
內部溫度傳感器在ADC1的通道16上,所以只需要初始化以下ADC1就好了,然后再寫兩個函數來獲得ADC轉換之后的值並根據公式將該值轉換為溫度即可.
溫度公式:

公式中的 Avg_Slope 的典型值 4.3 的單位是 mv/C,而通過ADC采集並計算后的電壓單位是 V,所以這里 Avg_Slope 應該取 0.0043.這里好像一個坑,不知道正點原子怎么想的,在計算溫度的時候來了下面的兩行代碼:
result=temperate*=100; //擴大100倍.
return result;
看不懂他這個擴大100倍,明明返回的值是沒有擴大之前的值.不知道是不是bug,唉...現在想想,上學期模電沒學好,現在才發現模電的知識還是很有用的,以后還是得把專業課學好.
另外,需要注意,初始化的時候要開啟內部溫度傳感器功能,也可以說是使能內部溫度傳感器啦,其實也就是調用一個庫函數而已:
void ADC_TempSensorVrefintCmd(FunctionalState NewState); //開啟內部溫度傳感器
沒錯,就是這么簡單;
下面貼一下代碼,有關溫度傳感器配置相關的代碼都放在了 /HARDWARE/TSensor.c 下.
初始化函數:void TSensor_Init(void)
void TSensor_Init(void) { ADC_InitTypeDef adcInitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6); //ADC时钟设置为12MHz ADC_DeInit(ADC1); adcInitStruct.ADC_ContinuousConvMode = DISABLE; adcInitStruct.ADC_DataAlign = ADC_DataAlign_Right; adcInitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; adcInitStruct.ADC_Mode = ADC_Mode_Independent; adcInitStruct.ADC_NbrOfChannel = 1; adcInitStruct.ADC_ScanConvMode = DISABLE; ADC_Init(ADC1,&adcInitStruct); ADC_TempSensorVrefintCmd(ENABLE); ADC_Cmd(ADC1,ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1));
}
獲取指定通道ADC轉換的結果:u16 ADC1_GetConvValue(uint8_t channel)
u16 ADC1_GetConvValue(uint8_t channel)
{
ADC_RegularChannelConfig(ADC1,channel,1,ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
return ADC_GetConversionValue(ADC1);
}
獲取多次ADC的值求平均值:u16 ADC1_GetAverageConvValue(uint8_t channel,uint8_t times)
u16 ADC1_GetAverageConvValue(uint8_t channel,uint8_t times)
{
u8 i;
u32 temp = 0;
for(i = 0;i < times;i++)
{
temp += ADC1_GetConvValue(channel);
}
return temp/times;
}
將ADC采集到的值轉換為電壓值:double ACD1_SampleValue2ReadableValue(u16 sampleValue)
double ACD1_SampleValue2ReadableValue(u16 sampleValue)
{
return (double)sampleValue*((double)ADC_RefVoltoge/4096.0);
}
獲得溫度值:double TSensor_GetTemperature()
double TSensor_GetTemperature()
{
double VSense = ACD1_SampleValue2ReadableValue(ADC1_GetAverageConvValue(ADC_Channel_16,20));
USART_WriteLine("VSense:%.2f; %.2f",VSense,((1.43 - VSense)/0.0043+25.0));
return (1.43 - VSense)/0.0043+25.0;
}
main.c代碼
Init()函數
void Init(void)
{
delay_init();
USART_Debug_Init();
TSensor_Init();
USART_WriteLine("系統初始化完成!");
}
Loop()函數
void Loop(void)
{
double temp = TSensor_GetTemperature();
USART_WriteLine("溫度:%.2f",temp);
delay_ms(250);
}
這里面除了用到TSensor.c中的函數,還用到了我自己封裝的 Usart.c中的串口函數.有時間會記錄一下我是如何封裝自己的Usart來進行調試輸出的.
</div>
