[基本功能:]
ADC 可以(獨立轉換) 或 (雙重轉換) 提高解析精度
ADC 12bit SAR 逐步逼近式
ADC type :
** 高精度的用sigma-delta, delta-sigma data converters
theory
** 高速的用pipeline,
** 而超高速的用FLASH,
** 一般的用SAR
ST32 有 16 ext_Channel And
2 int_Channel single source
ADC 轉換模式
單次 連續 掃描 間斷
ADC load data(12 bit) save to 16 bit Reg 可以採 靠右存 或 靠左存
ADC 值可以設比較中斷 當信號轉換達到設定值自動產生中斷
ADC 最道轉換率 1M (word)/s , 所以(ADC_CLK < 14MHz)
ADC 通道分兩組
規則通道: 正常運行被動轉換最多16 Channel
注入通道: 由中斷引起轉換 最多 4 Channel
注入通道可以中斷規則通道作業,等注入通道完成後規則通道才能作業
[作業說明:]
1
ADC_CR2#0_ADON setup 1: 啟動 0:停止
2 轉換完成 存入 ADC_DR(16bit 靠左 or 靠右)
3 存入ADC_DR 後 EOC Flag 被設為1 若 ADC_CR1#5_EOCIE set 1: 產生中斷
ADC
停止到下次啟動
[ADC REG]
ADC_CR1#8 SCAN
該位元用於設置掃描模式,由軟體設置和清除,如果設置
為1,則使用掃描模式,如果為0,則關閉掃描模式
ADC_CR1#5_EOCIE
ADC_CR1#7_JEOCIE
ADC_CR1#[16:19] DUALMOD[3:0] ADC 操作 mode
0000: 獨立mode
0001: 混合的同步規則+ 注入同步
0010: 混合的同步規則+ 交替觸發
0011: 混合的同步規則+ 快速交替
0100: 混合的同步規則+ 慢速交替
0101: 注入同步
0110: 規則同步
0111: 快速交替
1000: 慢速交替
1001: 交替觸發
ADC_CR2
ADC_CR2#0 ADON 位元用於開關AD 轉換
ADC_CR2#1 CONT CONT
位用於設置是否進行連續轉換,
我們使用單次轉換,所以CONT 位必須為0
我們使用單次轉換,所以CONT 位必須為0
ADC_CR2#2 CAL ADC 校準
ADC_CR2#3 RSTCAL ADC 校準
ADC_CR2#11
ALIGN
ALIGN 用於設置資料對齊,我們使用右對齊,該位設置為0
ADC_CR2#[19:17] EXTSEL[2:0] 規則通道觸發條件
ADC1 , ADC2
000 T1 cc1 100 T3 TRGO
001 T1 cc2 101 T4 cc4
010 T1 cc3 110 EXTI 11/T8_TRGO
011 T2 cc2 111 [WSTART 軟體觸發]
ADC3
000 T3 cc1 100 T8 TRGO
001 T2 cc3 101 T5 cc1
010 T1 cc3 110 T5 cc4
011 T8 cc1 111 [WSTART 軟體觸發]
用於選擇啟動規則轉換組轉換的外部事件,我們這
裡使用的是軟體觸發(SWSTART),所以設置這3
個位為111
ADC_SMPR1
ADC_SMPR2
這兩個寄存器用於設置通道0~17
的採樣時間,每個通道佔用3 個位
ADC_SQR1..3:
ADC_DR
ADC_SR
1)開啟PA口時鐘,設置PA0為模擬輸入。
STM32F103RBT6的ADC通道0在PA0上,所以,我們先要使能PORTA的時鐘,然後設置PA0為模擬輸入。
2)使能ADC1時鐘,並設置分頻因數。
要使用ADC1,第一步就是要使能ADC1的時鐘,在使能完時鐘之後,進行一次ADC1的復位。接著我們就可以通過RCC_CFGR設置ADC1的分頻因數。分頻因數要確保ADC1的時鐘(ADCCLK)不要超過14Mhz。
3)設置ADC1的工作模式。
在設置完分頻因數之後,我們就可以開始ADC1的模式配置了,設置單次轉換模式、觸發方式選擇、資料對齊方式等都在這一步實現。
4)設置ADC1規則序列的相關資訊。
接下來我們要設置規則序列的相關資訊,我們這裡只有一個通道,並且是單次轉換的,所以設置規則序列中通道數為1,然後設置通道0的採樣週期。
5)開啟AD轉換器,並校準。
在設置完了以上資訊後,我們就開啟AD轉換器,執行復位校準和AD校準,注意這兩步是必須的!不校準將導致結果很不準確。
6)讀取ADC值。
在上面的校準完成之後,ADC就算準備好了。接下來我們要做的就是設置規則序列0裡面的通道,然後啟動ADC轉換。在轉換結束後,讀取ADC1_DR裡面的值就是了。
通過以上幾個步驟的設置,我們就可以正常的使用STM32
的ADC1 來執行AD 轉換操作了。
二,程式碼
void Adc_Init(void)
{
//先初始化IO口
RCC->APB2ENR|=1<<2 p="">2>
GPIOA->CRL&=0XFFFF0000;//PA0
1 2 3 anolog 輸入
//通道10/11設置
RCC->APB2ENR|=1<<9 p="">9>
RCC->APB2RSTR|=1<<9 p="">9>
RCC->APB2RSTR&=~(1<<9 p="">9>
RCC->CFGR&=~(3<<14 p="">14>
//SYSCLK/DIV2=12M
ADC時鐘設置為12M,ADC最大時鐘不能超過14M!
//否則將導致ADC準確度下降!
RCC->CFGR|=2<<14 p="">14>
ADC1->CR1&=0XF0FFFF;
//工作模式清零
ADC1->CR1|=0<<16 p="">16>
ADC1->CR1&=~(1<<8 p="">8>
ADC1->CR2&=~(1<<1 p="">1>
ADC1->CR2&=~(7<<17 p="">17>
ADC1->CR2|=7<<17 p="">17>
ADC1->CR2|=1<<20 p="">20>
ADC1->CR2&=~(1<<11 p="">11>
ADC1->SQR1&=~(0XF<<20 p="">20>
ADC1->SQR1&=0<<20 p="">20>
//設置通道0~3的採樣時間
ADC1->SMPR2&=0XFFFFF000;//通道0,1,2,3採樣時間清空
ADC1->SMPR2|=7<<9 239.5="" p="">9>
ADC1->SMPR2|=7<<6 239.5="" p="">6>
ADC1->SMPR2|=7<<3 239.5="" p="">3>
ADC1->SMPR2|=7<<0 239.5="" p="">0>
ADC1->CR2|=1<<0 p="">0>
ADC1->CR2|=1<<3 p="">3>
while(ADC1->CR2&1<<3 p="">3>
//該位元由軟體設置並由硬體清除。在校準寄存器被初始化後該位將被清除。
ADC1->CR2|=1<<2 p="">2>
while(ADC1->CR2&1<<2 p="">2>
//該位元由軟體設置以開始校準,並在校準結束時由硬體清除
}
//獲得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{
//設置轉換序列
ADC1->SQR3&=0XFFFFF
ADC1->CR2|=1<<22 p="">22>
while(!(ADC1->SR&1<<1 p="">1>
return
ADC1->DR; //返回adc值
}
//。接下來在adc.h檔裡面輸入如下代碼:
#ifndef __ADC_H
#define __ADC_H
//Mini STM32開發板
//ADC 驅動代碼
//正點原子@ALIENTEK
#define ADC_CH0 0
//通道0
#define ADC_CH1 1
//通道1
#define ADC_CH2 2
//通道2
#define ADC_CH3 3
//通道3
void
Adc_Init(void);
u16 Get_Adc(u8 ch);
#endif
該部分代碼很簡單,這裡我們就不多說了,這裡定義的4個通道的巨集定義,我們在main函數將會用到ADC_CH0。
接下來我們在test.c裡面,修改main函數如下:
int main(void)
{
u16
adcx;
float
temp;
Stm32_Clock_Init(9);//系統時鐘設置
delay_init(72);
//延時初始化
uart_init(72,9600);
//串口1初始化
LED_Init();
LCD_Init();
Adc_Init();
POINT_COLOR=RED;//設置字體為紅色
POINT_COLOR=BLUE;//設置字體為藍色
LCD_ShowString(60,150,"ADC_CH0_VOL:0.000V");
while(1)
{
LCD_ShowNum(156,150,adcx,1,16);//顯示電壓值
temp-=adcx;
temp*=1000;
LCD_ShowNum(172,150,temp,3,16);
LED0=!LED0;
delay_ms(250);
}
}
沒有留言:
張貼留言