longor 发表于 2022-6-2 18:24:35

FM33L0系列adc通过ATIM触发怎么设置

代码如下所示,配置了atim为200ms中断一次,adc初始化如下,但是最终并没有触发adc转换,请教下要怎么配置啊。void adcInit(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    //AD检测口
    GPIO_InitStruct.Pin = ADC_DET_PIN;
    GPIO_InitStruct.PxFCR = GPIO_FCR_ANA;
    GPIO_InitStruct.PxPUEN = GPIO_PU_Dis;
    GPIO_InitStruct.PxINEN = GPIO_IN_Dis;
    GPIO_InitStruct.PxODEN = GPIO_OD_En;
    GPIO_Init( ADC_DET_PORT, &GPIO_InitStruct );

    // 模块时钟
    RCC_OPC_CR2_ADCCKE_Setable(ENABLE);               // ADC时钟使能
    RCC_OPC_CR2_ADCPRSC_Set(RCC_OPC_CR2_ADCPRSC_DIV16); // ADC工作时钟
    RCC_OPC_CR2_ADCCKS_Set(RCC_OPC_CR2_ADCCKS_RCHF);   // ADC时钟 RCHF
    RCC_PERCLK_SetableEx( ADCCLK, ENABLE );
    RCC_PCLK_CR2_ADCPCE_Set(RCC_PCLK_CR2_ADC_PCE_Msk);
   
    // 电源控制
    if(DISABLE == PMU_VREF_CR_EN_Getable())   //判断ref122是否使能,如果禁止需清IF,保证下次使能查到的IF正确
      PMU_VREF_SR_IF_Clr();
    PMU_VREF_CR_EN_Setable(ENABLE);   // EN VREF1.22
    while(!PMU_VREF_SR_IF_Chk());
    // 复位ADC模块
    RCC_PRST_EN_Write(RSTKEY0);
    RCC_APBRST_CR2_ADCRST_Setable(ENABLE);// 数字部分复位
    RCC_APBRST_CR2_ADCRST_Setable(DISABLE);
    RCC_APBRST_CR2_ADCCRST_Setable(ENABLE); // 模拟部分复位
    RCC_APBRST_CR2_ADCCRST_Setable(DISABLE);
    RCC_PRST_EN_Write(RSTKEY1);

    //上电校准
    ADC_CR_ADEN_Setable(ENABLE);    // 使能ADC
    ADC_CAL_CALEN_Setable(ENABLE);// Calibration使能,软件写1启动校准周期,硬件开始校准后自动清零。软件通过EOCAL寄存器查询校准周期结束。
    while(0 == ADC_ISR_EOCAL_Chk());
    ADC_ISR_EOCAL_Clr();            // 清校准结束
    ADC_CR_ADEN_Setable(DISABLE);   // 关闭ADC

    // ADC配置
    ADC_CAL_CONV_CAL_Set(ADC_CAL_CONV_CAL_USE_CAL); //ADC转换使用校准寄存器里的数据
    ADC_SMTR_SMTS1_Set(ADC_SMTR_SMTS1_10_5_TMCLK);//设置快速采样时间
    ADC_SMTR_SMTS2_Set(ADC_SMTR_SMTS2_10_5_TMCLK);//设置慢速采样时间

    // ADC配置寄存器
    ADC_CFGR_CKS_Set(ADC_CFGR_CKS_ADCCLK);// ADCCLK
    ADC_CFGR_WAIT_Setable(ENABLE);                //使用DMA时必须使能
    ADC_CFGR_CONT_Setable(DISABLE);          // ENABLE:连续转换, DISABLE: 单次转换
    ADC_CFGR_SEMI_Set(ADC_CFGR_SEMI_HALF_AUTO);   //半自动,仅单次转换有效
    ADC_CFGR_OVRM_Set(ADC_CFGR_OVRM_COVER); // 当overrun发生时,覆盖上次数据
//    ADC_CFGR_SCANDIR_Set(ADC_CFGR_SCANDIR_FORWARD); // 前向扫描
    ADC_CFGR_EXTS_Set(ADC_CFGR_EXTS_ATIM_TROG); //设置硬件触发源
    ATIM_CR2_MMS_Set(ATIM_CR2_MMS_CEN);
   
    // DMA配置
    ADC_CFGR_DMACFG_Set(ADC_CFGR_DMACFG_SINGLE);    //dma模式:单次模式
   
    //过采样设置
    ADC_CFGR_OVSS_Set(ADC_CFGR_OVSS_R_SHIFT_4);
    ADC_CFGR_OVSR_Set(ADC_CFGR_OVSR_16x);
    ADC_CFGR_OVSEN_Setable(ENABLE);
   
    //AD检测口设置为ADC输入通道
    GPIOx_ANEN_Setable(ADC_DET_PORT, ADC_DET_PIN, ENABLE);
   

}

void AdcDmaInit(void)
{   
    DMA_CHx_CR_PRI_Set(DMA_CH0, DMA_CHx_CR_PRI_HIGH);   //设置通道优先级
    DMA_CHx_CR_INC_Set(DMA_CH0, DMA_CHx_CR_INC_INC);    //RAM地址自增
    DMA_CHx_CR_SSEL_Set(DMA_CH0, DMA_CH0_CR_SSEL_ADC_OUT);//外设选择为adc
    DMA_CHx_CR_DIR_Set(DMA_CH0, DMA_CHx_CR_DIR_PER_TO_RAM); //方向:外设到RAM
    DMA_CHx_CR_BDW_Set(DMA_CH0, DMA_CHx_CR_BDW_16BIT);//传输带宽:半字
    DMA_CHx_CR_CIRC_Setable(DMA_CH0, DISABLE);//关闭循环缓冲
    DMA_CHx_CR_FTIE_Setable(DMA_CH0, ENABLE);   //使能传输完成中断
    DMA_CHx_CR_HTIE_Setable(DMA_CH0, DISABLE);//关闭半程传输完成中断
    DMA_CHx_CR_EN_Setable(DMA_CH0, DISABLE);    //开启dma通道0
   
    DMA_GCR_DMAEN_Setable(ENABLE);//使能dma
   
    NVIC_DisableIRQ(DMA_IRQn);
    NVIC_SetPriority(DMA_IRQn, 2);
    NVIC_EnableIRQ(DMA_IRQn);
}

顾博文 发表于 2022-6-6 08:55:40

没有 FM33L0的例程。 有一个FM33LC0的例程,你可以参考下。

longor 发表于 2022-6-6 18:00:31

顾博文 发表于 2022-6-6 08:55
没有 FM33L0的例程。 有一个FM33LC0的例程,你可以参考下。

现在用atim可以触发adc转换,如果关闭dma转换,则每次atim时间到了会转换一次。但是使用dma转换就有问题,如果atim定时100ms,在atim定时时间第一次100ms到了后adc转换就不受控了,接下来就转换完预计的长度了,而不是间隔100ms转换预计的长度。现象是atim值触发一次,dma就完成了。这个要怎么解决啊

顾博文 发表于 2022-6-7 08:08:02

longor 发表于 2022-6-6 18:00
现在用atim可以触发adc转换,如果关闭dma转换,则每次atim时间到了会转换一次。但是使用dma转换就有问题 ...

FM33LC0的例程可以一直触发dma转换。你再比对下设置,看看哪里没对。

kp_jenny_li 发表于 2022-6-15 10:43:19

顾博文 发表于 2022-6-7 08:08
FM33LC0的例程可以一直触发dma转换。你再比对下设置,看看哪里没对。

其实我也遇到过这个问题,也是参照例程的模板来修改,就一直没有成功过,最后我放弃用DMA转换,直接用ADC中断来转换数据,就没有出现过DMA转换那样的问题。我在想是不是atim定时器触发adc-dma转换有隐藏的问题呢
页: [1]
查看完整版本: FM33L0系列adc通过ATIM触发怎么设置