HuadaHDL136Xチップadcはサンプリングにdmaを使用します

 

        HDL136 adcはStm32と同じ方法でdmaを使用してサンプリングしますが、現在使用している場合、Huadaチップのadcソフトウェアトリガーはまったく味がなく、起動するたびに1回の変換しか実行できないため、継続的な変換を行う必要があります。 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 / BGRGPIOペリフェラルクロックをオンにします

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は毎回1つのチャネルを変換するために24クロックを必要とし、adcのサンプリング周波数は1mspsです

// 10チャネルのADCデータの変換ごとに、各順次サンプリングには10usが必要です

stcAdcCfg.enAdcMode = AdcScanMode; /// <サンプリングモード-スキャン

stcAdcCfg.enAdcClkDiv = AdcMskClkDiv1; /// <サンプリング分割-1

stcAdcCfg.enAdcSampCycleSel = AdcMskSampCycle8Clk; /// <サンプリングサイクル数-8

stcAdcCfg.enAdcRefVolSel = AdcMskRefVolSelAVDD; /// <基準電圧の選択-VCC

stcAdcCfg.enAdcOpBuf = AdcMskBufDisable; /// <OPBUF構成-オフ

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ペリフェラルクロックゲーティングスイッチを有効にする

// rxdma構成

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つしかないため、転送は1回だけです。

stcDmaCfg.u16TransferCnt = 1;

stcDmaCfg.enMode = DmaMskBlock; //送信をブロックする

// 32ビットバイト送信、adcデータレジスタは32ビットであるため、32ビットに設定されます

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

}

 

おすすめ

転載: blog.csdn.net/zhuimeng_ruili/article/details/114198704