野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12784|回复: 5

求助关于定时器事件触发ADC采样

[复制链接]
发表于 2016-10-17 13:48:11 | 显示全部楼层 |阅读模式
我不想在ISR中软件触发ADC,想利用定时器的事件输出触发,然后DMA传到内存或者串口。但是我尝试了很久也没成功,已确定DMA和ADC本身的配置没啥问题,用软件触发一切正常,就是定时器的事件触发完全不起作用,以下是定时器和ADC的配置,硬件是STM32F302,和F4系列差别不大。void BSP_ADC_Init(void)
{
        ADC_InitTypeDef       ADC_InitStructure;
        ADC_CommonInitTypeDef ADC_CommonInitStructure;
        GPIO_InitTypeDef    GPIO_InitStructure;
        ADC_InjectedInitTypeDef   ADC_InjectedInitStructure;
       
        RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
        //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
       
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        ADC_StructInit(&ADC_InitStructure);
        ADC_InjectedStructInit(&ADC_InjectedInitStructure);
        ADC_VoltageRegulatorCmd(ADC1, ENABLE);
        delay_us(10);
       
  ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
  ADC_StartCalibration(ADC1);
  while(ADC_GetCalibrationStatus(ADC1) != RESET );
  //calibration_value = ADC_GetCalibrationValue(ADC1);        
       
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;      
  ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;

  ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
       
  ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b;
  ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_4;                    //ADC_ExternalTrigConvEvent_4 :TIM3 TRGO事件
  ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigInjecEventEdge_RisingEdge;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;
  ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;
  ADC_InitStructure.ADC_NbrOfRegChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_181Cycles5);
  //ADC_ExternalTriggerConfig(ADC1,ADC_ExternalTrigConvEvent_4,ADC_ExternalTrigEventEdge_RisingEdge);
       
        ADC_InjectedInitStructure.ADC_ExternalTrigInjecConvEvent = ADC_ExternalTrigInjecConvEvent_0;
        ADC_InjectedInitStructure.ADC_ExternalTrigInjecEventEdge = ADC_ExternalTrigInjecEventEdge_None;
        ADC_InjectedInitStructure.ADC_NbrOfInjecChannel = 1;
        ADC_InjectedInitStructure.ADC_InjecSequence1 = ADC_InjectedChannel_1;
        ADC_InjectedInit(ADC1,&ADC_InjectedInitStructure);
        ADC_InjectedChannelSampleTimeConfig(ADC1,ADC_InjectedChannel_1,ADC_SampleTime_181Cycles5);
       
        ADC_Cmd(ADC1, ENABLE);
       
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));
        ADC_DMAConfig(ADC1, ADC_DMAMode_Circular);
  ADC_DMACmd(ADC1, ENABLE);                                                                                                                                                                       
}


void TIM3_Configuration(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 , ENABLE);
    //TIM_DeInit(TIM2);

    TIM_TimeBaseStructure.TIM_Period=125;

    TIM_TimeBaseStructure.TIM_Prescaler= 71;
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
       
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
       
    TIM_ClearFlag(TIM3, TIM_FLAG_Update);
       
    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);

    TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_Update);
    TIM_Cmd(TIM3, ENABLE);
}


回复

使用道具 举报

发表于 2016-10-17 13:52:41 | 显示全部楼层
你的配置是外部触发,不是定时器触发啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-17 14:02:07 | 显示全部楼层
随风 发表于 2016-10-17 13:52
你的配置是外部触发,不是定时器触发啊

这里的external应该是ADC外设的外部,实际还是片内,还不是说片外引脚的信号触发
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-17 17:08:50 | 显示全部楼层
问题找到了,配置完成后,还是要软件触发一次转换,然后定时器触发才能工作,也就是在ADC ENABLE之后执行一次ADC_StartConversion(ADCx);  好坑啊,手册里根本看不出来。
回复 支持 反对

使用道具 举报

发表于 2017-1-4 12:53:08 | 显示全部楼层
你好,我也是用的stm32f302,也需要用到定时ADC,你能把你的工程文件给发给我吗?不甚感激
回复 支持 反对

使用道具 举报

发表于 2017-4-13 21:47:32 | 显示全部楼层
然而stm32f4xx里面并没有这个函数
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 07:52 , Processed in 0.031103 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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