锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

HC32F460之adc+dma使用

时间:2023-05-18 01:07:00 dd70f120三社二极管模块

ADC简介

???ADC 它是将模拟信号转换为数字信号的电路,为模数转换器。
???我现在用的ADC12位,12位ADC模拟量范围为2^12也就是4096,也就是说我的12位ADC模拟量的范围为0~4096.

具体实现

.h头文件编写

#include "hc32_ddl.h"  //Pin角定义 #define BOARD_ADC_CH0_PORT (PortC) #define BOARD_ADC_CH0_PIN (Pin03) #define BOARD_ADC_CH0_CH (ADC1_CH13)  #define BOARD_ADC_CH1_PORT (PortC) #define BOARD_ADC_CH1_PIN (Pin01) #define BOARD_ADC_CH1_CH (ADC1_CH11)  #define BOARD_ADC_CH2_PORT (PortC) #define BOARD_ADC_CH2_PIN (Pin02) #define BOARD_ADC_CH2_CH (ADC1_CH12)   extern void adc_init(void); extern uint16_t adc_value[3]; 

c文件编写

#include "bsp_adc.h" #include "bsp_irq.h"   #define ADC_CH_COUNT 3 //adc收集通道数量 uint16_t adc_value[3];  //存储采集数值buf  static void adc_pin_init(void); //ADC init pin static void AdcClockConfig(void); //ADC intit clk static void AdcInitConfig(void); //ADC initial configuration. static void AdcChannelConfig(void); //ADC channel configuration. static void AdcTriggerConfig(void); //ADC trigger source configuration. static void 
       
        adc_dma_config
        (
        void
        )
        ; 
        //ADC config DMA 
        void 
        adc_init
        (
        void
        ) 
        { 
          
        AdcInitConfig
        (
        )
        ; 
        adc_pin_init
        (
        )
        ; 
        AdcChannelConfig
        (
        )
        ; 
        AdcTriggerConfig
        (
        )
        ; 
        adc_dma_config
        (
        )
        ; 
        ADC_StartConvert
        (M4_ADC1
        )
        ; 
        } 
        static 
        void 
        adc_pin_init
        (
        void
        ) 
        { 
          stc_port_init_t stcPortInit
        ; 
        MEM_ZERO_STRUCT
        (stcPortInit
        )
        ; stcPortInit
        .enPullUp 
        = Disable
        ; stcPortInit
        .enPinMode 
        = Pin_Mode_Ana
        ; 
        PORT_Init
        (BOARD_ADC_CH0_PORT
        , BOARD_ADC_CH0_PIN
        , 
        &stcPortInit
        )
        ; 
        PORT_Init
        (BOARD_ADC_CH1_PORT
        , BOARD_ADC_CH1_PIN
        , 
        &stcPortInit
        )
        ; 
        PORT_Init
        (BOARD_ADC_CH2_PORT
        , BOARD_ADC_CH2_PIN
        , 
        &stcPortInit
        )
        ; 
        } 
        /** ******************************************************************************* ** \brief ADC clock configuration. ** ** \note 1) ADCLK max frequency is 60MHz. ** 2) If PCLK2 and PCLK4 are selected as the ADC clock, ** the following conditions must be met: ** a. ADCLK(PCLK2) max 60MHz; ** b. PCLK4 : ADCLK = 1:1, 2:1, 4:1, 8:1, 1:2, 1:4 ** ******************************************************************************/ 
        static 
        void 
        AdcClockConfig
        (
        void
        ) 
        { 
          
        #if (ADC_CLK == ADC_CLK_PCLK) stc_clk_sysclk_cfg_t stcSysclkCfg
        ; 
        /* Set bus clock division, depends on the system clock frequency. */ stcSysclkCfg
        .enHclkDiv 
        = ClkSysclkDiv1
        ; 
        // 168MHz stcSysclkCfg
        .enExclkDiv 
        = ClkSysclkDiv2
        ; 
        // 84MHz stcSysclkCfg
        .enPclk0Div 
        = ClkSysclkDiv1
        ; 
        // 168MHz stcSysclkCfg
        .enPclk1Div 
        = ClkSysclkDiv2
        ; 
        // 84MHz stcSysclkCfg
        .enPclk2Div 
        = ClkSysclkDiv4
        ; 
        // 42MHz stcSysclkCfg
        .enPclk3Div 
        = ClkSysclkDiv4
        ; 
        // 42MHz stcSysclkCfg
        .enPclk4Div 
        = ClkSysclkDiv1
        ; 
        // 84MHz. 
        CLK_SysClkConfig
        (
        &stcSysclkCfg
        )
        ; 
        CLK_SetPeriClkSource
        (ClkPeriSrcPclk
        )
        ; 
        #elif (ADC_CLK == ADC_CLK_MPLLQ) stc_clk_xtal_cfg_t stcXtalCfg
        ; stc_clk_mpll_cfg_t stcMpllCfg
        ; 
        if 
        (CLKSysSrcMPLL 
        == 
        CLK_GetSysClkSource
        (
        )
        ) 
        { 
          
        /* * Configure MPLLQ(same as MPLLP and MPLLR) when you * configure MPLL as the system clock. */ 
        } 
        else 
        { 
          
        /* Use XTAL as MPLL source. */ stcXtalCfg
        .enFastStartup 
        = Enable
        ; stcXtalCfg
        .enMode 
        = ClkXtalModeOsc
        ; stcXtalCfg
        .enDrv 
        = ClkXtalLowDrv
        ; 
        CLK_XtalConfig
        (
        &stcXtalCfg
        )
        ; 
        CLK_XtalCmd
        (Enable
        )
        ; 
        /* Set MPLL out 240MHz. */ stcMpllCfg
        .pllmDiv 
        = 
        1u
        ; 
        /* mpll = 8M / pllmDiv * plln */ stcMpllCfg
        .plln 
        = 
        30u
        ; stcMpllCfg
        .PllpDiv 
        = 
        16u
        ; stcMpllCfg
        .PllqDiv 
        = 
        16u
        ; stcMpllCfg
        .PllrDiv 
        = 
        16u
        ; 
        CLK_SetPllSource
        (ClkPllSrcXTAL
        )
        ; 
        CLK_MpllConfig
        (
        &stcMpllCfg
        )
        ; 
        CLK_MpllCmd
        (Enable
        )
        ; 
        } 
        CLK_SetPeriClkSource
        (ClkPeriSrcMpllp
        )
        ; 
        #elif (ADC_CLK == ADC_CLK_UPLLR) stc_clk_xtal_cfg_t stcXtalCfg
        ; stc_clk_upll_cfg_t stcUpllCfg
        ; 
        MEM_ZERO_STRUCT
        (stcXtalCfg
        )
        ; 
        MEM_ZERO_STRUCT
        (stcUpllCfg
        )
        ; 
        /* Use XTAL as UPLL source. */ stcXtalCfg
        .enFastStartup 
        = Enable
        ; stcXtalCfg
        .enMode 
        = ClkXtalModeOsc
        ; stcXtalCfg
        .enDrv 
        = ClkXtalLowDrv
        ; 
        CLK_XtalConfig
        (
        &stcXtalCfg
        )
        ; 
        CLK_XtalCmd
        (Enable
        )
        ; 
        /* Set UPLL out 240MHz. */ stcUpllCfg
        .pllmDiv 
        = 
        2u
        ; 
        /* upll = 8M(XTAL) / pllmDiv * plln */ stcUpllCfg
        .plln 
        = 
        60u
        ; stcUpllCfg
        .PllpDiv 
        = 
        16u
        ; stcUpllCfg
        .PllqDiv 
        = 
        16u
        ; stcUpllCfg
        .PllrDiv 
        = 
        16u
        ; 
        CLK_SetPllSource
        (ClkPllSrcXTAL
        )
        ; 
        CLK_UpllConfig
        (
        &stcUpllCfg
        )
        ; 
        CLK_UpllCmd
        (Enable
        )
        ; 
        CLK_SetPeriClkSource
        (ClkPeriSrcUpllr
        )
        ; 
        #endif 
        } 
        /** ******************************************************************************* ** \brief ADC initial configuration. ** ******************************************************************************/ 
        static 
        void 
        AdcInitConfig
        (
        void
        ) 
        { 
          stc_adc_init_t stcAdcInit
        ; 
        MEM_ZERO_STRUCT
        (stcAdcInit
        )
        ; stcAdcInit
        .enResolution 
        = AdcResolution_12Bit
        ; stcAdcInit
        .enDataAlign 
        = AdcDataAlign_Right
        ; stcAdcInit
        .enAutoClear 
        = AdcClren_Enable
        ; stcAdcInit
        .enScanMode 
        = AdcMode_SAContinuous
        ; stcAdcInit
        .enRschsel 
        = AdcRschsel_Restart
        ; 
        /* 1. Enable ADC1. */ 
        PWC_Fcg3PeriphClockCmd
        (PWC_FCG3_PERIPH_ADC1
        , Enable
        )
        ; 
        /* 2. Initialize ADC1. */ 
        ADC_Init
        (M4_ADC1
        , 
        &stcAdcInit
        )
        ; 
        } 
        /** ******************************************************************************* ** \brief ADC channel configuration. ** ******************************************************************************/ 
        static 
        void 
        AdcChannelConfig
        (
        void
        ) 
        { 
          stc_adc_ch_cfg_t stcChCfg
        ; uint8_t au8Adc1SaSampTime
        [
        3
        ] 
        = 
        { 
          
        0x60
        , 
        0x60
        , 
        0x60 
        }
        ; 
        MEM_ZERO_STRUCT
        (stcChCfg
        )
        ; stcChCfg
        .u32Channel 
        = BOARD_ADC_CH0_CH 
        | BOARD_ADC_CH1_CH 
        | BOARD_ADC_CH2_CH
        ; stcChCfg
        .u8Sequence 
        = ADC_SEQ_A
        ; stcChCfg
        .pu8SampTime 
        = au8Adc1SaSampTime
        ; 
        ADC_AddAdcChannel
        (M4_ADC1
        , 
        &stcChCfg
        )
        ; 
        // ADC_ConfigAvg(M4_ADC1, AdcAvcnt_64); 
        // ADC_AddAvgChannel(M4_ADC1, BOARD_ADC_CH0_CH | BOARD_ADC_CH1_CH | BOARD_ADC_CH2_CH); 
        } 
        /** ******************************************************************************* ** \brief ADC trigger source configuration. ** ******************************************************************************/ 
        static 
        void 
        AdcTriggerConfig
        (
        void
        ) 
        { 
          stc_adc_trg_cfg_t stcTrgCfg
        ; 
        MEM_ZERO_STRUCT
        (stcTrgCfg
        )
        ; 
        /* * If select an event(@ref en_event_src_t) to trigger ADC, * AOS must be enabled first. */ 
        PWC_Fcg0PeriphClockCmd
        (PWC_FCG0_PERIPH_AOS
        , Enable
        )
        ; 
        /* ADC1 sequence A will be started by software. */ 
        ADC_TriggerSrcCmd
        (M4_ADC1
        , ADC_SEQ_A
        , Disable
        )
        ; 
        } 
        /** ******************************************************************************* ** \brief Config the pin which is mapping the channel to analog or digit mode. ** ******************************************************************************/ 
        static 
        void 
        AdcSetChannelPinMode
        (
        const M4_ADC_TypeDef 
        *ADCx
        , uint32_t u32Channel
        , en_pin_mode_t enMode
        ) 
        { 
          uint8_t u8ChIndex
        ; 
        #if (ADC_CH_REMAP) uint8_t u8AdcPin
        ; 
        #else uint8_t u8ChOffset 
        = 
        0u
        ; 
        #endif 
        if 
        (M4_ADC1 
        == ADCx
        ) 
        { 
          u32Channel 
        &
        = ADC1_PIN_MASK_ALL
        ; 
        } 
        else 
        { 
          u32Channel 
        &
        = ADC2_PIN_MASK_ALL
        ; 
        #if (!ADC_CH_REMAP) u8ChOffset 
        = 
        4u
        ; 
        #endif 
        } u8ChIndex 
        = 
        0u
        ; 
        while 
        (
        0u 
        != u32Channel
        ) 
        { 
          
        if 
        (u32Channel 
        & 
        0x1ul
        ) 
        { 
          
        #if (ADC_CH_REMAP) u8AdcPin 
        = 
        ADC_GetChannelPinNum
        (ADCx
        , u8ChIndex
        )
        ; 
        AdcSetPinMode
        (u8AdcPin
        , enMode
        )
        ; 
        #else 
        AdcSetPinMode
        (
        (u8ChIndex 
        + u8ChOffset
        )
        , enMode
        )
        ; 
        #endif 
        } u32Channel 
        >>= 
        1u
        ; u8ChIndex
        ++
        ; 
        } 
        } 
        /** ******************************************************************************* ** \brief Set an ADC pin as analog input mode or digit mode. ** ******************************************************************************/ 
        static 
        void 
        AdcSetPinMode
        (uint8_t u8AdcPin
        , en_pin_mode_t enMode
        ) 
        { 
          en_port_t enPort 
        = PortA
        ; en_pin_t enPin 
        = Pin00
        ; bool bFlag 
        = true
        ; stc_port_init_t stcPortInit
        ; 
        MEM_ZERO_STRUCT
        (stcPortInit
        )
        ; stcPortInit
        .enPinMode 
        = enMode
        ; stcPortInit
        .enPullUp 
        = Disable
        ; 
        switch 
        (u8AdcPin
        ) 
        { 
          
        case ADC1_IN0
        : enPort 
        = PortA
        ; enPin 
        = Pin00
        ; 
        break
        ; 
        case ADC1_IN1
        : enPort 
        = PortA
        ; enPin 
        = Pin01
        ; 
        break
        ; 
        case ADC1_IN2
        : enPort 
        = PortA
        ; enPin 
        = Pin02
        ; 
        break
        ; 
        case ADC1_IN3
        : enPort 
        = PortA
        ; enPin 
        = Pin03
        ; 
        break
        ; 
        case ADC12_IN4
        : enPort 
        = PortA
        ; enPin 
        = Pin04
        ; 
        break
        ; 
        case ADC12_IN5
        : enPort 
        = PortA
        ; enPin 
        = Pin05
        ; 
        break
        ; 
        case ADC12_IN6
        : enPort 
        = PortA
        ; enPin 
        = Pin06
        ; 
        break
        ; 
        case ADC12_IN7
        : enPort 
        = PortA
        ; enPin 
        = Pin07
        ; 
        break
        ; 
        case ADC12_IN8
        : enPort 
        = PortB
        ; enPin 
        = Pin00
        ; 
        break
        ; 
        case ADC12_IN9
        : enPort 
        = PortB
        ; enPin 
        = Pin01
        ; 
        break
        ; 
        case ADC12_IN10
        : enPort 
        = PortC
        ; enPin 
        = Pin00
        ; 
        break
        ; 
        case ADC12_IN11
        : enPort 
        = PortC
        ; enPin 
        = Pin01
        ; 
        break
        ; 
        case ADC1_IN12
        : enPort 
        = PortC
        ; enPin 
        = Pin02
        ; 
        break
        ; 
        case ADC1_IN13
        : enPort 
        = PortC
        ; enPin 
        = Pin03
        ; 
        break
        ; 
        case ADC1_IN14
        : enPort 
        = PortC
        ; enPin 
        = Pin04
        ; 
        break
        ; 
        case ADC1_IN15
        : enPort 
        = PortC
        ; enPin 
        = Pin05
        ; 
        break
        ; 
        default
        : bFlag 
        = false
        ; 
        break
        ; 
        } 
        if 
        (true 
        == bFlag
        ) 
        { 
          
        PORT_Init
        (enPort
        , enPin
        , 
        &stcPortInit
        )
        ; 
        } 
        } 
        // DMA2 CH0 ~ CH2 
        static 
        void 
        adc_dma_config
        (
        void
        ) 
        { 
          stc_dma_config_t stcDmaCfg
        ; 
        MEM_ZERO_STRUCT
        (stcDmaCfg
        )
        ; stcDmaCfg
        .u16BlockSize 
        = ADC_CH_COUNT
        ; stcDmaCfg
        .u16TransferCnt 
        = 
        0u
        ; stcDmaCfg
        .u32SrcAddr 
        = 
        (uint32_t
        )
        (
        &M4_ADC1
        ->DR11
        )
        ; stcDmaCfg
        .u32DesAddr 
        = 
        (uint32_t
        )
        (
        &adc_value
        [
        0
        ]
        )
        ; stcDmaCfg
        .u16DesRptSize 
        = ADC_CH_COUNT
        ; stcDmaCfg
        .u16SrcRptSize 
        = ADC_CH_COUNT
        ; stcDmaCfg
        .u32DmaLlp 
        = 
        0u
        ; stcDmaCfg
        .stcSrcNseqCfg
        .u16Cnt 
        = 
        0u
        ; stcDmaCfg
        .stcSrcNseqCfg
        .u32Offset 
        = 
        0u
        ; stcDmaCfg
        .stcDesNseqCfg
        .u16Cnt 
        = 
        0u
        ; stcDmaCfg
        .stcDesNseqCfg
        .u32Offset 
        = 
        0u
        ; stcDmaCfg
        .stcDmaChCfg
        .enSrcInc 
        = AddressIncrease
        ; stcDmaCfg
        .stcDmaChCfg
        .enDesInc 
        = AddressIncrease
        ; stcDmaCfg
        .stcDmaChCfg
        .enSrcRptEn 
        = Enable
        ; stcDmaCfg
        .stcDmaChCfg
        .enDesRptEn 
        = Enable
        ; stcDmaCfg
        .stcDmaChCfg
        .enSrcNseqEn 
        = Disable
        ; stcDmaCfg
        .stcDmaChCfg
        .enDesNseqEn 
        = Disable
        ; stcDmaCfg
        .stcDmaChCfg
        .enTrnWidth 
        = Dma16Bit
        ; stcDmaCfg
        .stcDmaChCfg
        .enLlpEn 
        = Disable
        ; stcDmaCfg
        .stcDmaChCfg
        .enIntEn 
        = Disable
        ; 
        PWC_Fcg0PeriphClockCmd
        (PWC_FCG0_PERIPH_DMA2
        , Enable
        )
        ; 
        DMA_InitChannel
        (M4_DMA2
        , DmaCh3
        , 
        &stcDmaCfg
        )
        ; 
        DMA_Cmd
        (M4_DMA2
        , Enable
        )
        ; 
        DMA_ChannelCmd
        (M4_DMA2
        , DmaCh3
        , Enable
        )
        ; 
        DMA_ClearIrqFlag
        (M4_DMA2
        , DmaCh3
        , TrnCpltIrq
        )
        ; 
        /* AOS must be enabled to use DMA */ 
        /* AOS enabled at first. */ 
        /* If you have enabled AOS before, then the following statement is not needed. */ 
        PWC_Fcg0PeriphClockCmd
        (PWC_FCG0_PERIPH_AOS
        , Enable
        )
        ; 
        DMA_SetTriggerSrc
        (M4_DMA2
        , DmaCh3
        , EVT_ADC1_EOCA
        )
        ; 
        } 
       

具体使用

int main()
{ 
        
   // ..... //init other config
	adc_init(); //init adc
	
	while(1)
	{ 
        
		//deal adc value (adc_value)
	}
}
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章