打印

stm32比较器使用问题。

[复制链接]
9223|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
司空落星|  楼主 | 2014-7-15 20:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 司空落星 于 2014-7-15 22:51 编辑

本人想把一个正弦信号输入给stm32l151 的PB5引脚,想通过比较器实现把正弦波转为方波信号,然后通过定时器2的输入捕获功能测得方波的脉宽,我的这个思路可行吗?哪位大虾能给我详细的分析一下该如何实现呢?

下面是函数实现部分,向PB5输入一个正弦波,发现一直都进不了定时器中断函数,是哪里没有配置好吗?
/*******************************
*定时器2中断处理函数
*******************************/
void TIM2_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM2, TIM_IT_CC4) == SET)
  {
    GPIO_ResetBits(GPIOB,GPIO_Pin_9);
    GPIO_SetBits(GPIOB,GPIO_Pin_9);
  TIM_ClearITPendingBit(TIM2, TIM_IT_CC4|TIM_IT_Update);/*清除中断标志位*/
  }
}
/*******************************
*定时器2输入捕获配置
*******************************/
void TIM_Config(void)
{
  TIM_ICInitTypeDef TIM_ICInitStructure;
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  TIM_ClearFlag(TIM2, TIM_FLAG_Update);

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0;
  TIM_ICInit(TIM2, &TIM_ICInitStructure);

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

  TIM_ITConfig(TIM2, TIM_IT_CC4, ENABLE);

  TIM_Cmd(TIM2, ENABLE);
  TIM2->SR = 0;
}
/*******************************
*比较器配置函数
*******************************/
void COMP_Config(void)
{
  COMP_InitTypeDef COMP_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP, ENABLE);

  COMP_InitStructure.COMP_InvertingInput = COMP_InvertingInput_1_2VREFINT;
  COMP_InitStructure.COMP_OutputSelect = COMP_OutputSelect_TIM2IC4;
  COMP_InitStructure.COMP_Speed = COMP_Speed_Fast;
  COMP_Init(&COMP_InitStructure);
  COMP_Cmd(ENABLE);/**/
}
沙发
airwill| | 2014-7-15 20:12 | 只看该作者
方案可行. 能否增加回滞特性, 以提高转换出的方波的稳定性.

使用特权

评论回复
板凳
icecut| | 2014-7-15 22:15 | 只看该作者
使用adc,然后数字计算也可以

使用特权

评论回复
地板
mmuuss586| | 2014-7-15 22:57 | 只看该作者
原理上可行,你可以用da输出正弦波,先测试下。

使用特权

评论回复
5
司空落星|  楼主 | 2014-7-16 09:44 | 只看该作者
airwill 发表于 2014-7-15 20:12
方案可行. 能否增加回滞特性, 以提高转换出的方波的稳定性.

版主,能否帮小弟查看一下代码,万分感激

使用特权

评论回复
6
司空落星|  楼主 | 2014-7-16 09:46 | 只看该作者
mmuuss586 发表于 2014-7-15 22:57
原理上可行,你可以用da输出正弦波,先测试下。

超级版主,能否帮我看看代码哪里的问题,谢谢!

使用特权

评论回复
7
司空落星|  楼主 | 2014-7-16 10:43 | 只看该作者
icecut 发表于 2014-7-15 22:15
使用adc,然后数字计算也可以

使用adc如何实现呢,能否给详细解释一下呢?

使用特权

评论回复
8
icecut| | 2014-7-16 10:54 | 只看该作者
传统的方法就是adc读取模拟信号,然后数字滤波.然后数字比较器.这样比较浪费cpu资源.
你可以对正弦模拟滤波然后用比较器比较,做数字滞后滤波,然后输出

使用特权

评论回复
9
司空落星|  楼主 | 2014-7-16 12:57 | 只看该作者
icecut 发表于 2014-7-16 10:54
传统的方法就是adc读取模拟信号,然后数字滤波.然后数字比较器.这样比较浪费cpu资源.
你可以对正弦模拟滤波 ...

对正弦模拟滤波是软件做还是硬件做的,数字滞后滤波可以用软件配置吗?小弟学识甚浅,多多指教了!

使用特权

评论回复
10
icecut| | 2014-7-16 22:00 | 只看该作者
司空落星 发表于 2014-7-16 12:57
对正弦模拟滤波是软件做还是硬件做的,数字滞后滤波可以用软件配置吗?小弟学识甚浅,多多指教了! ...

能用硬件做就不用软件做.stm32需要节约着用

使用特权

评论回复
11
bsdl900| | 2014-9-2 00:33 | 只看该作者
库里面有个例子是测量pwm的,可以参考
贴下目前我用的:
void DAC_Config(void)
{
        DAC_InitTypeDef  DAC_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;
  /* DAC clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

  /* Fill DAC InitStructure */
  DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
  DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bits2_0;
  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;

/*
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
*/
  /* DAC Channel2 Init */
  DAC_Init(DAC_Channel_2, &DAC_InitStructure);
  /* Enable DAC Channel2 */
  DAC_Cmd(DAC_Channel_2, ENABLE);
  /* Set DAC Channel2 DHR register: DAC_OUT2 = (3.3 * 868) / 4095 ~ 0.7 V */
  DAC_SetChannel2Data(DAC_Align_12b_R, 2);
}

/**
  * @brief  Configures COMP2: DAC channel 2 to COMP2 inverting input
  *                           and COMP2 output to TIM2 IC4.
  * @param  None
  * @retval None
  */
void COMP_Config(void)
{
        COMP_InitTypeDef COMP_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;

  /**************************** COMP2 Config **********************************/
  /* GPIOB Peripheral clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  /* Configuring PB5 in analog mode closes the switch GR6-2 so PB5 is connected
     to COMP2 non inverting input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* COMP clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  SYSCFG_RIIOSwitchConfig(RI_IOSwitch_GR6_2,ENABLE);

  /* COMP2 Init: COMP2 is enabled as soon as inverting input is selected */
  /* use DAC2 output as a reference voltage: DAC2 output is connected to COMP2
     inverting input */
  COMP_InitStructure.COMP_InvertingInput = COMP_InvertingInput_DAC2;
  /* Redirect COMP2 output to TIM2 Input capture 4 */
  COMP_InitStructure.COMP_OutputSelect = COMP_OutputSelect_TIM2IC4;
  COMP_InitStructure.COMP_Speed = COMP_Speed_Fast;
  COMP_Init(&COMP_InitStructure);
}

/**
  * @brief  Configures TIM2 channel 4 in input capture mode
  * @param  None
  * @retval None
  */
void TIM_Config(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        TIM_ICInitTypeDef TIM_ICInitStructure;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  /**************************** TIM2 Config ***********************************/
  /* TIM2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  /* TIM2 Time base configuration */
  TIM_TimeBaseStructure.TIM_Prescaler = 0;//fck_cnt = 8M/2 = 4Mhz
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  TIM_ClearFlag(TIM2, TIM_FLAG_Update|TIM_FLAG_CC4);


  /* TIM2 Channel4 Input capture Mode configuration */
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
  /* TIM2 counter is captured at each transition detection: rising or falling edges (both edges) */
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 8;//once 4us
  TIM_ICInit(TIM2, &TIM_ICInitStructure);

  /* TIM2 IRQChannel enable */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  // time2 capture
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* Enable capture interrupt */
  TIM_ITConfig(TIM2, TIM_IT_CC4, ENABLE);

  /* Enable the TIM2 counter */
  TIM_Cmd(TIM2, ENABLE);

  /* Reset the flags */
  TIM2->SR = 0;
}

使用特权

评论回复
12
悲伤流逝| | 2014-9-2 09:26 | 只看该作者
学习了

使用特权

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

本版积分规则

7

主题

21

帖子

0

粉丝