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

关于定时器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
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版