1. 程式人生 > >stm32 多通道ADC+DMA採集

stm32 多通道ADC+DMA採集

/*******************************************************************
** Variables Definitions **
*******************************************************************/
__IO uint16_t ADC_DMAValue[20][2];
GPIO_InitTypeDef GPIO_Init_ADC;           
ADC_InitTypeDef ADC1_InitStructure;        //ADC初始化結構體宣告
DMA_InitTypeDef DMA1_InitStructure;        //DMA初始化結構體宣告
NVIC_InitTypeDef NVIC_DMA1Structure; /******************************* 函式名稱:ADC_DMA_config 函式功能:ADC1與DMA1的聯合初始化 函式引數:uint32_t addr DMA1記憶體儲存地址 函式返回值:無 *********************************/ void ADC1_DMA1_config(uint32_t addr) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC時鐘
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE); //使能GPIOC時鐘 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE); //使能GPIOC時鐘 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA時鐘 RCC_ADCCLKConfig(RCC_ADCCLK_PCLK2_Div4); //ADC時鐘頻率 48/4=12MHZ ,不可以大於14MHZ
GPIO_Init_ADC.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_0; //管腳PB1 PB0 GPIO_Init_ADC.GPIO_Mode = GPIO_Mode_AN; //模擬輸入模式 GPIO_Init_ADC.GPIO_Speed = GPIO_Speed_Level_3; GPIO_Init_ADC.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_Init_ADC); //GPIOB初始化 /********************* ADC1初始化 ******************************/ ADC_DeInit(ADC1); ADC1_InitStructure.ADC_Mode = ADC_Mode_Independent; //獨立的轉換模式 ADC1_InitStructure.ADC_ScanConvMode = ENABLE; //開啟掃描模式 ADC1_InitStructure.ADC_ContinuousConvMode = ENABLE; //開啟連續轉換模式 ADC1_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //ADC外部開關,關閉狀態 ADC1_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //對齊方式,ADC為12位中,右對齊方式 ADC1_InitStructure.ADC_NbrOfChannel =2; //開啟通道數,2個 ADC_Init(ADC1, &ADC1_InitStructure); // ADC_ExternalTrigConvCmd(ADC1,ENABLE); ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5); //ADC通道組, 第8個通道 取樣順序1,轉換時間 239.5個週期 ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_239Cycles5); //ADC通道組, 第9個通道 取樣順序2,轉換時間 ADC_DMACmd(ADC1, ENABLE); //使能ADC與DMA的傳輸 ADC_Cmd(ADC1, ENABLE); //開啟ADC1 Delay_US(20); ADC_ResetCalibration(ADC1); //重新校準 while(ADC_GetResetCalibrationStatus(ADC1)); //等待重新校準完成 ADC_StartCalibration(ADC1); //開始校準 while(ADC_GetCalibrationStatus(ADC1)); //等待校準完成 /****************** DMA1初始化 *******************/ DMA_DeInit(DMA1_Channel1); //開啟DMA1的第一通道 DMA1_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)&ADC1->DR; //DMA對應的外設基地址 DMA1_InitStructure.DMA_MemoryBaseAddr =addr; //記憶體儲存基地址 DMA1_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA的轉換模式為SRC模式,由外設搬移到記憶體 DMA1_InitStructure.DMA_BufferSize =40; //DMA快取大小,20個 DMA1_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設地址遞增 DMA1_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //記憶體地址遞增 DMA1_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //定義外設資料寬度 DMA1_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //DMA搬移資料尺寸 DMA1_InitStructure.DMA_Mode = DMA_Mode_Circular; //轉換模式,迴圈快取模式。 DMA1_InitStructure.DMA_Priority = DMA_Priority_High; //DMA優先順序高 DMA1_InitStructure.DMA_M2M = DMA_M2M_Disable; //M2M模式禁用 DMA_Init(DMA1_Channel1, &DMA1_InitStructure); DMA_Cmd(DMA1_Channel1, ENABLE); DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); //DMA傳送中斷使能 NVIC_DMA1Structure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_DMA1Structure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_DMA1Structure.NVIC_IRQChannelSubPriority = 1; NVIC_DMA1Structure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_DMA1Structure); // Enable the DMA Interrupt } /*********************************************************** 函式名稱: Get_Adc 函式功能: 等待ADC1轉換完成 入口引數: void 出口引數: void ***********************************************************/ void Get_Adc() { ADC_RegularChannelConfig(ADC1,ADC_Channel_8,1, ADC_SampleTime_239Cycles5); //ADC通道組, 第8個通道 取樣順序1,轉換時間 239.5個週期 ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_239Cycles5); //ADC通道組, 第9個通道 取樣順序2,轉換時間 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //軟體規則組通道轉換使能 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC )); //等待轉換結束 } void bubbleSort(uint8_t column) //氣泡排序演算法,從大到小進行排序 { int i,j; int flag = 1; for(i=0;i<N&&flag;i++) { for(j=0;j<N-1-i;j++) { flag = 0; if(ADC_DMAValue[j][column]>ADC_DMAValue[j+1][column]) { uint16_t temp = ADC_DMAValue[j][column]; ADC_DMAValue[j][column] = ADC_DMAValue[j+1][column]; ADC_DMAValue[j+1][column] = temp; flag = 1; } } } } void filter() //均值濾波處理函式 { for(count=4;count<N-4;count++) //去掉較大的四個值和較小的四個值,再取其餘值的平均值 { ADC_Value1+=ADC_DMAValue[count][0]; ADC_Value2+=ADC_DMAValue[count][1]; } ADC_Value1=ADC_Value1/(N-8); ADC_Value2=ADC_Value2/(N-8); RxCounter=7; } 該程式由本樓主自己編寫,完成除錯,只要適當呼叫程式即可正常使用,有問題可評論,一起探討。。。