|
#include "adc.h"
#include "delay.h"
//初始化ADC1
//這里我們僅以規則通道為例
//我們默認僅開啟通道1
void Adc_Init(void)
{
//先初始化IO口
RCC->APB2ENR|=1<<2; //使能PORTA口時鐘
GPIOA->CRL&=0XFFFFFF0F;//PA1 anolog輸入
RCC->APB2ENR|=1<<9; //ADC1時鐘使能
RCC->APB2RSTR|=1<<9; //ADC1復位
RCC->APB2RSTR&=~(1<<9);//復位結束
RCC->CFGR&=~(3<<14); //分頻因子清零
//SYSCLK/DIV2=12M ADC時鐘設置為12M,ADC最大時鐘不能超過14M!
//否則將導致ADC準確度下降!
RCC->CFGR|=2<<14;
ADC1->CR1&=0XF0FFFF; //工作模式清零
ADC1->CR1|=0<<16; //獨立工作模式
ADC1->CR1&=~(1<<8); //非掃描模式
ADC1->CR2&=~(1<<1); //單次轉換模式
ADC1->CR2&=~(7<<17);
ADC1->CR2|=7<<17; //軟件控制轉換
ADC1->CR2|=1<<20; //使用用外部觸發(SWSTART)!!! 必須使用一個事件來觸發
ADC1->CR2&=~(1<<11); //右對齊
ADC1->SQR1&=~(0XF<<20);
ADC1->SQR1|=0<<20; //1個轉換在規則序列中 也就是只轉換規則序列1
//設置通道1的采樣時間
ADC1->SMPR2&=~(3*1); //通道1采樣時間清空
ADC1->SMPR2|=7<<(3*1); //通道1 239.5周期,提高采樣時間可以提高精確度
ADC1->CR2|=1<<0; //開啟AD轉換器
ADC1->CR2|=1<<3; //使能復位校準
while(ADC1->CR2&1<<3); //等待校準結束
//該位由軟件設置并由硬件清除。在校準寄存器被初始化后該位將被清除。
ADC1->CR2|=1<<2; //開啟AD校準
while(ADC1->CR2&1<<2); //等待校準結束
//該位由軟件設置以開始校準,并在校準結束時由硬件清除
}
//獲得ADC1某個通道的值
//ch:通道值 0~16
//返回值:轉換結果
u16 Get_Adc(u8 ch)
{
//設置轉換序列
ADC1->SQR3&=0XFFFFFFE0;//規則序列1 通道ch
ADC1->SQR3|=ch;
ADC1->CR2|=1<<22; //啟動規則轉換通道
while(!(ADC1->SR&1<<1));//等待轉換結束
return ADC1->DR; //返回adc值
}
//獲取通道ch的轉換值,取times次,然后平均
//ch:通道編號
//times:獲取次數
//返回值:通道ch的times次轉換結果平均值
u16 Get_Adc_Average(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_Adc(ch);
delay_ms(5);
}
return temp_val/times;
}
|
-
-
stm32 ADC實驗.zip
2019-10-4 16:12 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
217.1 KB, 下載次數: 7, 下載積分: 黑幣 -5
|