未完,待續。。。。。。
也就是stm32f10X系列的adc采集出來的結果是12位的
stm32f10X系列有兩個16位adc
關於程序的編寫方法:一般 “某某.c文件”:都是用來設置“某某”的一些參數,在初始化函數里;還有就是“某某”的一些動作,比如小燈的亮滅。
“某某.h文件”:都是與.c文件配對的,主要是包含“某某.c”文件中的變量名和函數名。
這樣一來程序中所有的功能被拆分成塊,如:顯示用的屏幕部分,輸入用的按鍵部分,采集數據用的傳感器部分······
並把每個部分都變成了成對的.h和.c文件;實際上把各個部分的設置參數和動作函數都寫了下來。
之后在主函數main中根據需要依次進行調用。這樣一來不就是面向對象的思想了嗎??,,其實單片機也是面向對象的,而不是面向過程的。
每個 某某.c 文件都有固定的編寫次序:打開“某某”需要的時鍾;配置“某某”需要的管腳;編寫“某某”的初始化參數配置;使能“某某”;“某某”的動作函數編寫
下面是ADC中的 adc.c文件配置:
/*******************************************************************************
* 函數名 : adc_init
* 函數功能 :初始化ADC
* 輸入 :無
* 輸出 :無
*******************************************************************************/
void adc_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_ADC1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12M 最大14M 設置ADC的時鍾
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;//ADC
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; //管腳設置為模擬輸入
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
//指定ADC為規則組通道
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1);//重置指定ADC校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1));//獲取ADC重置校准寄存器的狀態
ADC_StartCalibration(ADC1);//開始指定ADC校准狀態
while(ADC_GetCalibrationStatus(ADC1));//獲取校准狀態
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能ADC轉換,讓ADC進行轉換。
}
下面是ADC的主程序
int main()
{
u32 ad=0;
u8 i;
adc_init(); //
printf_init(); //
while(1)
{
ad=0;
for(i=0;i<50;i++)//
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//
ad=ad+ADC_GetConversionValue(ADC1);//
}
ad=ad/50;
printf("ad=%fV\n",ad*3.3/4096);
delay_ms(1000);
}
}
一下內容摘自網絡:
STM32是自帶ADC的,關於ADC的簡介:
12位ADC是一種逐次逼近型模擬數字轉換器。
它有多達18個通道,可測量16個外部和2個內部信號源。
各通道的A/D轉換可以單次、連續、掃描或間斷模式執行。
ADC的結果可以左對齊或右對齊方式存儲在16位數據寄存器中。
模擬看門狗特性允許應用程序檢測輸入電壓是否超出用戶定義的高/低閥值。
ADC 的輸入時鍾不得超過14MHz,它是由PCLK2經分頻產生。
ADC的主要特征:
● 12位分辨率
● 規則轉換、注入轉換結束和發生模擬看門狗事件時產生中斷
● 單次和連續轉換模式
● 從通道0到通道n的自動掃描模式
● 間斷模式執行
● 自校准
● 帶內嵌數據一致性的數據對齊
● 采樣間隔可以按通道分別編程
● 規則轉換和注入轉換均有外部觸發選項
● 雙重模式(帶2個或以上ADC 的器件)
通道選擇:
有16個多路通道。可以把轉換組織成兩組:規則組和注入組。在任意多個通道上以任意順序進行的一系列轉換構成成組轉換。例如,可以如下順序完成轉換:通道3 、通道8 、通道2 、通道2、通道0、通道2、通道2、通道15。 ● 規則組由多達16個轉換組成。規則通道和它們的轉換順序在ADC_SQRx寄存器中選擇。規則組中轉換的總數應寫入ADC_SQR1寄存器的L[3:0]位中。 ● 注入組由多達4個轉換組成。注入通道和它們的轉換順序在ADC_JSQR寄存器中選擇。注入組里的轉換總數目應寫入ADC_JSQR寄存器的L[1:0]位中。 如果ADC_SQRx或ADC_JSQR寄存器在轉換期間被更改,當前的轉換被清除,一個新的啟動脈沖將發送到ADC 以轉換新選擇的組。 溫度傳感器和通道ADC1_IN16相連接,內部參照電壓VREFINT和ADC1_IN17相連接。可以按注入或規則通道對這兩個內部通道進行轉換。 注意: 溫度傳感器和VREFINT只能出現在主ADC1 中。
單次轉換模式:
單次轉換模式下,ADC只執行一次轉換。該模式既可通過設置ADC_CR2 寄存器的ADON位(只適用於規則通道)啟動也可通過外部觸發啟動(適用於規則通道或注入通道),這時CONT位為0 。 一旦選擇通道的轉換完成: ● 如果一個規則通道被轉換: ─ 轉換數據被儲存在16位ADC_DR寄存器中 ─ EOC(轉換結束)標志被設置 ─ 如果設置了EOCIE,則產生中斷。 ● 如果一個注入通道被轉換: ─ 轉換數據被儲存在16位的ADC_DRJ1寄存器中 ─ JEOC(注入轉換結束)標志被設置 ─ 如果設置了JEOCIE位,則產生中斷。然后ADC停止。
連續轉換模式:
在連續轉換模式中,當前面ADC轉換一結束馬上就啟動另一次轉換。此模式可通過外部觸發啟動或通過設置ADC_CR2寄存器上的ADON位啟動,此時CONT位是1。 每個轉換后: ● 如果一個規則通道被轉換: ─ 轉換數據被儲存在16位的ADC_DR寄存器中 ─ EOC(轉換結束)標志被設置 ─ 如果設置了EOCIE,則產生中斷。 ● 如果一個注入通道被轉換: ─ 轉換數據被儲存在16位的ADC_DRJ1寄存器中 ─ JEOC(注入轉換結束)標志被設置 ─ 如果設置了JEOCIE位,則產生中斷。
掃描模式:
此模式用來掃描一組模擬通道。 掃描模式可通過設置ADC_CR1寄存器的SCAN位來選擇。一旦這個位被設置,ADC掃描所有被ADC_SQRX 寄存器(對規則通道)或ADC_JSQR(對注入通道)選中的所有通道。在每個組的每個通道上執行單次轉換。在每個轉換結束時,同一組的下一個通道被自動轉換。如果設置了CONT位,轉換不會在選擇組的最后一個通道上停止,而是再次從選擇組的第一個通道繼續轉換。 如果設置了DMA位,在每次EOC后,DMA控制器把規則組通道的轉換數據傳輸到SRAM 中。而注入通道轉換的數據總是存儲在ADC_JDRx寄存器中。
間斷模式:
規則組 此模式通過設置ADC_CR1 寄存器上的DISCEN位激活。它可以用來執行一個短序列的n次轉換(n<=8),此轉換是ADC_SQRx寄存器所選擇的轉換序列的一部分。數值n由ADC_CR1寄存器的DISCNUM[2:0]位給出。 一個外部觸發信號可以啟動ADC_SQRx 寄存器中描述的下一輪n次轉換,直到此序列所有的轉換完成為止。總的序列長度由ADC_SQR1寄存器的L[3:0]定義。 舉例: n=3,被轉換的通道 = 0 、1、2、3、6、7、9、10 第一次觸發:轉換的序列為 0 、1、2 第二次觸發:轉換的序列為 3 、6、7 第三次觸發:轉換的序列為 9 、10,並產生EOC事件 第四次觸發:轉換的序列 0 、1、2 注意: 當以間斷模式轉換一個規則組時,轉換序列結束后不自動從頭開始。 當所有子組被轉換完成,下一次觸發啟動第一個子組的轉換。在上面的例子中,第四次觸發重新轉換第一子組的通道 0 、1和2。
注入組 此模式通過設置ADC_CR1 寄存器的JDISCEN位激活。在一個外部觸發事件后,該模式按通道順序逐個轉換ADC_JSQR寄存器中選擇的序列。 一個外部觸發信號可以啟動ADC_JSQR寄存器選擇的下一個通道序列的轉換,直到序列中所有的轉換完成為止。總的序列長度由ADC_JSQR寄存器的JL[1:0]位定義。 例子: n=1,被轉換的通道 = 1 、2、3 第一次觸發:通道1被轉換 第二次觸發:通道2被轉換 第三次觸發:通道3被轉換,並且產生EOC和JEOC事件 第四次觸發:通道1被轉換 注意: 1 當完成所有注入通道轉換,下個觸發啟動第1個注入通道的轉換。 在上述例子中,第四個觸發重新轉換第1個注入通道1。 2 不能同時使用自動注入和間斷模式。 3 必須避免同時為規則和注入組設置間斷模式。間斷模式只能作用 於一組轉換。
ADC時鍾配置:
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2); 輸入參數范圍: #define RCC_PCLK2_Div2 ((uint32_t)0x00000000) #define RCC_PCLK2_Div4 ((uint32_t)0x00004000) #define RCC_PCLK2_Div6 ((uint32_t)0x00008000) #define RCC_PCLK2_Div8 ((uint32_t)0x0000C000) STM32的ADC最大的轉換速率為1Mhz,也就是轉換時間為1us(在ADCCLK=14M,采樣周期為1.5個ADC時鍾下得到),不要讓ADC的時鍾超過14M,否則將導致結果准確度下降。
ADC的采樣時間:
可編程的通道采樣時間 ADC 使用若干個ADC_CLK 周期對輸入電壓采樣,采樣周期數目可以通過ADC_SMPR1 和ADC_SMPR2寄存器中的SMP[2:0]位更改。每個通道可以分別用不同的時間采樣。 總轉換時間如下計算: TCONV = 采樣時間+ 12.5個周期 例如:當ADCCLK=14MHz ,采樣時間為1.5周期 TCONV = 1.5 + 12.5 = 14周期 = 1μs 常見的周期有: 1.5周期、7.5周期、13.5周期、28.5周期、41.5周期、55.5周期、71.5周期、239.5周期。
數據對齊:
ADC_CR2寄存器中的ALIGN位選擇轉換后數據儲存的對齊方式。數據可以左對齊或右對齊,如圖29和圖30所示。 注入組通道轉換的數據值已經減去了在ADC_JOFRx寄存器中定義的偏移量,因此結果可以是一個負值。SEXT位是擴展的符號值。 對於規則組通道,不需減去偏移值,因此只有12個位有效。
校准:
ADC有一個內置自校准模式。校准可大幅減小因內部電容器組的變化而造成的准精度誤差。在校准期間,在每個電容器上都會計算出一個誤差修正碼(數字值),這個碼用於消除在隨后的轉換中每個電容器上產生的誤差。 通過設置ADC_CR2寄存器的CAL位啟動校准。一旦校准結束,CAL位被硬件復位,可以開始正常轉換。建議在上電時執行一次ADC校准。校准階段結束后,校准碼儲存在ADC_DR 中。 注意: 1 建議在每次上電后執行一次校准。 2 啟動校准前,ADC必須處於關電狀態(ADON=’0’)超過至少兩個ADC時鍾周期。