打印
[应用相关]

请香主看看:关于stm32 定时器捕获

[复制链接]
7004|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LGghost|  楼主 | 2009-4-28 21:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
我想要实现如下功能:
要用stm32自带的AD测量交流信号的一个周波32个点。
思路是这样子的:
先用TIM4来检测交流信号的过零点,我准备用TIM4的捕获功能,当信号有上升沿时,捕获,此时会进入中断程序(在定时器配置的时候已经开了捕获中断),在中断程序中,开TIM2的定时器(用这个定时器来控制AD的采样间隔)。定时器TIM2触发AD采样32次后,停止计数。等到下一个周波的上升沿来时,又进入TIM4的捕获中断,启动TIM2,如此反复。
预订做法:
(1)配置信号PB6(TIM4-CH1)为浮空输入,信号经过比较器进入到这里,从而取得上升沿。
(2)配置TIM4时基,配置TIM4-CH1输入捕获,选TIM_TS_TI1FP1输入触发,其他配置照例程,使能TIM4,开中断TIM_IT_CC1。
(3)在TIM4的中断程序中启动TIM2采样间隔定时。
(4)在TIM2的中断程序中,开始采样。

这样可以吗?
沙发
香水城| | 2009-4-28 22:28 | 只看该作者

基本思路正确,但是还可以优化

你可以只用一个定时器,用你的过零检测信号的上升沿,使用STM32参考手册第13.3.14节中的"从模式:触发模式"触发你预定的TIM2,从而省却你设计中的TIM4和捕获中断。

在此基础上,使用TIM2的每个周期直接触发一次ADC转换,ADC转换结束后触发一次DMA传输,把转换数据直接传送到存储器中。然后在DMA传输结束中断中,停止TIM2和ADC,同时处理这个周波的所有转换数据。

这样要测量的交流信号每个周波只有一次中断,只需一次的集中数据处理,大大地优化了CPU的操作效率。

使用特权

评论回复
板凳
LGghost|  楼主 | 2009-4-29 09:11 | 只看该作者

从模式

恩,你的这个方案比较好,我试试看。如果遇到问题再请教,谢谢香主!

使用特权

评论回复
地板
McuPlayer| | 2009-4-29 10:15 | 只看该作者

Timer和DMA配合最好

DMA不占用CPU的时间(实际上也要占用总线的时间,不过非常小,看看CM3的手册就知道了)

STM32几乎每个外设可以做DMA的触发源,这点设计得非常好。
我的一个设计中用了2个DMA,一个捕捉外部的脉冲宽度,一个输出PWM


DIY的朋友可以试试用DMA+PWM输出语音,效果非常好,也不占用CPU时间。

使用特权

评论回复
5
LGghost|  楼主 | 2009-4-29 22:15 | 只看该作者

还请香主帮忙看看,关于定时器捕获功能。

今天按照你先前跟我说的方法试了下,发现在触发后,计数器时一直计数的,而且TIF一直都是置位,加了给它复位也不行。是不是它只要检测到是相应电平就会置位呢?
捣腾了一天也没成功。晚上又尝试了输入捕获功能,发现可以实现我的要求,但是有一点问题,就是我设置了上升沿为有效的的电平转变。但是,在我实际测量时(我需要在上升沿过零点开始采样),发现在上升和下降沿均产生捕获。不知道是为什么?请香主帮我看看问题在哪儿?
程序:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;

void RCC_Configuration(void);
void NVIC_Configuration(void);

int main(void)
{
  RCC_Configuration(); 
  /* NVIC Configuration */
  NVIC_Configuration();
    //电网频率检测Ua-1,对应PB6,用TIM4-CH1
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_ICInitTypeDef  TIM_ICInitStructure;    
 /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 65535;          
  TIM_TimeBaseStructure.TIM_Prescaler = 29;//21;       
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;    //接收最小为:72M/(29+1)/65535
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;     //65535为ccr1/2中的值
  
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
    
             
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;           
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;         
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;       
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV2;       
  TIM_ICInitStructure.TIM_ICFilter = 0x1;
  
  TIM_ICInit(TIM4, &TIM_ICInitStructure);

  TIM_SelectInputTrigger(TIM4, TIM_TS_TI1FP1);
  TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset); 
  TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable); 
  TIM_Cmd(TIM4, ENABLE); 

  TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE);

  while(1)
  {

  }
}
void RCC_Configuration(void)
{。。。}//为简便,此处省略
void NVIC_Configuration(void)
{
 NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM  
  /* Set the Vector Table base location at 0x20000000 */ 
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */ 
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif

  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

}

void TIM4_IRQHandler(void)
{
  TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
 // StartSampling();//这是我的启动采样函数,在此处未列出。
}

使用特权

评论回复
6
香水城| | 2009-4-30 15:01 | 只看该作者

按照我说的方法,你应该选择外部触发信号作为触发条件

请看下图中红框标出的部分,而你使用了下图中蓝框标出的部分。

使用从模式的触发模式,计数器在启动后如果没有软件干预当然不会停下来,所以2楼我就说“在DMA传输结束中断中,停止TIM2和ADC”。

你也可以使用从模式的门控模式,当你的过零信号为高时定时器计数,过零信号变低时计数器停止计数。同样还可以考虑从模式的复位模式。


至于你尝试输入捕获功能,发现在上升和下降沿均产生捕获,这个我不太理解,请问你如何判断的,依据什么得出这个结论?

使用特权

评论回复
7
香水城| | 2009-4-30 15:34 | 只看该作者

关于选择外部触发信号作为触发条件,请参考STM32固件库例子

请看这个例子:TIM_ExtTrigger_Synchro

使用特权

评论回复
8
fanxsd| | 2014-9-11 14:46 | 只看该作者
本帖最后由 fanxsd 于 2014-9-11 14:50 编辑
LGghost 发表于 2009-4-29 22:15
今天按照你先前跟我说的方法试了下,发现在触发后,计数器时一直计数的,而且TIF一直都是置位,加了给它复 ...


不知到你的问题解决了吗,我也感觉 霍尔异或 捕获的时候,设置为上升沿捕获,而实际上是 有边沿跳动就有捕获的。


我看手册上就是这样解释的 任意一个跳变就会触发。

我的程序配置如下:上升沿触发

   TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;              //选择通道1
   TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;   //输入上升沿捕获  
   TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;    //配置通道为输入,并映射到哪里
   TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //输入捕获预分频值
   TIM_ICInitStructure.TIM_ICFilter = 10;                        //输入滤波器带宽设置

霍尔捕获.jpg (128.07 KB )

霍尔捕获.jpg

使用特权

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

本版积分规则

2

主题

8

帖子

0

粉丝