你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于定时器TIM3 触发 ADC1 采样的一点困惑

[复制链接]
狂奔的企鹅 提问时间:2015-4-14 18:29 /
本帖最后由 狂奔的企鹅 于 2015-4-15 14:36 编辑

我用的是STM32F4-DISCOVERY (探索板)

下面是我写的配置文件,分别是 adc 的配置文件和 tim的配置文件,其中 tim_gpio_config的配置文件,那部分是 为了检测是否有30KHZ方波产生。

波形产生没有错误,我用示波器测了一下,是 30KHZ的方波。
而ADC配置部分也用软件启动试过也没有问题,唯一有问题的就是 tim 触发 adc 这部分..

我是通过TIM_Cmd(TIM3, ENABLE); 启动AD转换的。然后在一个循环里不断读取 EOC标志位来 存贮 ADC 转换值的。

会滴举个手,指点下我。谢谢!

  1. void adc_config(void)
  2. {
  3.     GPIO_InitTypeDef      GPIO_InitStructure;
  4.     ADC_CommonInitTypeDef ADC_CommonInitStructure;
  5.     ADC_InitTypeDef       ADC_InitStructure;
  6.    
  7.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  8.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // APB2 时钟84MHZ

  9.     /* Configure ADC1 Channel15 pin as analog input pc5******************************/
  10.     /* Configure ADC1 Channel11 pin as analog input pc1******************************/
  11.    
  12.     GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_1 | GPIO_Pin_5;
  13.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  14.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  15.     GPIO_Init(GPIOC, &GPIO_InitStructure);

  16.     /* ADC Common Init **********************************************************/
  17.     //
  18.     ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
  19.     ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; // 84MHZ / 2 = 42MHZ;
  20.     ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  21.     ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
  22.     ADC_CommonInit(&ADC_CommonInitStructure);

  23.     /* ADC1 Init ****************************************************************/
  24.     ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  25.     ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  26.     ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  27.    
  28.     // 通过上升沿触发
  29.     ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
  30.    
  31.     // 通过 定时器的TRGO 信号来启动 ADC1
  32.     ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_T3_TRGO;

  33.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  34.     ADC_InitStructure.ADC_NbrOfConversion = 2;
  35.     ADC_Init(ADC1, &ADC_InitStructure);
  36.    
  37.    
  38.     /* ADC1 regular channel11,15 configuration *************************************/
  39.     ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 2, ADC_SampleTime_144Cycles);   
  40.     ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_144Cycles);
  41.    
  42.     ADC_Cmd(ADC1, ENABLE);
  43.    
  44.     // 在每个通道转换结束后 产生标志位EOC
  45.     ADC_EOCOnEachRegularChannelCmd(ADC1,ENABLE);   
  46. }


  47. // 检测是否波形是否正确
  48. void GPIO_TIM_Config(void)
  49. {   
  50.     GPIO_InitTypeDef  GPIO_InitStructure;
  51.   
  52.     /* Enable the GPIOC Clock */
  53.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

  54.   /* Configure the GPIO_6 pin */
  55.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  56.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  57.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  58.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  59.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  60.     GPIO_Init(GPIOC, &GPIO_InitStructure);
  61.    
  62.     // 打开GPIOC_6 的引脚复用功能 TIM3_CH1
  63.     GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM3);
  64.    
  65. }
  66. // 计数器 60khz的工作频率
  67. const u16 PrescalerValue = (u16)((168000000 / 2) /60000) - 1;
  68. void TIM1_Config(void)
  69. {
  70.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  71.     TIM_OCInitTypeDef           TIM_OCInitStructure;
  72.    
  73.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

  74.     /* Time base configuration */
  75.     // 计数到1,从0到1,计数两次,两次后计数溢出 产生更新事件。更新事件的频率是30KHZ
  76.     TIM_TimeBaseStructure.TIM_Period = 1;
  77.    
  78.     TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; // 计数器 60khz的工作频率
  79.     TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  80.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
  81.    
  82.     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  83.    
  84.     /* Prescaler configuration  1MHZ 的计时工作频率*/
  85.     //TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate);
  86.    
  87.     /* Output Compare Timing Mode configuration: Channel2 */
  88.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 使用 PWM 技术检测是否能输出 30KHZ的波
  89.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  90.     TIM_OCInitStructure.TIM_Pulse = 1; // 占空比为 25%
  91.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //  高电平为有效电平
  92.    
  93.     TIM_OC1Init(TIM3, &TIM_OCInitStructure);
  94.     // 预载寄存器使能
  95.     TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
  96.     /* TIM1 enable counter */
  97.     TIM_ARRPreloadConfig(TIM3, ENABLE);
  98.     // 选择事件作为外部触发 --- > ADC1
  99.     TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_Update);
  100.    
  101. }


复制代码




收藏 评论12 发布时间:2015-4-14 18:29

举报

12个回答
废鱼 回答时间:2015-4-15 09:30:01
先配置TIM,然后配置ADC,在TIM中断里面判断EOC,读取数据存放到指定的缓冲区中。
狂奔的企鹅 回答时间:2015-4-15 10:09:44
安 发表于 2015-4-15 09:30
先配置TIM,然后配置ADC,在TIM中断里面判断EOC,读取数据存放到指定的缓冲区中。 ...

这样不就失去了通过 TIM 3的更新事件触发 ADC 采样 的优越性了嘛,还有 adc_config的配置那块的 // 通过 定时器的TRGO 信号来启动 ADC1
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;

已经修改为 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO; 还是不行吖,
不知道阁下有啥好的建议?
狂奔的企鹅 回答时间:2015-4-15 10:32:12
试了一下,发下 ADC 根本就没有被启动。
废鱼 回答时间:2015-4-15 10:51:26
楼主为什么要用TIM来触发采集AD呢?想实现什么样的功能?
拼命三郎 回答时间:2015-4-15 13:21:09
ddddd.png
狂奔的企鹅 回答时间:2015-4-15 14:35:23
安 发表于 2015-4-15 10:51
楼主为什么要用TIM来触发采集AD呢?想实现什么样的功能?

我想采集20K个点来实现电压量的采集。因为要求采样频率必须固定,所以想通过定时器采样。
废鱼 回答时间:2015-4-15 16:37:23
哦。楼主可以开启AD中断,中断实时转换数据放入到指定的变量中,当TIM中断产生时,直接取值就可以了。
狂奔的企鹅 回答时间:2015-4-15 17:55:14
安 发表于 2015-4-15 16:37
哦。楼主可以开启AD中断,中断实时转换数据放入到指定的变量中,当TIM中断产生时,直接取值就可以了。 ...

EN, thanks, 我已经试过了在TIM中断里面通过软件开启 adc 了,这样是可以,但是方法没有 通过TIM的trgo事件触发 ADC 转换 优越,而且精度 比不上 trgo触发 。毕竟 进入中断要 出栈入栈。
hjl2832 回答时间:2015-4-16 13:19:23
我记得ADC转換在第一次使能时,只是把ADC从休眠模式唤醒,需要再次使能才开使转换数据的。
AD开关控制.JPG
wyxy163@126.com 回答时间:2015-4-16 19:04:31
提示: 作者被禁止或删除 内容自动屏蔽
wamcncn 回答时间:2015-4-16 19:24:43
学习经验
狂奔的企鹅 回答时间:2015-4-17 07:52:59
hjl2832 发表于 2015-4-16 13:19
我记得ADC转換在第一次使能时,只是把ADC从休眠模式唤醒,需要再次使能才开使转换数据的。
见 ...

嗯,是的官方资料是这么说的,谢谢交流,我这块和这点没关系,应该是多通道的关系。

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版