华大HDL136X芯片adc用dma方式进行采样

 

        HDL136 adc采用dma方式来采样的方式和Stm32相差不多,但是目前使用下来,感觉华大芯片的adc软件触发比较鸡肋,每次启动之后只能进行一次转换,要进行持续的转换需要在adc转换完成中断之后再次启动adc转换。而stm32的adc软件触发之后就可以持续不断的进行转换,除非进行停止操作。

///< 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中断服务函数

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();

}

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值