stm32 ADC模數轉換 ADC多通道 ADC DMA
通過調節電位器,改變AD轉換值和電壓值
STM32F1 ADC 配置步驟
1.使能GPIO時鐘和ADC時鐘
2.配置引腳模式為模擬輸入
3.配置ADC的分頻因子
4.初始化ADC引數,ADC_InitTypeDef
5.使能ADC
6.執行ADC校準
7.設定ADC軟體啟動
8.讀取ADC轉換值
9.設定ADC規則,取樣時間等
10.使能ADC的軟體轉換
11.讀取ADC轉換結果
舉例
u16 ADC_value(u8 time)
{
u8 i = 0;
u16 value;
for(i = 0; i < time; i++)
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC的軟體轉換
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != SET);
value += ADC_GetConversionValue(ADC1); //讀取ADC轉換結果
}
return value/time;
}
typedef struct
{
uint32_t ADC_Mode; //雙模式選擇
FunctionalState ADC_ScanConvMode; //掃描模式
FunctionalState ADC_ContinuousConvMode; //連續轉換
uint32_t ADC_ExternalTrigConv; //注入通道的外部觸發轉換模式
uint32_t ADC_DataAlign; //資料對齊
uint8_t ADC_NbrOfChannel; //規則通道序列長度
}ADC_InitTypeDef;
void ADC_init()
{
GPIO_InitTypeDef gpio =
{
GPIO_Pin_1,
GPIO_Speed_50MHz,
GPIO_Mode_AIN //模擬輸入
};
ADC_InitTypeDef adc =
{
ADC_Mode_Independent, //獨立模式
DISABLE, //關閉掃描模式
DISABLE, //單次轉換模式
ADC_ExternalTrigConv_None, //不用外部事件啟動轉換
ADC_DataAlign_Right, //右對齊
1, //通道數目1
};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); //使能GPIO時鐘和ADC時鐘
GPIO_Init(GPIOA, &gpio); //配置引腳模式
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //配置ADC的分頻因子 72/6=12(通常)
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5); //設定ADC規則,取樣週期
ADC_Init(ADC1, &adc); //初始化ADC引數
ADC_Cmd(ADC1, ENABLE); //使能ADC
ADC_ResetCalibration(ADC1); //執行ADC復位校準
while(ADC_GetResetCalibrationStatus(ADC1) == SET); //等待校準完成
ADC_StartCalibration(ADC1); //執行ADC校準
while(ADC_GetCalibrationStatus(ADC1) == SET);
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //ADC軟體啟動
}
int main(void)
{
ADC_init();
while(1)
{
adc = ADC_value(15); //15次平均值
printf("ADC_value is %d.\n", adc);
printf("vol is %.3fV.\n", adc * (3.3 / 4096)); //電壓值
delay_ms(500);
led1 = ~led1;
}
}
電壓計算
vol = ADC * (3.3 / 4096);
ADC的參考電壓VREF+為3.3V。ADC為12位轉換精度, 2^12為4096
DMA方式
ADC_DMACmd開啟DMA,在ADC初始化之後
ADC_RegularChannelConfig通道配置,在ADC初始化之後
DMA_MemoryInc要設定為DMA_MemoryInc_Enable,儲存器地址遞增
DMA_BufferSize大小,是定義DMA_MemoryBaseAddr記憶體的大小。根據DMA_MemoryDataSize儲存器資料寬度,HalfWord佔16bit
#define CHANNEL_NUM 4
volatile u16 AD_Bufer[4];
volatile u8 adc1_ok;
//多通道配置。4路輸入
void ADC_init()
{
...
ADC_InitTypeDef adc =
{
ADC_Mode_Independent, //獨立模式
ENABLE, //開啟掃描模式
ENABLE, //開啟連續轉換模式
ADC_ExternalTrigConv_None, //不用外部事件啟動轉換
ADC_DataAlign_Right, //右對齊
CHANNEL_NUM, //通道數目4
};
ADC_Init(ADC1, &adc);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_55Cycles5);
DMA_adc_init(ADC1, (u32)AD_Bufer, CHANNEL_NUM);
...
}
void DMA_adc_init(ADC_TypeDef *ADCx, u32 mem_addr, u32 size)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA控制器時鐘
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADCx->DR; //外設地址
DMA_InitStructure.DMA_MemoryBaseAddr = mem_addr; //記憶體地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = size; //4個快取大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //迴圈模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE); //開啟中斷
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_DMACmd(ADCx, ENABLE); //開啟ADC1 DMA採集
}
void DMA1_Channel1_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC1) != RESET)
{
DMA_ClearITPendingBit(DMA1_IT_TC1);
adc1_ok = 1;
}
}
int main(void)
{
ADC_init();
while(1)
{
if(adc1_ok == 1)
{
v0 = AD_Bufer[0];
v1 = AD_Bufer[1];
v2 = AD_Bufer[2];
v3 = AD_Bufer[3];
printf("v0 is %.3fV.\n", v0 * (3.3 / 4096)); //電壓值
printf("v1 is %.3fV.\n", v1 * (3.3 / 4096));
printf("v2 is %.3fV.\n", v2 * (3.3 / 4096));
printf("v3 is %.3fV.\n", v3 * (3.3 / 4096));
led1 = ~led1;
adc1_ok = 0;
}
delay_ms(500);
}
}
相關文章
- STM32-ADC模數轉換
- STM32ADC單通道轉換
- STM32CubeMX系列|ADC模數轉換
- STM32F407-ADC(模數轉換)
- STM32定時器觸發ADC多通道連續取樣,DMA快取結果定時器快取
- STM32 逐次逼近暫存器型(SAR)模擬數字轉換器(ADC)
- adc/dac
- 介紹,14位模數轉換器: AD9697BCPZRL7-1300單通道ADC,AD9695BCPZRL7-625 和 AD9695BCPZRL7-1300雙通道ADC
- stm32學習之ADC入門
- AD模數轉換(ADC)在音訊處理中的詳細深度講解音訊
- 記錄-cubemx配置STM32F334雙ADC+DMA同步規則轉換
- STM32 ADC詳細篇(基於HAL庫)
- STM32H723 ADC+DMA 誤差解決
- adc指令(Addition Carry)
- Luat例項教程:adc
- 【CC2530授課筆記】⑩ ADC 數模轉換,訊號採集,光敏電阻筆記
- Hi3518EV200平臺ADC多通道取樣流程
- ADC藥物平臺分析
- ST ADC取樣時間計算
- ADC and DAC Analog Filters for Data ConversionFilter
- sam9260 adc 標頭檔案
- Voltage Translation for Analog to Digital Interface ADCGit
- 模擬積體電路設計系列部落格——7.1.6 多位元SAR ADC
- 模擬積體電路設計系列部落格——7.5.2 週期型ADC
- 嵌入式作業6.2 ADC 程式設計程式設計
- STM32F4 timer定時器觸發ADC採集,DMA轉運資料 (標準庫)定時器
- 透過 adc 實現一個IO對多個按鍵讀取
- 模擬積體電路設計系列部落格——7.5.6 時間交錯型ADC
- 一種3位sar adc工作過程推導(二)
- 百奧賽圖與ADC Therapeutics簽署抗體協議協議
- 4G模組軟體的ADC示例 | 智慧演繹
- stm32f10x系列學習筆記(三)ADC筆記
- 模擬積體電路設計系列部落格——7.1.5 SAR ADC中的錯誤糾正
- 模擬積體電路設計系列部落格——7.4.1 過取樣ADC的基本介紹
- IR35217MTRPBF專用型電源管理晶片、ADS122C04IPWR 24位模數轉換器 (ADC)概述、應用晶片
- FPGA驅動adc128s052的幾個問題FPGA
- 【GMT43智慧液晶模組】例程八:ADC實驗——電源監控
- 【iCore3 雙核心板】例程九:ADC實驗——電源監控