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