1. 程式人生 > 其它 >STM32之ADC實驗——獲取溫度

STM32之ADC實驗——獲取溫度

技術標籤:臨時微控制器stm32

使用韌體庫提供的函式來獲取內部溫度感測器資料的效果。
STM32F103VET6處理器內部內建了一個溫度感測器,該溫度感測器的在內部和ADC1_IN16輸入通道相連線,此通道把感測器輸出的電壓轉換成數字值。
需要注意的是,內部溫度感測器更適用於檢測溫度的變化,而不是測量絕對的溫度,如果需要測量精確的溫度,應該使用外接的溫度感測器。
ADC輸出的數字值和溫度之間的對應關係如下:
在這裡插入圖片描述
本例是使用通道10,採集PC0引腳的輸入電壓。

#include "stm32f10x.h"
#include "stm32f10x_usart.h"
#include <stdio.h> #include "stm32f10x dma.h" #include "stm32f10x_adc.h" void RCC_Configuration(void); void GPIO_Configuration(void); void DMA_Configuration(void); void USART_Config(void); int fputc(int ch, FILE*f); void ADC_Configuration(void): vul6 ADC_ConvertedValue; static
unsigned long ticks; int main(void) { uint8_t flag=0; vu16 Temperature; RCC_Configuration(): GPIO_Configuration(): USART_Config(): DMA_Configuration(): ADC_Configuration(): USART_ClearFlag(USART1,USART_FLAG_TC); while(1) { if(ticks++>=9000000) { ticks=
0; flag=1: } if(flag) { flag=0; Temperature=(1.43-ADC_ConvertedValue*3.3/4096)*1000/4.35+25; printf("The current AD value=%d\n",Temperrature; } } }

主函式中呼叫,RCC_Configuration()函式初始化系統時鐘,接著呼叫GPIO_Configuration()函式配置UART傳送和接收引腳以及ADC1輸入引腳,然後呼叫USART_Config()函式,配置串列埠輸出通訊引數,如波特率,資料位數等,呼叫DMA_Configuration()函式實現對DMA控制器的初始化,最後都要用ADC_Configuration()初始化ADC相關引數因為開啟了DMA功能,所以ADC轉換結束後,ADC的取樣值會被DMA源源不斷的運送到資料緩衝區,ADC_ConvertedValue中,雖然此資料緩衝區只有16位長度。
主函式中延時一段時間,然後打印出ADC的取樣值。

void GPIO_Configuration(void)
{
    GPIO_InitTypeDefGPIO_InitStructure;
    GPIO_Structinit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;             //USARTI TX
    GPIO_InitStructure.GPIO_Mode=GPIO_ Mode_AF_PP;      //複用推輓輸出
    GPlO_Init(GPIOA, &GPlO_lnitStructure);

    GPlO_InitStructure.GPIO_Pin = GPlO_Pin_10;          //USARTI RX
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //複用開漏輸入
    GPlO_Init(GPIOA,&GPlO_InitStructure);

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0:
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
    GPiO_Init(GPIOC, &GPlO_InitStructure);
}

該函式主要配置UART收發引腳以及ADC輸入引腳。

void RCC_Configuration(void)
{
   Systemlnit();
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
   RCC_AHBPeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
   RCC_ADCCLKConfig(RCC_PCLK2_Div6);
}


該函式負責管理各個模組的時鐘,該實驗中用到了ADC1所以需要開啟它的時鐘,同時,PC0作為ADC輸入引腳,因此也需要開啟CPIOC時鐘,最後一行使用RCC_ADCCLKConfig(RCC_PCLK2_Div6)函式對配置ADC1輸入時鐘,對PCLK2進行6分頻,因為PCLK2時鐘頻率為,72MHz,所以ADC1輸入時鐘為12MHz。

viod USART_Config(void)
{
   USART_InitTypeDefUSART_InitStructure;
   USART_InitStructure.USART_BaudRate                  = 115200;
   USART_InitStructure.USART_WordLength                =USART_WordLength_8b;
   USART_InitStructure.USART_StopBits                  =USART_StopBits_1;
   USART_InitStructure.USART_Parity                    =USART_Parity_No;
   USART_InitStructure.USART_HardwareFlowControl       =USART_HardwareFlowControl_None;
   USART_InitStructure.USART_Mode                      =USART_Mode_Tx;
   USART_Init(USART1,&USART_InitStructure);
   USART_Cmd(USART1, ENABLE);
}
void ADC_Configuration(void)
{
    ADC_InittypeDef ADC_InitStructure;
    ADC_InitStructurc.ADC_Mode                         =ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode                 =ENABLE;
    ADC InitStructure.ADC_ContinuousConvMode           =ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConv             =ADC_ExternalTrigConv_None;
    ADC_InitStructurc.ADC_DataAlign                    =ADC_DataAlign_Right;
    ADC_InitStructurc.ADC_NbrOfChannel                 =1;
    ADC_Init(ADCI, &ADC_InitStructure):

    ADC_RegularChannelConfig(ADC1,ADC_Channel_16,1,ADC_SampleTime_55Cycles5);
    ADC_DMACmd(ADC1, ENABLE);
    
    ADC_TempSensorVrefintCmd(EMABLE);                  //開啟溫度感測器參考電壓
    
    ADC_Cmd(ADCI ENABLE):
    ADC_ResetCalibration(ADC1);
    while(ADC_GetReseiCalibrationStatus(ADC1)):
    ADC_StartCalibration(ADC1);
    whilet(ADC_GetCalibrationStatus(ADC1)):

    ADC_SoftwareStartConvCmd(ADC1, ENABLE):
}

第1行,定義結構體變鼠ADC_IniStructure, 該變數中包含了初始化ADC相關的引數,對該變數的成員變數進行初始化,然後呼叫ADC_Init()函式 (第8行)即可實現對ADC相關裔存器最終的初始化。
第2行,設定ADC工作在獨立工作模式,ADC 有幾種工作模式,如同步注入模式、同步規則模式、快速交叉模式、慢速交義模式、交替觸發模式等,但是目前為止,還是先預設使用獨立工作模式,因為這種工作模式最簡單。
第3~4行,設定掃描模式和連續工作模式,即連續採集ADC第11通道(PC0引腳)的電壓值。
第5行,不需要外部觸發ADC轉換,在本實驗中使用軟體觸發ADC轉換。
第6行,資料對齊方式選擇右對齊,因為16位的ADC資料暫存器中只儲存了12位的有效數比據(ADC的解析度為12位),所以オ有資料對齊的問題。
第7行,設定轉換的通道數目,使用多個通道時,這裡需要改為確切的通道數目。
第9行,設定ADC輸入通道的取樣週期數。ADC總轉換時間計算式如下:

Tconv = (取樣週期數+ 12.5)個週期

例如,當ADCCLK=14MHz,取樣時間為1.5個週期時,ADC轉換時間Tcoxv=1.5+ 12.5=14個週期=1微秒。
第10~11行,使能DMA功能,同時使能ADC.

第12~14行,復位校準備存器,待校準暫存器復位後,開啟ADC校準功能,持ADC膠準結束後。即可府動ADC轉換。ADC有一個內建自校準模式.校準功能可大幅波小個因內部電容器組的變化而造皮的誤だ。在校準明間,在每個電容器上都會計算出個誤差修正碼,這個碼用於消除在隨後的轉換中每個電容器上產生的誤差。

void DMA_Configuration(void)
{
   DMA_lnitTypeDefDMA_JnitStructurc.
   DMA_DeInit(DMA1_Channel1):
   DNA_InitStructure.DMA_peripheralBaseAddr=(uint32_t)&ADC1->DR;
   DNA_InitStructure.DMA_MemoryBaseAddr    =(u32)&ADC_ConvertedValue;
   DNA_InitStructure.DMA_DIR               =DMA_DIR_peripheralSRC;
   DNA_InitStructure.DMA_BufferSize        =1;
   DNA_InitStructure.DMA_PeripheralInc     =DMA_PeripheralInc_Disable;
   DNA_InitStructure.DMA_MemoryInc         =DMA_MenoryInc_Disable;
   DNA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
   DNA_InitStructure.DMA_MemoryDataSize    =DMA_MenoryDataSize_HalfWord;
   DNA_InitStructure.DMA_Mode              =DMA+Mode_Circular;
   DNA_InitStructure.DMA_Priority          =DMA_Priority_High;
   DNA_InitStructure.DMA_M2M               =DMA_M2M_Disable;
   DMA_Init(DMA1_Channe1,&DMA_InitStructure);
   DMA_Cmd(DMA1_Channel1,ENABLE);
}


上述函式主要配置ADC相關DMA通道引數,在前文中已經說了。

int fputc(int ch, FILE*f)
{
   if(ch=="\n")
   { 
         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
         USART_SendData(USART1,"\r");
   }
   while(USART_GeFlagStatus(USART1,USART_FLAG_Tc)==RESET);
   USART_SendDate(USART1,ch);

return ch;




該函式主要為了串列埠重定向功能。
main()函式主要是實現對溫度的資料處理工作,資料處理完成後通過串列埠輸出以便於觀察實驗結果。