新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > STM32F10XXX 雙通道ADC數據采集,TIM2觸發(fā)采集

        STM32F10XXX 雙通道ADC數據采集,TIM2觸發(fā)采集

        作者: 時間:2016-11-17 來源:網絡 收藏
        /********** (C) COPYRIGHT 2007 STMicroelectronics ***********
        *STM32F10XXX 雙通道ADC數據采集
        *環(huán)境:keil for arm mdk 4.71a 官方V3.5庫
        *STM32數據采集部分
        * 1、ADC1/ADC2實現(xiàn)并行同時數據采集,12BIT最高可達1MSPS采樣速度并通過STM32的DMA傳輸放入內存中
        * 2、TIM2 CC2實現(xiàn)對ADC采樣的觸發(fā),ADC_Sample_Frequency_Set函數實現(xiàn)自定義TIM2 CC2頻率輸出,
        * 3、采樣的頻率和采樣個數通過接收到的UDP控制命令來指定
        * 采樣的頻率為20HZ~1MHZ;
        * 采樣深度為1~4000個數據(受限于STM32內存20KB容量,一個數據為2個12bitADC通道讀數,需一個word)
        *******************************************************************************/
        #define ADC1_DR_addr ((u32)0x4001244C) //AD轉換結果存放地址定義
        /*******************************************************************************
        * Function Name : DMA_ADC_Transfer_Reset
        * Description : ADC1/ADC2 DMA傳輸通道復位,準備下一次DMA傳輸
        * Input : None
        * Output : None
        * Return : None
        *******************************************************************************/
        void DMA_ADC_Transfer_Reset(void)
        {
        //開始DMA傳輸
        DMA_Channel1->CCR &= ~(1<<0); //禁用DMA_Channel,EN是CCR1寄存器的0位
        DMA->IFCR |= 0x0000000F;//清除CHANNEL1的4個標志
        DMA_Channel1->CNDTR = (u16)SampleDepth;//重新設置要設置的DMA傳輸數據量
        DMA_Channel1->CCR |= (1<<0);//重新使能DMA_channel1
        while(!(DMA->ISR & DMA_FLAG_TC1));
        DMA_Channel1->CCR &= ~(1<<0); //禁用DMA_Channel,EN是CCR1寄存器的0位
        }
        /*******************************************************************************
        * Function Name : DMA_ADC_Transfer_Init
        * Description : ADC1/ADC2 DMA傳輸通道初始化
        * Input : None
        * Output : None
        * Return : None
        *******************************************************************************/
        void DMA_ADC_Transfer_Init(void)
        {
        DMA_InitTypeDef DMA_InitStructure;
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
        /* DMA channel1 configuration ----------------------------------------------*/
        DMA_DeInit(DMA_Channel1);
        DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_DR_Address;//ADC數據寄存器地址
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&Data_Buffer[0];//目標緩沖區(qū)地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外設是源
        DMA_InitStructure.DMA_BufferSize = 0;//設置DMA讀取長度為
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設地址不遞增
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//目標緩沖區(qū)地址遞增
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//外設數據寬度
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//目標緩沖區(qū)數據寬度
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA模式:Circular循環(huán)模式/Normal普通模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//優(yōu)先級
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//內存到內存模式不使能
        DMA_Init(DMA_Channel1, &DMA_InitStructure);
        /* Enable DMA channel1 */
        //DMA_Cmd(DMA_Channel1, ENABLE);
        }
        /*******************************************************************************
        * Function Name : ADC_Initial
        * Description : ADC1/ADC2初始化
        *******************************************************************************/
        void ADC_Initial(void)
        {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB| RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC1, ENABLE ); //使能ADC通道時鐘
        ADC_InitTypeDef ADC_InitStructure;
        /* ADC1 configuration ------------------------------------------------------*/
        ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;//ADC1/ADC2同時并行采樣模式
        ADC_InitStructure.ADC_ScanConvMode = DISABLE;//多通道掃描模式
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//單次轉換模式(轉換后即停止)
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;//觸發(fā)模式
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//數據右對齊
        ADC_InitStructure.ADC_NbrOfChannel = 1;
        ADC_Init(ADC1 , &ADC_InitStructure);
        /* ADC1 regular channel14 configuration */
        ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_1Cycles5);
        /* Enable ADC1 DMA */
        ADC_DMACmd(ADC1, ENABLE);
        /* ADC2 configuration ---配置同ADC1--------------------------------------------*/
        ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
        ADC_InitStructure.ADC_ScanConvMode = DISABLE;
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
        ADC_InitStructure.ADC_NbrOfChannel = 1;
        ADC_Init(ADC2, &ADC_InitStructure);
        /* ADC2 regular channels configuration */
        ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_1Cycles5);
        /* Enable ADC2 external trigger conversion */
        ADC_ExternalTrigConvCmd(ADC2, ENABLE);
        /* Enable ADC1 */
        ADC_Cmd(ADC1, ENABLE);
        /* Enable ADC1 reset calibaration register 校準ADC1*/
        ADC_ResetCalibration(ADC1);
        /* Check the end of ADC1 reset calibration register */
        while(ADC_GetResetCalibrationStatus(ADC1));
        /* Start ADC1 calibaration */
        ADC_StartCalibration(ADC1);
        /* Check the end of ADC1 calibration */
        while(ADC_GetCalibrationStatus(ADC1));
        /* Enable ADC2 */
        ADC_Cmd(ADC2, ENABLE);
        /* Enable ADC2 reset calibaration register 校準ADC2*/
        ADC_ResetCalibration(ADC2);
        /* Check the end of ADC2 reset calibration register */
        while(ADC_GetResetCalibrationStatus(ADC2));
        /* Start ADC2 calibaration */
        ADC_StartCalibration(ADC2);
        /* Check the end of ADC2 calibration */
        while(ADC_GetCalibrationStatus(ADC2));
        /* Test on channel1 transfer complete flag */
        //while(!DMA_GetFlagStatus(DMA_FLAG_TC1));
        /* Clear channel1 transfer complete flag */
        //DMA_ClearFlag(DMA_FLAG_TC1);
        ADC_ExternalTrigConvCmd( ADC1, ENABLE);
        }
        /*******************************************************************************
        * Function Name : ADC_Sample_Frequency_Set
        * Description : 根據輸入的頻率設置,TIM2_CC2產生相應的頻率
        * 用來控制ADC的采樣,F(xiàn)requency=1000000/(Prescaler+1)來產生
        * 因此有些頻率計算不準確,一般頻率為2或5的倍數才準確
        * 頻率范圍為16Hz~1000,000Hz
        * Input : u16 Frequency:輸入所需要的采樣頻率
        *******************************************************************************/
        void ADC_Sample_Frequency_Set(u32 Frequency)
        {
        TIM_OCInitTypeDef TIM_OCInitStructure;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE );
        TIM_Cmd(TIM2, DISABLE);//先停止TIM2時鐘,以準備下面的設置
        /* -----------------------------------------------------------------------
        TIM2 配置: 產生TIM2_CC2時鐘控制信號用于控制ADC采樣
        TIM2CLK =72 MHz
        TIM2 ARR Register = 35 => TIM3 Frequency = (TIM3 counter clock/(ARR + 1))/2
        TIM2 Frequency = 1000 KHz.
        ----------------------------------------------------------------------- */
        /* Time base configuration */
        TIM_TimeBaseStructure.TIM_Period = 35; //APR寄存器
        TIM_TimeBaseStructure.TIM_Prescaler = 1000000/Frequency-1; //預分頻值,用來調整頻率,分頻系數=1000khz/(prescaler+1)
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
        /* TIM_OCMode_Toggle Mode configuration: Channel2 */
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1 ;//TIM_OCMode_Toggle,TIM_OCMode_PWM1
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period; //CCR2寄存器
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
        TIM_OC2Init(TIM2, &TIM_OCInitStructure);
        /* TIM使能 */
        TIM_Cmd(TIM2, ENABLE);
        /* TIM 輸出使能 */
        TIM_CtrlPWMOutputs(TIM2, ENABLE);
        }


        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 虹口区| 大冶市| 应城市| 绥德县| 榆林市| 鄄城县| 敦化市| 同德县| 武义县| 蒙山县| 凤山县| 城市| 库伦旗| 保德县| 卢湾区| 潍坊市| 宜黄县| 晋江市| 凉城县| 西乌珠穆沁旗| 上蔡县| 黄浦区| 逊克县| 珲春市| 城步| 忻城县| 安远县| 读书| 晋宁县| 淮北市| 铜川市| 涡阳县| 子洲县| 丰镇市| 齐河县| 永仁县| 岳普湖县| 新沂市| 乳山市| 株洲市| 琼结县|