打印

关于定时器触发AD转换的问题

[复制链接]
5201|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jinjing999|  楼主 | 2009-4-22 17:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我按照库给的配置
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); 
  TIM_TimeBaseStructure.TIM_Period = 0xFF;          
  TIM_TimeBaseStructure.TIM_Prescaler = 0x4;       
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;    
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
  /* TIM1 channel1 configuration in PWM mode */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;                
  TIM_OCInitStructure.TIM_Pulse = 0x7F; 
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;         
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);

用定时器触发AD,可我不知道怎么算它触发频率?
还有我只要求定时器触发AD,我不要PWM输出,这种模式是不是还输出波形啊?

我按照
72/4/256=72265的方法计算,改了几个值,可是转换率感觉还是不对


我到底采用定时器1哪种模式去触发AD,我的采样率在9600HZ左右
怎么计算?
沙发
jinjing999|  楼主 | 2009-4-22 18:12 | 只看该作者

我也试过,时基本模式,

时基模式,这种AD根本不转换
TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

  /* Prescaler configuration */
  TIM_PrescalerConfig(TIM1, 4, TIM_PSCReloadMode_Immediate);

  /* Output Compare Timing Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC1Init(TIM1, &TIM_OCInitStructure);

  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable);

  /* Output Compare Timing Mode configuration: Channel2 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

  TIM_OC2Init(TIM1, &TIM_OCInitStructure);

  TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable);

  /* Output Compare Timing Mode configuration: Channel3 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR3_Val;

  TIM_OC3Init(TIM1, &TIM_OCInitStructure);

  TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Disable);

  /* Output Compare Timing Mode configuration: Channel4 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR4_Val;

  TIM_OC4Init(TIM1, &TIM_OCInitStructure);

  TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Disable);

  /* TIM IT enable */
  TIM_ITConfig(TIM1, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);

  /* TIM2 enable counter */
  TIM_Cmd(TIM1, ENABLE);

使用特权

评论回复
板凳
香水城| | 2009-4-22 18:31 | 只看该作者

使用PWM模式并把OC输出关闭即可

1楼的PWM设置就可以,只需关闭OC输出。

打开OC输出可以观察触发频率。你看到的触发频率是多少?

使用特权

评论回复
地板
jinjing999|  楼主 | 2009-4-23 11:04 | 只看该作者

我看到波形了,可是采样间隔还是不能改变

我用示波器看到PWM输出的频率了,现在问题是我改变频率,可采样时间间隔还是没有变。
我是用DMA中断取数据,DMA中断的时间并没有根据我PWM脉冲而改变。
是什么原因造成的啊?

使用特权

评论回复
5
jinjing999|  楼主 | 2009-4-23 11:35 | 只看该作者

把程序贴出来

使用特权

评论回复
6
jinjing999|  楼主 | 2009-4-23 11:39 | 只看该作者

配置程序

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC |
                          RCC_APB2Periph_TIM1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2, ENABLE);// 时钟

      /* Configure PC.01, PC.02 and PC.04 (ADC Channel11, Channel12 and Channel14)
    as analog input ----------------------------------------------------------*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
      GPIO_Init(GPIOC, &GPIO_InitStructure);

    //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2| GPIO_Pin_3| GPIO_Pin_4;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

      GPIO_Init(GPIOA, &GPIO_InitStructure);

     NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
   
     NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQChannel;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);


    //CC1 update rate = TIM2 counter clock / CCR1_Val = 146.48 Hz
    //72/7500=9600  9600/3=3200  64/3200 =0.02秒
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_Period = 3750;//7500
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
   
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
  //TIM1 channel1 configuration in PWM mode 
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;                
  TIM_OCInitStructure.TIM_Pulse =1750; 
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;         
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
 
  /* DMA1 Channel1 Configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_collection;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = ADC_number;//ADC_number;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  
  /* Enable DMA1 channel1 */
  DMA_Cmd(DMA1_Channel1, ENABLE);
  DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE); //使能DMA传输完成中断 

  /* ADC1 configuration ------------------------------------------------------*/
    ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
      ADC_InitStructure.ADC_ScanConvMode = ENABLE;
      ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //DISABLE;
      ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
      ADC_InitStructure.ADC_NbrOfChannel = 9;//装换9个通道
    //ADC_InitStructure.ADC_NbrOfChannel = 1;//装换1个通道
      ADC_Init(ADC1, &ADC_InitStructure);
    ADC_Init(ADC2, &ADC_InitStructure);
    ADC_DiscModeChannelCountConfig (ADC1, 3);//一次转换3个数据
    ADC_DiscModeChannelCountConfig (ADC2, 3);//一次转换3个数据

    //ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5);
    //ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_1Cycles5);
    
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 4, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 5, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 6, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 7, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 8, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 9, ADC_SampleTime_1Cycles5);

    ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 1, ADC_SampleTime_1Cycles5);
      ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 2, ADC_SampleTime_1Cycles5);
      ADC_RegularChannelConfig(ADC2, ADC_Channel_I5, 3, ADC_SampleTime_1Cycles5);

      ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 4, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_7, 5, ADC_SampleTime_1Cycles5);
      ADC_RegularChannelConfig(ADC2, ADC_Channel_8, 6, ADC_SampleTime_1Cycles5);

      ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 7, ADC_SampleTime_1Cycles5);
      ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 8, ADC_SampleTime_1Cycles5);
      ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 9, ADC_SampleTime_1Cycles5);

      /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);

  /* Enable ADC1 external trigger */ 
  ADC_ExternalTrigConvCmd(ADC1, ENABLE);
  ADC_ExternalTrigConvCmd(ADC2, ENABLE);
    //ADC_ExternalTrigConvCmd(ADC1, DISABLE);
    //ADC_ExternalTrigConvCmd(ADC2, DISABLE);
  /* Enable ADC1 */
  
    ADC_Cmd(ADC1, ENABLE);                        // 使能ADC1
    ADC_ResetCalibration(ADC1);                    // 复位ADC1的校准寄存器
    while(ADC_GetResetCalibrationStatus(ADC1));    // 等待检测校准过程完成
    ADC_StartCalibration(ADC1);                    // 开始校准各个通道
    while(ADC_GetCalibrationStatus(ADC1));        // 等待校准过程完成

    ADC_Cmd(ADC2, ENABLE); //使能ADC
    ADC_ResetCalibration(ADC2);                    // 复位ADC2的校准寄存器
    while(ADC_GetResetCalibrationStatus(ADC2));    // 等待检测校准过程完成
    ADC_StartCalibration(ADC2);                    // 开始校准各个通道
    while(ADC_GetCalibrationStatus(ADC2));        // 等待校准过程完成



      TIM_Cmd(TIM1, ENABLE);
      TIM_CtrlPWMOutputs(TIM1, ENABLE); 

    while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
    DMA_ClearFlag(DMA1_FLAG_TC1);

使用特权

评论回复
7
jinjing999|  楼主 | 2009-4-23 11:42 | 只看该作者

问题是,改变PWM输出频率,AD转换间隔不变

我还改变了分频倍数,可DMA的中断时间还是不改变
用DMA转换固定的数据,定时器触发频率不同,DMA的中断时间应该也不同吧

使用特权

评论回复
8
jinjing999|  楼主 | 2009-4-23 11:55 | 只看该作者

我改变了DMA的传送的数据了,增加2倍

我改变了DMA的传送的数据了,增加2倍我采集到的时间也是2倍,说明我内部采集时间是没有错的。

使用特权

评论回复
9
jinjing999|  楼主 | 2009-4-23 13:52 | 只看该作者

整料两天了,就是找不到问题,版主看看,到底是怎么回事

使用特权

评论回复
10
香水城| | 2009-4-23 14:15 | 只看该作者

看了半天,没有明白楼主的问题在哪里

好像是:改变PWM输出频率,AD转换间隔不变,但8楼又说:我改变了DMA的传送的数据了,增加2倍我采集到的时间也是2倍,说明我内部采集时间是没有错的。

一方面说AD转换间隔不变,另一方面又说内部采集时间没有错,所以我不明白楼主的问题是什么,请说清楚些。


根据你的要求,应该设置通过定时器触发ADC开始转换,在ADC转换完成触发DMA进行数据传送。如果你只是使用DMA数据传送,而没有把定时器、ADC和DMA三者同步起来,结果当然会有问题。

使用特权

评论回复
11
jinjing999|  楼主 | 2009-4-23 14:39 | 只看该作者

这是说,8楼我说的意识

是这样,采样间隔,我是用滴嗒数值进行计数,采样2304个数据,进入一个DMA中断,看看我这到底是用料多少时间。我用这个数据来验证采样间隔是否正确?
“应该设置通过定时器触发ADC开始转换,在ADC转换完成触发DMA进行数据传送。如果你只是使用DMA数据传送,而没有把定时器、ADC和DMA三者同步起来,结果当然会有问题”

我的要求就是:应该设置通过定时器触发ADC开始转换,在ADC转换完成触发DMA进行数据传送

定时器触发AD,AD转换结束把数据传到DMA上,(两个AD是同步采集),每次定时器触发不是传送一个32位数据到DMA吗?那这个时间间隔不是定时触发的结果吗?如果我改变定时器触发的时间,那我DMA数据传送完毕,这段时间应该是有变化的啊?可现在这个时间就是没有变化,这是什么问题啊?

使用特权

评论回复
12
jinjing999|  楼主 | 2009-4-23 14:49 | 只看该作者

修改11楼的贴子

验证采样间隔,是用系统滴嗒数值计数的方法,采样2304个数据,进入一个DMA中断,看看我这到底是用了多少时间,用系统滴嗒数值来验证采样间隔是否正确?

   我的应用要求就是:应该设置通过定时器触发ADC开始转换,在ADC转换完成触发DMA进行数据传送。

现在的问题是:
   定时器触发AD,AD转换结束把数据传到DMA上,(两个AD是同步采集),每次定时器触发不是传送一个32位数据到DMA吗?那这个时间间隔不是定时触发的结果吗?如果我改变定时器触发的时间,那我DMA数据传送完毕,这段时间应该是有变化的啊?可现在这个时间就是没有变化,这是什么问题啊?

使用特权

评论回复
13
jinjing999|  楼主 | 2009-4-23 15:01 | 只看该作者

楼主,怎么把定时器、ADC和DMA三者同步起

我刚翻看库文件的说明
和手册,这没有说:定时器、ADC和DMA三者同步起
我的理解就是:
应该设置通过定时器触发ADC开始转换,在ADC转换完成触发DMA进行数据传送

采集几个数据,用多少时间,就是定时器间隔时间有关系

使用特权

评论回复
14
香水城| | 2009-4-23 15:56 | 只看该作者

ADC应该使用单次转换模式而不是连续转换模式

连续转换模式是在触发一次后重复地进行转换,而不是你需要的每次定时器触发时才转换。

使用特权

评论回复
15
jinjing999|  楼主 | 2009-4-23 16:20 | 只看该作者

找到问题了

你说的是一个问题
但是还有一个问题

应该打开间隔采集

使用特权

评论回复
16
jinjing999|  楼主 | 2009-4-23 16:24 | 只看该作者

谢谢版主

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

73

主题

363

帖子

1

粉丝