Huada HDL136X chip adc uses dma for sampling

 

        HDL136 adc uses dma to sample in the same way as Stm32, but when used at present, it feels that the adc software triggering of the Huada chip is quite tasteless, and only one conversion can be performed after each startup. Continuous conversion needs to be completed in adc After the interruption, start the adc conversion again. After the stm32 adc software is triggered, the conversion can be continuously performed, unless the stop operation is performed.

///< ADC中断服务函数
void ADC_IRQHandler(void)
{    
    //大概10us进入一次中断
    if(TRUE == Adc_GetIrqStatus(AdcMskIrqSqr))
    {
        Adc_ClrIrqStatus(AdcMskIrqSqr);
        //进入中断之后,再次开启adc转换
        Adc_SQR_Start();
    }
}

///< ADC采样端口初始化
static void Adc_Gpio_Config(void)
{    
    ///< 开启ADC/BGR GPIO外设时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
    
    Gpio_SetAnalogMode(GpioPortA, GpioPin0);        //PA00 (AIN0)
    Gpio_SetAnalogMode(GpioPortA, GpioPin1);        //PA01 (AIN1)
    Gpio_SetAnalogMode(GpioPortA, GpioPin2);        //PA02 (AIN2)
    Gpio_SetAnalogMode(GpioPortA, GpioPin3);        //PA03 (AIN3)
    Gpio_SetAnalogMode(GpioPortA, GpioPin4);        //PA04 (AIN4)
    Gpio_SetAnalogMode(GpioPortA, GpioPin5);        //PA05 (AIN5)
    Gpio_SetAnalogMode(GpioPortA, GpioPin6);        //PA06 (AIN6)
    Gpio_SetAnalogMode(GpioPortA, GpioPin7);        //PA07 (AIN7)
    Gpio_SetAnalogMode(GpioPortB, GpioPin0);        //PB00 (AIN8)
    Gpio_SetAnalogMode(GpioPortB, GpioPin1);        //PB01 (AIN9)
}

///< ADC模块初始化
static void Adc_Config(void)
{
    stc_adc_cfg_t              stcAdcCfg;
    stc_adc_sqr_cfg_t          stcAdcSqrCfg;

    DDL_ZERO_STRUCT(stcAdcCfg);
    Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE); 
    Bgr_BgrEnable();        ///< 开启BGR
    ///< ADC 初始化配置
    //adc每次转换单个通道需要24个时钟,adc采样频率是1m sps
    //每次转换10个通道的adc数据,则每次顺序采样需要10个us
    stcAdcCfg.enAdcMode         = AdcScanMode;              ///<采样模式-扫描
    stcAdcCfg.enAdcClkDiv       = AdcMskClkDiv1;            ///<采样分频-1
    stcAdcCfg.enAdcSampCycleSel = AdcMskSampCycle8Clk;      ///<采样周期数-8
    stcAdcCfg.enAdcRefVolSel    = AdcMskRefVolSelAVDD;      ///<参考电压选择-VCC
    stcAdcCfg.enAdcOpBuf        = AdcMskBufDisable;         ///<OP BUF配置-关
    stcAdcCfg.enInRef           = AdcMskInRefDisable;       ///<内部参考电压使能-关
    stcAdcCfg.enAdcAlign        = AdcAlignRight;            ///<转换结果对齐方式-右
    Adc_Init(&stcAdcCfg);

    
    DDL_ZERO_STRUCT(stcAdcSqrCfg);
        
    ///< 顺序扫描模式功能及通道配置
    ///< 注意:扫描模式下,当配置转换次数为n时,转换通道的配置范围必须为[SQRCH(0)MUX,SQRCH(n-1)MUX]
    //转换完成后触发dma
    stcAdcSqrCfg.bSqrDmaTrig = TRUE;
    stcAdcSqrCfg.enResultAcc = AdcResultAccDisable;
    stcAdcSqrCfg.u8SqrCnt    = 10;
    Adc_SqrModeCfg(&stcAdcSqrCfg);

    Adc_CfgSqrChannel(AdcSQRCH0MUX, AdcExInputCH0);
    Adc_CfgSqrChannel(AdcSQRCH1MUX, AdcExInputCH1);
    Adc_CfgSqrChannel(AdcSQRCH2MUX, AdcExInputCH2);
    Adc_CfgSqrChannel(AdcSQRCH3MUX, AdcExInputCH3);
    Adc_CfgSqrChannel(AdcSQRCH4MUX, AdcExInputCH4);
    Adc_CfgSqrChannel(AdcSQRCH5MUX, AdcExInputCH5);
    Adc_CfgSqrChannel(AdcSQRCH6MUX, AdcExInputCH6);
    Adc_CfgSqrChannel(AdcSQRCH7MUX, AdcExInputCH7);
    Adc_CfgSqrChannel(AdcSQRCH8MUX, AdcExInputCH8);
    Adc_CfgSqrChannel(AdcSQRCH9MUX, AdcExInputCH9);
 
    
    ///< ADC 中断使能
    Adc_EnableIrq();
    
    EnableNvic(ADC_IRQn, IrqLevel3, TRUE);
    
    ///< 启动顺序扫描采样
    Adc_SQR_Start();
    
}

//DMA参数配置
static void Dma_Config(void)
{
    stc_dma_cfg_t stcDmaCfg;
    
    DDL_ZERO_STRUCT(stcDmaCfg);                                //初始化变量

    Sysctrl_SetPeripheralGate(SysctrlPeripheralDma,TRUE);      //使能DMAC外设时钟门控开关
    
    //rx dma配置
    stcDmaCfg.u32SrcAddress = 0x40002450;                      //源地址
    stcDmaCfg.u32DstAddress = (uint32_t)ADC_DATA.Conversion_Value;       //目标地址
    stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadEnable;  //使能DMA源地址重载
    stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadEnable;     //使能BC[3:0]和CONFA:TC[15:0]的重载功能
    stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadEnable; //使能DMA目的地址重载
    stcDmaCfg.enTransferMode = DmaMskContinuousTransfer;       //连续传输,DMAC传输完成时不清除CONFA:ENS位
    stcDmaCfg.enDstAddrMode = DmaMskDstAddrInc;                //目的地址自增
    stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrInc;                //源地址自增
    //块传输个数,一共转换10个通道,所以设置为9个
    stcDmaCfg.u16BlockSize = 10; 
    //块传输次数,只有1个块,所以只传输一次
    stcDmaCfg.u16TransferCnt = 1;                              
    stcDmaCfg.enMode = DmaMskBlock;                            //块(Block)传输
    // 32 bit  字节传输,因为adc数据寄存器为32位,所以设置为32bit
    stcDmaCfg.enTransferWidth = DmaMsk32Bit;                    
    stcDmaCfg.enRequestNum = DmaADCSQRTrig;                   //DMA硬件触发源位Uart1Rx
    stcDmaCfg.enPriority = DmaMskPriorityFix;                  //DMA 各通道优先级固定 (CH0>CH1)
    
    Dma_Enable();                                              //DMA模块使能
    Dma_InitChannel(DmaCh0, &stcDmaCfg);                       //DMA通道0初始化
    Dma_EnableChannel(DmaCh0);                                 //使能通道1
    
}

void ADC_Init(void)
{
    Adc_Gpio_Config();
    Adc_Config();
    Dma_Config();
    
}

///< ADC interrupt service function

void ADC_IRQHandler(void)

{

//About 10us enters an interrupt

if(TRUE == Adc_GetIrqStatus(AdcMskIrqSqr))

{

Adc_ClrIrqStatus(AdcMskIrqSqr);

//After entering the interrupt, turn on the adc conversion again

Adc_SQR_Start();

}

}

///< ADC sampling port initialization

static void Adc_Gpio_Config(void)

{

///< Turn on ADC/BGR GPIO peripheral clock

Sysctrl_SetPeripheralGate (SysctrlPeripheralGpio, TRUE);

Gpio_SetAnalogMode (GpioPortA, GpioPin0); // PA00 (AIN0)

Gpio_SetAnalogMode (GpioPortA, GpioPin1); // PA01 (AIN1)

Gpio_SetAnalogMode (GpioPortA, GpioPin2); // PA02 (AIN2)

Gpio_SetAnalogMode (GpioPortA, GpioPin3); // PA03 (AIN3)

Gpio_SetAnalogMode (GpioPortA, GpioPin4); // PA04 (AIN4)

Gpio_SetAnalogMode (GpioPortA, GpioPin5); // PA05 (AIN5)

Gpio_SetAnalogMode (GpioPortA, GpioPin6); // PA06 (AIN6)

Gpio_SetAnalogMode (GpioPortA, GpioPin7); // PA07 (AIN7)

Gpio_SetAnalogMode (GpioPortB, GpioPin0); // PB00 (AIN8)

Gpio_SetAnalogMode (GpioPortB, GpioPin1); // PB01 (AIN9)

}

 

///< ADC module initialization

static void Adc_Config(void)

{

stc_adc_cfg_t stcAdcCfg;

stc_adc_sqr_cfg_t stcAdcSqrCfg;

 

DDL_ZERO_STRUCT(stcAdcCfg);

Sysctrl_SetPeripheralGate (SysctrlPeripheralAdcBgr, TRUE);

Bgr_BgrEnable(); ///< Turn on BGR

///< ADC initialization configuration

//Adc needs 24 clocks to convert a single channel each time, and the sampling frequency of adc is 1m sps

//Each conversion of 10 channels of adc data, each sequential sampling requires 10 us

stcAdcCfg.enAdcMode = AdcScanMode; ///<Sampling mode-scan

stcAdcCfg.enAdcClkDiv = AdcMskClkDiv1; ///<Sampling division -1

stcAdcCfg.enAdcSampCycleSel = AdcMskSampCycle8Clk; ///<Number of sampling cycles-8

stcAdcCfg.enAdcRefVolSel = AdcMskRefVolSelAVDD; ///<reference voltage selection-VCC

stcAdcCfg.enAdcOpBuf = AdcMskBufDisable; ///<OP BUF configuration-off

stcAdcCfg.enInRef = AdcMskInRefDisable; ///<Internal reference voltage enable-off

stcAdcCfg.enAdcAlign = AdcAlignRight; ///<Conversion result alignment-right

Adc_Init(&stcAdcCfg);

 

DDL_ZERO_STRUCT(stcAdcSqrCfg);

///< Sequential scan mode function and channel configuration

///< Note: In scan mode, when the configuration conversion times is n, the configuration range of the conversion channel must be [SQRCH(0)MUX,SQRCH(n-1)MUX]

//Trigger dma after the conversion is completed

stcAdcSqrCfg.bSqrDmaTrig = TRUE;

stcAdcSqrCfg.enResultAcc = AdcResultAccDisable;

stcAdcSqrCfg.u8SqrCnt = 10;

Adc_SqrModeCfg(&stcAdcSqrCfg);

 

Adc_CfgSqrChannel(AdcSQRCH0MUX, AdcExInputCH0);

Adc_CfgSqrChannel(AdcSQRCH1MUX, AdcExInputCH1);

Adc_CfgSqrChannel(AdcSQRCH2MUX, AdcExInputCH2);

Adc_CfgSqrChannel(AdcSQRCH3MUX, AdcExInputCH3);

Adc_CfgSqrChannel(AdcSQRCH4MUX, AdcExInputCH4);

Adc_CfgSqrChannel(AdcSQRCH5MUX, AdcExInputCH5);

Adc_CfgSqrChannel(AdcSQRCH6MUX, AdcExInputCH6);

Adc_CfgSqrChannel(AdcSQRCH7MUX, AdcExInputCH7);

Adc_CfgSqrChannel(AdcSQRCH8MUX, AdcExInputCH8);

Adc_CfgSqrChannel(AdcSQRCH9MUX, AdcExInputCH9);

///< ADC interrupt enable

Adc_EnableIrq();

EnableNvic(ADC_IRQn, IrqLevel3, TRUE);

///< Start sequential scan sampling

Adc_SQR_Start();

}

 

//DMA parameter configuration

static void Dma_Config(void)

{

stc_dma_cfg_t stcDmaCfg;

DDL_ZERO_STRUCT(stcDmaCfg); //Initialize variables

 

Sysctrl_SetPeripheralGate(SysctrlPeripheralDma,TRUE); //Enable DMAC peripheral clock gating switch

//rx dma configuration

stcDmaCfg.u32SrcAddress = 0x40002450; //Source address

stcDmaCfg.u32DstAddress = (uint32_t)ADC_DATA.Conversion_Value; //Target address

stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadEnable; //Enable DMA source address reload

stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadEnable; //Enable the reload function of BC[3:0] and CONFA:TC[15:0]

stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadEnable; //Enable DMA destination address reload

stcDmaCfg.enTransferMode = DmaMskContinuousTransfer; //Continuous transfer, the CONFA:ENS bit is not cleared when the DMAC transfer is completed

stcDmaCfg.enDstAddrMode = DmaMskDstAddrInc; //Destination address self-increment

stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrInc; //source address self-increment

//The number of block transfers, a total of 10 channels are converted, so it is set to 9

stcDmaCfg.u16BlockSize = 10;

//The number of block transfers, there is only 1 block, so only transfer once

stcDmaCfg.u16TransferCnt = 1;

stcDmaCfg.enMode = DmaMskBlock; //Block transmission

// 32 bit byte transmission, because the adc data register is 32 bits, it is set to 32bit

stcDmaCfg.enTransferWidth = DmaMsk32Bit;

stcDmaCfg.enRequestNum = DmaADCSQRTrig; //DMA hardware trigger source bit Uart1Rx

stcDmaCfg.enPriority = DmaMskPriorityFix; //The priority of each DMA channel is fixed (CH0>CH1)

Dma_Enable(); //DMA module enable

Dma_InitChannel(DmaCh0, &stcDmaCfg); //DMA channel 0 initialization

Dma_EnableChannel(DmaCh0); //Enable channel 1

}

 

void ADC_Init(void)

{

Adc_Gpio_Config();

Adc_Config();

Dma_Config();

}

 

Guess you like

Origin blog.csdn.net/zhuimeng_ruili/article/details/114198704