welcom ! Handel home

2014年7月1日 星期二

ST32 ADC REG and Flag function List and Demo code 0

[基本功能:]
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


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
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="">
GPIOA->CRL&=0XFFFF0000;//PA0 1 2 3 anolog 輸入

//通道10/11設置
RCC->APB2ENR|=1<<9 p="">
RCC->APB2RSTR|=1<<9 p="">
RCC->APB2RSTR&=~(1<<9 p="">
RCC->CFGR&=~(3<<14 p="">

//SYSCLK/DIV2=12M ADC時鐘設置為12M,ADC最大時鐘不能超過14M!
//否則將導致ADC準確度下降!
RCC->CFGR|=2<<14 p="">
ADC1->CR1&=0XF0FFFF; //工作模式清零
ADC1->CR1|=0<<16 p="">
ADC1->CR1&=~(1<<8 p="">
ADC1->CR2&=~(1<<1 p="">
ADC1->CR2&=~(7<<17 p="">
ADC1->CR2|=7<<17 p="">
ADC1->CR2|=1<<20 p="">
ADC1->CR2&=~(1<<11 p="">
ADC1->SQR1&=~(0XF<<20 p="">
ADC1->SQR1&=0<<20 p="">

//設置通道0~3的採樣時間
ADC1->SMPR2&=0XFFFFF000;//通道0,1,2,3採樣時間清空
ADC1->SMPR2|=7<<9 239.5="" p="">
ADC1->SMPR2|=7<<6 239.5="" p="">
ADC1->SMPR2|=7<<3 239.5="" p="">
ADC1->SMPR2|=7<<0 239.5="" p="">
ADC1->CR2|=1<<0 p="">
ADC1->CR2|=1<<3 p="">
while(ADC1->CR2&1<<3 p="">
//該位元由軟體設置並由硬體清除。在校準寄存器被初始化後該位將被清除。
ADC1->CR2|=1<<2 p="">
while(ADC1->CR2&1<<2 p="">
//該位元由軟體設置以開始校準,並在校準結束時由硬體清除
}

//獲得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{
//設置轉換序列
ADC1->SQR3&=0XFFFFF
ADC1->CR2|=1<<22 p="">
while(!(ADC1->SR&1<<1 p="">
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);
}
}






























沒有留言: