日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

(stm32f103学习总结)—ADC模数转换实验

發(fā)布時(shí)間:2023/12/19 综合教程 52 生活家
生活随笔 收集整理的這篇文章主要介紹了 (stm32f103学习总结)—ADC模数转换实验 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、STM32F1 ADC介紹

  TM32F103 系列一般都有 3 個(gè) ADC,這些 ADC 可以獨(dú)立使用,也可 以使用雙重(提高采樣率)。STM32F1 的 ADC 是 12 位逐次 逼近型的模擬數(shù)字轉(zhuǎn)換器。它具有多達(dá) 18個(gè)復(fù)用通道,可測(cè)量來自16 個(gè)外部源、2 個(gè)內(nèi)部源信號(hào)。 這些通道的 A/D 轉(zhuǎn)換可 以單次、連續(xù)、掃描或間斷模式執(zhí)行。ADC 的結(jié)果可以左對(duì)齊或右對(duì)齊 方式存儲(chǔ)在 16 位數(shù)據(jù)寄存器中。ADC具有模擬看門狗特性,允許應(yīng)用程 序檢測(cè)輸入電壓是否超出用戶定義的閥值上限或者下限。

1.2 STM32F1 ADC結(jié)構(gòu)框圖

STM32F1 ADC擁有這么多功能,是由ADC內(nèi)部結(jié)構(gòu)所決定。要更好的理 解STM32F1的ADC,就需要了解它內(nèi)部的結(jié)構(gòu)。如下圖所示:(大家 也可以查看《STM32F10x中文參考手冊(cè)》-11模數(shù)轉(zhuǎn)換器(ADC)章-ADC功 能說明)。

(1)標(biāo)號(hào)1:電壓輸入引腳

  ADC輸入電壓范圍為: VREF- ≤ VIN ≤ VREF+。由 VREF-、 VREF+ 、 VDDA 、 VSSA這四個(gè)外部引腳決定。通常我們把 VSSA和 VREF-接地 ,把 VREF+和 VDDA 接 3.3V,因此ADC的輸入電壓范圍為:0~3.3V。我 們使用的開發(fā)板ADC輸入電壓范圍為0~3.3V。

(2)標(biāo)號(hào)2:輸入通道

  STM32 的 ADC的輸入通道多達(dá) 18 個(gè),其中外部的 16 個(gè)通道就是框 圖中的 ADCx_IN0、ADCx_IN1...ADCx_IN5(x=1/2/3,表示ADC數(shù)),通 過這16個(gè)外部通道可以采集模擬信號(hào)這 16 個(gè)通道對(duì)應(yīng)著不同的 IO 口, 具體是哪一個(gè) IO 口可以從數(shù)據(jù)手冊(cè)查詢到,也可以從下圖查 看,同樣我們?cè)陂_發(fā)板芯片原理圖內(nèi)也給大家標(biāo)注了。其中 ADC1 還有2 個(gè)內(nèi)部通道:ADC1 的通道16連接到了芯片內(nèi)部的溫度傳感器通道17連 接到了內(nèi)部參考電壓 VREFINT。ADC2 和ADC3的通道 16、 17全部連接到 了內(nèi)部的 VSS。

(3)標(biāo)號(hào)3:通道轉(zhuǎn)換順序

  外部的 16 個(gè)通道在轉(zhuǎn)換的時(shí)候可分為2組通道:規(guī)則通道組注入 通道組,其中規(guī)則通道組最多有16路,注入通道組最多有 4 路。 規(guī)則通道組:從名字來理解,規(guī)則通道就是一種規(guī)規(guī)矩矩的通道,類 似于正常執(zhí)行的程序,通常我們使用的都是這個(gè)通道。 注入通道組:從名字來理解,注入即為插入,是一種不安分的通道, 類似于中斷。當(dāng)程序正常往下執(zhí)行時(shí),中斷可以打斷程序的執(zhí)行。同樣 如果在規(guī)則通道轉(zhuǎn)換過程中,有注入通道插入,那么就要先轉(zhuǎn)換完注入 通道,等注入通道轉(zhuǎn)換完成后再回到規(guī)則通道的轉(zhuǎn)換流程。 每個(gè)組包含一個(gè)轉(zhuǎn)換序列,該序列可按任意順序在任意通道上完成。 例如,可按以下順序?qū)π蛄羞M(jìn)行轉(zhuǎn)換: ADC_IN3、ADC_IN8、 ADC_IN2、 ADC_IN2、 ADC_IN0、 ADC_IN2、 ADC_IN2、 ADC_IN15。

(4)標(biāo)號(hào)4:觸發(fā)源(外部觸發(fā)和軟件觸發(fā))

  選擇好輸入通道,設(shè)置好轉(zhuǎn)換順序,接下來就可以開始轉(zhuǎn)換。要開啟 ADC轉(zhuǎn)換,可以直接設(shè)置ADC 控制寄存器ADC_CR2 的 ADON位為1,即使能 ADC。當(dāng)然ADC還支持外部事件觸發(fā)轉(zhuǎn)換,觸發(fā)源有很多,具體選擇哪一 種觸發(fā)源,由 ADC 控制寄存器2:ADC_CR2 的 EXTSEL[2:0]和 JEXTSEL[2:0]位來控制。EXTSEL[2:0]用于選擇規(guī)則通道的觸發(fā)源, JEXTSEL[2:0]用于選擇注入通道的觸發(fā)源。選定好觸發(fā)源之后,觸發(fā)源 是否要激活,則由 ADC 控制寄存器ADC_CR2 的 EXTTRIG 和 JEXTTRIG 這兩位來激活。 如果使能了外部觸發(fā)事件,我們還可以通過設(shè)置 ADC 控制寄存器 2:ADC_CR2 的EXTEN[1:0]和 JEXTEN[1:0]來控制觸發(fā)極性,可以有 4 種 狀態(tài),分別是:禁止觸發(fā)檢測(cè)、上升沿檢測(cè)、下降沿檢測(cè)以及上升沿和 下降沿均檢測(cè)。

(5)標(biāo)號(hào)5:ADC時(shí)鐘

  ADC 輸入時(shí)鐘 ADC_CLK 由 APB2經(jīng)過分頻產(chǎn)生,最大值是14MHz,分 頻因子由 RCC 時(shí)鐘配置寄存器 RCC_CFGR 的位 15:14 ADCPRE[1:0]設(shè)置 ,可以是 2/4/6/8 分頻,注意這里沒有 1 分頻。我們知道APB2總線時(shí) 鐘為72M而ADC最大工作頻率為14M所以一般設(shè)置分頻因子為6,這樣 ADC的輸入時(shí)鐘為12MHz。

  ADC要完成對(duì)輸入電壓的采樣需要若干個(gè)ADC_CLK周期,采樣的周期數(shù) 可通過ADC 采樣時(shí)間寄存器 ADC_SMPR1 和 ADC_SMPR2 中的 SMP[2:0]位 設(shè)置, ADC_SMPR2控制的是通道 0~9, ADC_SMPR1 控制的是通道 10~17 。每個(gè)通道可以分別用不同的時(shí)間采樣。其中采樣周期最小是1.5個(gè),即 如果我們要達(dá)到最快的采樣,那么應(yīng)該設(shè)置采樣周期為1.5個(gè)周期,這里 說的周期就是 1/ADC_CLK。

  ADC 的總轉(zhuǎn)換時(shí)間跟ADC 的輸入時(shí)鐘和采樣時(shí)間有關(guān),其公式如下:

  (轉(zhuǎn)換時(shí)間) Tconv = 采樣時(shí)間 + 12.5個(gè)周期

其中Tconv為ADC總轉(zhuǎn)換時(shí)間,當(dāng)ADC_CLK=14Mhz的時(shí)候,并設(shè)置1.5個(gè)周 期的采樣時(shí)間,則Tcovn=1.5+12.5=14個(gè)周期=1us

(6)標(biāo)號(hào)6:數(shù)據(jù)寄存器

  ADC 轉(zhuǎn)換后的數(shù)據(jù)根據(jù)轉(zhuǎn)換組的不同,規(guī)則組的數(shù)據(jù)放在ADC_DR 寄 存器內(nèi),注入組的數(shù)據(jù)放在 JDRx內(nèi)。 因?yàn)镾TM32F1的ADC是12位轉(zhuǎn)換精度,而數(shù)據(jù)寄存器是16位,所以ADC 在存放數(shù)據(jù)的時(shí)候就有左對(duì)齊和右對(duì)齊區(qū)分。如果是左對(duì)齊,AD轉(zhuǎn)換完 成數(shù)據(jù)存放在 ADC_DR 寄存器的[4:15]位內(nèi);如果是右對(duì)齊,則存放在 ADC_DR 寄存器的[0:11]位內(nèi)。具體選擇何種存放方式,需通過ADC_CR2 的 11 位 ALIGN 設(shè)置。

(7)標(biāo)號(hào)7:中斷

  當(dāng)發(fā)生如下事件且使能相應(yīng)中斷標(biāo)志位時(shí),ADC能產(chǎn)生中斷。

1.轉(zhuǎn)換結(jié)束(規(guī)則轉(zhuǎn)換)與注入轉(zhuǎn)換結(jié)束

2.模擬看門狗事件

3.DMA請(qǐng)求

二、STM32F1 ADC配置步驟

(1)使能端口時(shí)鐘和ADC時(shí)鐘,設(shè)置引腳模式為模擬輸入

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);

  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN; //模擬輸入模式

(2)設(shè)置ADC的分頻因子

  RCC_ADCCLKConfig(RCC_PCLK2_Div6);

(3)初始化ADC參數(shù),包括ADC工作模式、規(guī)則序列等

  ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);

(4)使能ADC并校準(zhǔn)

  ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);

  ADC_Cmd(ADC1, ENABLE);//開啟AD轉(zhuǎn)換器

  執(zhí)行復(fù)位校準(zhǔn)的方法是: ADC_ResetCalibration(ADC1);

  執(zhí)行 ADC 校準(zhǔn)的方法是: ADC_StartCalibration(ADC1); //開始指定 ADC1 的校準(zhǔn)狀態(tài)

  while(ADC_GetResetCalibrationStatus(ADC1)); //等待復(fù)位校準(zhǔn)結(jié)束

  while(ADC_GetCalibrationStatus(ADC1)); //等待校準(zhǔn)結(jié)束

(5)讀取ADC轉(zhuǎn)換值 設(shè)置規(guī)則序列通道以及采樣周期的庫函數(shù)是:

  ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel,uint8_t Rank, uint8_t ADC_SampleTime);

  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 )

設(shè)置好規(guī)則序列通道及采樣周期,接下來就要開啟轉(zhuǎn)換,由于我們采 用的是軟件觸發(fā),庫函數(shù)

 ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

要開啟 ADC轉(zhuǎn)換.

三、編寫ADC控制程序

本章所要實(shí)現(xiàn)的功能是:通過ADC1通道1采樣外部電壓值,將采樣的 AD值和轉(zhuǎn)換后的電壓值通過串口打印出來,同時(shí)D1指示燈閃爍,提示系 統(tǒng)正常運(yùn)行。

程序框架如下: (1)初始化ADC1_IN1相關(guān)參數(shù),開啟ADC1 (2)編寫獲取ADC1_IN1的AD轉(zhuǎn)換值函數(shù) (3)編寫主函數(shù)

 1 #ifndef _adc_H
 2 #define _adc_H
 3 
 4 #include "system.h"
 5 
 6 void ADCx_Init(void);
 7 u16 Get_ADC_Value(u8 ch,u8 times);
 8 
 9 
10 #endif

 1 #include "adc.h"
 2 #include "SysTick.h"
 3 
 4 /*******************************************************************************
 5 * 函 數(shù) 名         : ADCx_Init
 6 * 函數(shù)功能           : ADC初始化    
 7 * 輸    入         : 無
 8 * 輸    出         : 無
 9 *******************************************************************************/
10 void ADCx_Init(void)
11 {
12     GPIO_InitTypeDef GPIO_InitStructure; //定義結(jié)構(gòu)體變量    
13     ADC_InitTypeDef       ADC_InitStructure;
14     
15     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
16     
17     RCC_ADCCLKConfig(RCC_PCLK2_Div6);//設(shè)置ADC分頻因子6 72M/6=12,ADC最大時(shí)間不能超過14M
18     
19     GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;//ADC
20     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;    //模擬輸入
21     GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
22     GPIO_Init(GPIOA,&GPIO_InitStructure);
23     
24     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
25     ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非掃描模式    
26     ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//關(guān)閉連續(xù)轉(zhuǎn)換
27     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//禁止觸發(fā)檢測(cè),使用軟件觸發(fā)
28     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右對(duì)齊    
29     ADC_InitStructure.ADC_NbrOfChannel = 1;//1個(gè)轉(zhuǎn)換在規(guī)則序列中 也就是只轉(zhuǎn)換規(guī)則序列1 
30     ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
31     
32     ADC_Cmd(ADC1, ENABLE);//開啟AD轉(zhuǎn)換器
33     
34     ADC_ResetCalibration(ADC1);//重置指定的ADC的校準(zhǔn)寄存器
35     while(ADC_GetResetCalibrationStatus(ADC1));//獲取ADC重置校準(zhǔn)寄存器的狀態(tài)
36     
37     ADC_StartCalibration(ADC1);//開始指定ADC的校準(zhǔn)狀態(tài)
38     while(ADC_GetCalibrationStatus(ADC1));//獲取指定ADC的校準(zhǔn)程序
39 
40     ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能或者失能指定的ADC的軟件轉(zhuǎn)換啟動(dòng)功能
41 }
42 
43 /*******************************************************************************
44 * 函 數(shù) 名         : Get_ADC_Value
45 * 函數(shù)功能           : 獲取通道ch的轉(zhuǎn)換值,取times次,然后平均     
46 * 輸    入         : ch:通道編號(hào)
47                      times:獲取次數(shù)
48 * 輸    出         : 通道ch的times次轉(zhuǎn)換結(jié)果平均值
49 *******************************************************************************/
50 u16 Get_ADC_Value(u8 ch,u8 times)
51 {
52     u32 temp_val=0;
53     u8 t;
54     //設(shè)置指定ADC的規(guī)則組通道,一個(gè)序列,采樣時(shí)間
55     ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);    //ADC1,ADC通道,239.5個(gè)周期,提高采樣時(shí)間可以提高精確度                
56     
57     for(t=0;t<times;t++)
58     {
59         ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的ADC1的軟件轉(zhuǎn)換啟動(dòng)功能    
60         while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待轉(zhuǎn)換結(jié)束
61         temp_val+=ADC_GetConversionValue(ADC1);
62         delay_ms(5);
63     }
64     return temp_val/times;
65 } 

 1 #include "system.h"
 2 #include "SysTick.h"
 3 #include "led.h"
 4 #include "usart.h"
 5 #include "adc.h"
 6 
 7 
 8 /*******************************************************************************
 9 * 函 數(shù) 名         : main
10 * 函數(shù)功能           : 主函數(shù)
11 * 輸    入         : 無
12 * 輸    出         : 無
13 *******************************************************************************/
14 int main()
15 {
16     u8 i=0;
17     u16 value=0;
18     float vol;
19     
20     SysTick_Init(72);
21     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中斷優(yōu)先級(jí)分組 分2組
22     LED_Init();
23     USART1_Init(9600);
24     ADCx_Init();
25     
26     while(1)
27     {
28         i++;
29         if(i%20==0)
30         {
31             led1=!led1;
32         }
33         
34         if(i%50==0)
35         {
36             value=Get_ADC_Value(ADC_Channel_1,20);
37             printf("檢測(cè)AD值為:%d
",value);
38             vol=(float)value*(3.3/4096);
39             printf("檢測(cè)電壓值為:%.2fV
",vol);
40         }
41         delay_ms(10);    
42     }
43 }

總結(jié)

以上是生活随笔為你收集整理的(stm32f103学习总结)—ADC模数转换实验的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。