打印

已解决:示例程序测PWM高电平和周期的问题

[复制链接]
3803|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
早期的虫子|  楼主 | 2012-3-5 11:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 早期的虫子 于 2012-3-5 14:13 编辑

测量周期为20ms,高电平为10ms;但是用读出来的ICVALUE和IC1VALUE一直在变,有时候两者为0x08CC和0X97C,算出来占空比不是50%。以下为主程序
想了一个下午,已经把问题解决了:问题出在 对TIM定时器自动重装载寄存器TIMx_ARR即TIM_Period和预分频器即TIM_Prescaler的理解上。相信大部分初学者都不知道这两个是干嘛的。现在结合我的例子和大家分享下:假设时钟频率为72MHZ,我预分频器设为71,那么每一个计数的时间为(71+1)\72M=1微秒。这样的话,从我的捕获/比较寄存器 2(TIMx_CCR2) 的值为20000(因为波形有误差不一定为20000,但是很接近)的话,那么PWM周期为20ms,而从捕获/比较寄存器 1(TIMx_CCR1) 中读出来的值为10000,及高电平时间为10ms。还有一个问题,自动重装载寄存器TIMx_ARR即TIM_Period有什么用处呢?这里要强调一下,这个值的作用是,当时钟在计数到TIM_Period这个数的时候,会从0再开始计数,一直再计数到TIM_Period,如此循环往复,举个例子就像一天有24个小时计时,你也可以说一天有2个12小时,过了中午十二点,再从1开始。以我这个例子来说,这个是管着最大时间。我能测量的最大周期为65535乘以1微秒,就是65.535ms。一旦超过这个周期,又从0开始计数。我最开始的时候因为没有分频,计一个数的时间约为1\72M=0.01389微秒,TIM_Period = 4095,最大周期为4095*0.01389=56.875微秒。远小于我的周期20MS的需要。所以测得数据乱七八槽的。呵呵。现在已经好了。说的比较乱,但是大致意思就是这样了,我是初学者以上内容可能表达有的不准确,希望大家见谅。
int main(void)
{
  /* System Clocks Configuration */
  RCC_Configuration();

  /* Configure the GPIO ports */
  GPIO_Configuration();

  /* TIM3 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM3 CH2 pin (PA.07),
     The Rising edge is used as active edge,
     The TIM3 CCR2 is used to compute the frequency value
     The TIM3 CCR1 is used to compute the duty cycle value

本程序以 STM32F103手册225页的“PWM输入模式”为蓝本编写。

最终目的是求出PWM的频率和高电平脉宽
  ------------------------------------------------------------ */
   /* Time Base configuration */
  TIM_TimeBaseStructure.TIM_Period = 4095;//改为65535  TIM_TimeBaseStructure.TIM_Prescaler = 0;//改为71
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//定时器初始化


  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
//选择2通道作为输入通道
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  //选择上升沿触发
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //捕获通道选择
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  //输入预分频。意思是控制在多少个输入周期做一次捕获,如果输入的信号频率没有变,测得的周期也不会变。比如选择4分频,则每四个输入周期才做一次捕获,这样在输入信号变化不频繁的情况下,可以减少软件被不断中断的次数
  TIM_ICInitStructure.TIM_ICFilter = 0x0;
// 滤波设置,经历几个周期跳变认定波形稳定0x0~0xF

  TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);                //选择PWM捕获模式,根据参数配置TIM外设信息   


  /* Select the TIM3 Input Trigger: TI2FP2 */
  TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);
//选择IC2为始终触发源


  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
//TIM从模式:触发信号的上升沿重新初始化计数器和触发寄存器的更新事件

  /* Enable the Master/Slave Mode */
  TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);//启动定时器的被动触发

  /* TIM enable counter */
  TIM_Cmd(TIM3, ENABLE);//启动TIM2



  while (1)
  {
   ReadFlag1=TIM_GetFlagStatus(TIM3,TIM_FLAG_CC1);  //读取定时器状态寄存器TIMx_SR 中的CC1IF位判断是否有捕获发生
   ReadFlag2=TIM_GetFlagStatus(TIM3,TIM_FLAG_CC2);
//读取定时器状态寄存器TIMx_SR 中的CC2IF位判断是否有捕获发生
   if(ReadFlag1==SET)
  //如果有捕获发生
    {

IC1Value = TIM_GetCapture1(TIM3);
   //读取捕获寄存器TIMx_CCR1,即高电平计数
                                   //读取捕获寄存器TIMx_CCR2 ,即周期 计数

}
   if(ReadFlag2==SET)
  //如果有捕获发生
    {

ICValue = TIM_GetCapture2(TIM3);
   //读取捕获寄存器TIMx_CCR2,即周期计数
                                   //读取捕获寄存器TIMx_CCR2 ,即周期 计数

}
  }

}
沙发
mmuuss586| | 2014-4-21 16:47 | 只看该作者

解决了就好

使用特权

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

本版积分规则

0

主题

7

帖子

1

粉丝