查看: 6322|回复: 4

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

[复制链接]

8

主题

15

帖子

144

积分

中级工程师

Rank: 2

积分
144
发表于 2022-6-2 18:24:35 | 显示全部楼层 |阅读模式
代码如下所示,配置了atim为200ms中断一次,adc初始化如下,但是最终并没有触发adc转换,请教下要怎么配置啊。
  1. void adcInit(void)
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  4.     //AD检测口
  5.     GPIO_InitStruct.Pin = ADC_DET_PIN;
  6.     GPIO_InitStruct.PxFCR = GPIO_FCR_ANA;
  7.     GPIO_InitStruct.PxPUEN = GPIO_PU_Dis;
  8.     GPIO_InitStruct.PxINEN = GPIO_IN_Dis;
  9.     GPIO_InitStruct.PxODEN = GPIO_OD_En;
  10.     GPIO_Init( ADC_DET_PORT, &GPIO_InitStruct );

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

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

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

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

  61. }

  62. void AdcDmaInit(void)
  63. {   
  64.     DMA_CHx_CR_PRI_Set(DMA_CH0, DMA_CHx_CR_PRI_HIGH);   //设置通道优先级
  65.     DMA_CHx_CR_INC_Set(DMA_CH0, DMA_CHx_CR_INC_INC);    //RAM地址自增
  66.     DMA_CHx_CR_SSEL_Set(DMA_CH0, DMA_CH0_CR_SSEL_ADC_OUT);  //外设选择为adc
  67.     DMA_CHx_CR_DIR_Set(DMA_CH0, DMA_CHx_CR_DIR_PER_TO_RAM); //方向:外设到RAM
  68.     DMA_CHx_CR_BDW_Set(DMA_CH0, DMA_CHx_CR_BDW_16BIT);  //传输带宽:半字
  69.     DMA_CHx_CR_CIRC_Setable(DMA_CH0, DISABLE);  //关闭循环缓冲
  70.     DMA_CHx_CR_FTIE_Setable(DMA_CH0, ENABLE);   //使能传输完成中断
  71.     DMA_CHx_CR_HTIE_Setable(DMA_CH0, DISABLE);  //关闭半程传输完成中断
  72.     DMA_CHx_CR_EN_Setable(DMA_CH0, DISABLE);    //开启dma通道0
  73.    
  74.     DMA_GCR_DMAEN_Setable(ENABLE);  //使能dma
  75.    
  76.     NVIC_DisableIRQ(DMA_IRQn);
  77.     NVIC_SetPriority(DMA_IRQn, 2);
  78.     NVIC_EnableIRQ(DMA_IRQn);
  79. }
复制代码


回复

使用道具 举报

151

主题

840

帖子

4377

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4377
发表于 2022-6-6 08:55:40 | 显示全部楼层
没有 FM33L0的例程。 有一个FM33LC0的例程,你可以参考下。

ATIM触发ADC_DMA.rar

259.85 KB, 下载次数: 248

回复

使用道具 举报

8

主题

15

帖子

144

积分

中级工程师

Rank: 2

积分
144
 楼主| 发表于 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就完成了。这个要怎么解决啊
回复

使用道具 举报

151

主题

840

帖子

4377

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4377
发表于 2022-6-7 08:08:02 | 显示全部楼层
longor 发表于 2022-6-6 18:00
现在用atim可以触发adc转换,如果关闭dma转换,则每次atim时间到了会转换一次。但是使用dma转换就有问题 ...

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

使用道具 举报

3

主题

10

帖子

157

积分

中级工程师

Rank: 2

积分
157
发表于 2022-6-15 10:43:19 | 显示全部楼层
顾博文 发表于 2022-6-7 08:08
FM33LC0的例程可以一直触发dma转换。你再比对下设置,看看哪里没对。

其实我也遇到过这个问题,也是参照例程的模板来修改,就一直没有成功过,最后我放弃用DMA转换,直接用ADC中断来转换数据,就没有出现过DMA转换那样的问题。我在想是不是atim定时器触发adc-dma转换有隐藏的问题呢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表