stm32的定时器输入捕获与输出比较.docx

上传人:b****5 文档编号:29508781 上传时间:2023-07-24 格式:DOCX 页数:12 大小:273.72KB
下载 相关 举报
stm32的定时器输入捕获与输出比较.docx_第1页
第1页 / 共12页
stm32的定时器输入捕获与输出比较.docx_第2页
第2页 / 共12页
stm32的定时器输入捕获与输出比较.docx_第3页
第3页 / 共12页
stm32的定时器输入捕获与输出比较.docx_第4页
第4页 / 共12页
stm32的定时器输入捕获与输出比较.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

stm32的定时器输入捕获与输出比较.docx

《stm32的定时器输入捕获与输出比较.docx》由会员分享,可在线阅读,更多相关《stm32的定时器输入捕获与输出比较.docx(12页珍藏版)》请在冰豆网上搜索。

stm32的定时器输入捕获与输出比较.docx

stm32的定时器输入捕获与输出比较

定时器1的输出比较模式怎么用。

利用这个功能输出一个1KHZ,占空比为10%的程序怎么写啊?

求高人指点

1、陪定时器1的功能为特殊功能,不是普通IO  在PERCFG这里

2、P1SEL引脚选择

3、P1DIR设为输出

4、T3CC0设置周期

5、T3CC1设置占空比

6、T3CCTL0设置通道0

7、T3CCTL1设置通道1

8、T3CTL设为模模式

9、用T3CTL打开即可

************以下是用定时器做频率源,用定时器测量该频率的应用程序!

***********

调试STM32的定时器好几天了,也算是对STM32的定时器有了点清楚的认识了。

我需要测量4路信号的频率然后通过DMA将信号的频率传输到存储器区域,手册说的很明白每个定时器有4个独立通道。

然后我就想能不能将这4路信号都连接到一个定时器的4个通道上去。

理论上应该是行的通的。

刚开始俺使用的是TIM2的123通道,TIM4的2通道来进行频率的测量。

由于没有频率发生器,所以我用tim3作为信号源,用TIM2,TIM4来进行测量就ok了(刚好4个通道了)。

  请看一开始的程序,以TIM2的1,3通道为例子(2通道设置方法一样):

  TIM_ICInitStructure.TIM_ICMode=TIM_ICMode_ICAP;                //配置为输入捕获模式         

  TIM_ICInitStructure.TIM_Channel=TIM_Channel_1;                    //选择通道1

  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=0x0;                           //滤波

  TIM_ICInit(TIM2,&TIM_ICInitStructure);   //TIM2通道1配置完毕

 

  TIM_ICInitStructure.TIM_ICMode=TIM_ICMode_ICAP;     //配置为输入捕获模式     

  TIM_ICInitStructure.TIM_Channel=TIM_Channel_3;                 //选择通道3

  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=0x0;             //滤波

  TIM_ICInit(TIM2,&TIM_ICInitStructure);   //TIM2通道3配置完毕

 

  以上是输入捕获配置

  还需要做的工作就是(参考stm32参考手册的TIM的结构框图):

  

    TIM_SelectInputTrigger(TIM2,TIM_TS_TI1FP1);                     //参考TIM结构图选择滤波后的TI1输入作为触发源,触发下面程序的复位

  

    TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Reset);         //复位模式-选中的触发输入(TRGI)的上升沿初始化计数器,并且产生一个更新线号

  

    TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);      

  //主从模式选择

  这样我们就可以很轻松的就得到了连接在TIM2的通道1上的信号的频率,但是3通道的频率的值永远都是跳动的不准,测试了半天也没有找到根本原因,请看TIM的结构框图的一部分

  红色箭头所指,这才找到原因,触发的信号源只有这四种,而通道3上的计数器的值不可能在接受到信号的上升沿时候,有复位这个动作,找到原因了。

这就是3通道上的数据不停跳动的原因,要想得到信号的频率也是有办法的,可以取连续两次捕捉的值之差,这个值就是信号的周期,自己根据实际情况去算频率吧。

  有以上可以得到:

  stm32的TIM2的四个通道可以同时配置成输入捕捉模式,但是计算CH3,CH4信号的频率步骤有点繁琐(取前后捕捉的差值),但是他的CH1,和CH2可以轻松得到:

  通道1

  

    TIM_SelectInputTrigger(TIM2,TIM_TS_TI1FP1);                     //参考TIM结构图选择滤波后的TI1输入作为触发源,触发下面程序的复位

  

    TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Reset);         //复位模式-选中的触发输入(TRGI)的上升沿初始化计数器,并且产生一个更新线号

  TIMx->CRR1的值即为信号的周期

  通道2:

    TIM_SelectInputTrigger(TIM2,TIM_TS_TI2FP2);                    //参考TIM结构图选择滤波后的TI1输入作为触发源,触发下面程序的复位

 

  

    TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Reset);         //复位模式-选中的触发输入(TRGI)的上升沿初始化计数器,并且产生一个更新线号

  TIMx->CRR2的值即为信号的周期

STM32的定时器外设功能强大得超出了想像力,STM32一共有8个都为16位的定时器。

其中TIM6、TIM7是基本定时器;TIM2、TIM3、TIM4、TIM5是通用定时器;TIM1和TIM8是高级定时器。

这些定时器使STM32具有定时、信号的频率测量、信号的PWM测量、PWM输出、三相6步电机控制及编码器接口等功能,都是专门为工控领域量身订做的。

       基本定时器:

具备最基本的定时功能,下面是它的结构:

我们来看看它的启动代码:

voidTIM2_Configuration(void)

{   基本定时器TIM2的定时配置的结构体(包含定时器配置的所有元素例如:

TIM_Period=计数值)

   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

   设置TIM2_CLK为72MHZ(即TIM2外设挂在APB1上,把它的时钟打开。

)      

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

   设置计数值位1000

   TIM_TimeBaseStructure.TIM_Period=1000;

   将TIM2_CLK为72MHZ除以72=1MHZ为定时器的计数频率

   TIM_TimeBaseStructure.TIM_Prescaler=71;

   这个TIM_ClockDivision是设置时钟分割,这里不分割还是1MHZ的计数频率

   TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

   设置为向上计数模式;(计数模式有向上,向下,中央对齐1,中央对齐2,中央对齐3)

   TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

   将配置好的设置放进stm32f10x-tim.c的库文件中

    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);

   清除标志位

    TIM_ClearFlag(TIM2,TIM_FLAG_Update);

   使能TIM2中断

   TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

   使能TIM2外设      

    TIM_Cmd(TIM2,ENABLE);                                                                                                

}

      通用定时器:

就比基本定时器复杂得多了。

除了基本的定时,它主要用在测量输入脉冲的频率、脉冲宽与输出PWM脉冲的场合,还具有编码器的接口。

我们来详细讲解:

如何生成PWM脉冲

通用定时器可以利用GPIO引脚进行脉冲输出,在配置为比较输出、PWM输出功能时,捕获/比较寄存器TIMx_CCR被用作比较功能,下面把它简称为比较寄存器。

这里直接举例说明定时器的PWM输出工作过程:

若配置脉冲计数器TIMx_CNT为向上计数,而重载寄存器TIMx_ARR(相当于库函数写法的TIM_Period的值N)被配置为N,即TIMx_CNT的当前计数值数值X在TIMxCLK时钟源的驱动下不断累加,当TIMx_CNT的数值X大于N时,会重置TIMx_CNT数值为0重新计数。

而在TIMxCNT计数的同时,TIMxCNT的计数值X会与比较寄存器TIMx_CCR预先存储了的数值A进行比较,当脉冲计数器TIMx_CNT的数值X小于比较寄存器TIMx_CCR的值A时,输出高电平(或低电平),相反地,当脉冲计数器的数值X大于或等于比较寄存器的值A时,输出低电平(或高电平)。

如此循环,得到的输出脉冲周期就为重载寄存器TIMx_ARR存储的数值(N+1)乘以触发脉冲的时钟周期,其脉冲宽度则为比较寄存器TIMx_CCR的值A乘以触发脉冲的时钟周期,即输出PWM的占空比为A/(N+1)。

如果不想看的可以直接看我标注的红色字体,就大体可以理解。

下面我们来编写具体代码和讲解:

voidTIM3_GPIO_Config(void)

{配置TIM3复用输出PWM的IO

  GPIO_InitTypeDefGPIO_InitStructure;

  打开TIM3的时钟

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

  打开GPIOA和GPIOB的时钟

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);

  配置PA6.PA7的工作模式

  GPIO_InitStructure.GPIO_Pin=  GPIO_Pin_6|GPIO_Pin_7;

  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;      

  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

  GPIO_Init(GPIOA,&GPIO_InitStructure);

  配置PB0.PB1的工作模式

  GPIO_InitStructure.GPIO_Pin=  GPIO_Pin_0|GPIO_Pin_1;

  GPIO_Init(GPIOB,&GPIO_InitStructure);

}

voidTIM3_Mode_Config(void)

{

       TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;//初始化TIM3的时间基数单位

       TIM_OCInitTypeDef  TIM_OCInitStructure;//初始化TIM3的外设

        u16CCR1_Val=500;      

        u16CCR2_Val=375;

        u16CCR3_Val=250;

        u16CCR4_Val=125;//PWM信号电平跳变值(即计数到这个数值以后都是低电平之前都是高电平)

  TIM3的时间基数单位设置(如计数终止值:

999,从0开始;计数方式:

向上计数)      

  TIM_TimeBaseStructure.TIM_Period=999;      

  TIM_TimeBaseStructure.TIM_Prescaler=0;         

  TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;      

  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

  TIM3的外设的设置

  TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;      //TIM脉冲宽度调制模式1   

  TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//这个暂时不知道,stm32固件库里没有搜到。

应该是定时器输出声明使能的意思      

  TIM_OCInitStructure.TIM_Pulse=CCR1_Val;//设置了待装入捕获比较寄存器的脉冲值      

  TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; //TIM输出比较极性高

  TIM_OC1Init(TIM3,&TIM_OCInitStructure);

      

  TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);//使能或者失能TIMx在CCR1上的预装载寄存器

  下面3路PWM输出和上面的一样不再解说

  TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;

  TIM_OCInitStructure.TIM_Pulse=CCR2_Val;      

  TIM_OC2Init(TIM3,&TIM_OCInitStructure);      

  TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);

  TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;

  TIM_OCInitStructure.TIM_Pulse=CCR3_Val;      

  TIM_OC3Init(TIM3,&TIM_OCInitStructure);      

  TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);

  TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;

  TIM_OCInitStructure.TIM_Pulse=CCR4_Val;      

  TIM_OC4Init(TIM3,&TIM_OCInitStructure);      

  TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(TIM3,ENABLE);       //使能TIM3重载寄存器ARR           

  TIM_Cmd(TIM3,ENABLE);//使能TIM3         

}

太累了边看边写都这个点了2014年7月27日0:

24:

13在自己床上写的。

下面是看看我们程序达到的4路PWM的效果:

可以看到明显占空比不同的4路pwm波。

这一节终于讲完,个人觉得敲一遍代码学起来还是蛮容易懂的。

希望看到的人也能搞懂。

最后补充一点pwm具体能干什么?

  特别是对广大电子DIY爱好者的应用:

智能小车的电机控制:

我们可以利用pwm来控制我们的智能小车的车速;

机器人:

给“机器人关节”舵机周期一定(我以前玩过具体多少毫秒忘记了)pwm波就可以控制舵机的转动角度了;

呼吸灯:

输入不同的pwm波就可以达到明暗渐明渐暗的

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1