打印

stm32 的通用定时器 输出比较

[复制链接]
11059|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
pkat|  楼主 | 2010-7-26 23:14 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
这几天一直在看stm32 的通用定时器,  对定时器的输出比较很是迷惑,主要有以下几点:

1、输出模式有 Timing、Active、InActive、Toggle 等几种模式, 这几种模式有什么区别? 或者说各有什么用途?

2、 根据TIMx_CCMR 中的OC1M 模式选择位(3位)配置,可以选择不同的输出模式(对应1中的),手册上说当计数   
     器与比较寄存器中值匹配时,可以对 OC1REF 进行保持,强制为高或低,翻转的动作 ;     

    问题是:OC1REF是什么?     手册上指出:OCx状态=OCxREF + 极性   

    这里的极性(通过初始化函数配置为高或者低)具体指什么?  输出管脚的状态是否就是Ocx的状态?  按照这个式子,只要极

性设置为高,OCx 不就一直为高吗?  


比如通道设置为 Active 模式,极性设置为High  ;  当匹配时,输出管脚的状态怎么判断?

   (我的理解: 如果OCx的状态就是输出管脚的状态,
    (1)通道设置为 Active模式-----匹配时强制OC1REF为高;
 (2)极性配置为High ;
    所以OCx = 高!即输出管脚就一直为高电平!  

这样理解肯定是不对的,结果是输出的是方波。 但是就是想不通
沙发
eydj2008| | 2010-7-27 08:01 | 只看该作者
反复看技术手册,看不明白,就多做几个试验,然后动动手,动动脑 你就明白了。以后的路还长呢!

使用特权

评论回复
板凳
香水城| | 2010-7-27 10:29 | 只看该作者
1)不知道你从哪里看的:输出模式有 Timing、Active、InActive、Toggle 等几种模式,我不知道你说的Timing是指什么,Active=比较成功后把OCxREF置为高,InActive=比较成功后把OCxREF置为低,Toggle==比较成功后把OCxREF的状态翻转。

2)请看手册上这张图:

在OC1REF之后有一个TIMx_CCER的CC1P控制位,控制着是把CC1REF直接输出到后面的输出使能电路(Output Enable Circuit),还是把CC1REF反相后再送到输出使能电路。手册上说的+极性,就是指的这个CCxP控制位。这里不是算术加法,而是增加的意思。

使用特权

评论回复
地板
bg4ajb| | 2010-7-27 11:41 | 只看该作者


问题是这个版本库的手册和3.x的版本库很多都对不上。
而3.x的版本库没有一个像样的英文和中文版的使用手册。:L

使用特权

评论回复
5
香水城| | 2010-7-27 11:46 | 只看该作者
你看的这个是V2的手册,3.x的手册是安装目录下的一个CHM文件:stm32f10x_stdperiph_lib_um.chm

使用特权

评论回复
6
香水城| | 2010-7-27 11:57 | 只看该作者
TIM_OCMode_Timing:在比较成功时不对输出引脚的状态产生影响,适合于做定时使用。

使用特权

评论回复
7
bg4ajb| | 2010-7-27 12:18 | 只看该作者
本帖最后由 bg4ajb 于 2010-7-27 12:31 编辑

参照3.0库写的例程为何只能进入TIM_IT_Update而不能进入TIM_IT_CC1
右边对应3.0库代码:
void Tim2_Init(void)
{
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;

  TIM_TimeBaseStructure.TIM_Period = 5000;// 1us * 50 000 = 50ms;TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_Prescaler = 35;// 36mhz /36 = 1mhz, =1us  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;//  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  /* Prescaler configuration */
  TIM_PrescalerConfig(TIM2, 256, TIM_PSCReloadMode_Immediate);// TIM_PrescalerConfig(TIM2, 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 = 500;// TIM_OCInitStructure.TIM_Pulse = CCR1_Val;  __IO uint16_t CCR1_Val = 49152;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OC1Init(TIM2, &TIM_OCInitStructure);
  TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);
  /* TIM IT enable */
  TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_Update, ENABLE);//  TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);我没有使用cc2,cc3,cc4
/* TIM2 enable counter */
  TIM_Cmd(TIM2, ENABLE);
}

中断处理
void TIM2_IRQHandler(void)
{
   uint8_t b;
   b=10;
   b=b+1;
   #ifdef _DEBUG_
   printf("TIM2_IRQHnadler Success!\n");
   #endif

if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
  #ifdef _DEBUG_
  printf("TIM2_IRQHnadler_Update Success!\n");
  #endif
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}

if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
{
  #ifdef _DEBUG_
  printf("TIM2_IRQHnadler_CC1 Success!\n");
  #endif
  TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
  TIM_Cmd(TIM2, DISABLE);
  
}
}

keil4.12 调试结果

ex_timebase.JPG (80.05 KB )

ex_timebase.JPG

使用特权

评论回复
8
香水城| | 2010-7-27 12:50 | 只看该作者
你看看TIM2_SR、TIM2_DIER和TIM2_CCMR1寄存器的内容。

使用特权

评论回复
9
bg4ajb| | 2010-7-27 13:21 | 只看该作者
keil 模拟的结果

ex_timebase_register.JPG (250.75 KB )

ex_timebase_register.JPG

使用特权

评论回复
10
香水城| | 2010-7-27 14:03 | 只看该作者
不要模拟,直接在芯片上跑。

使用特权

评论回复
11
bg4ajb| | 2010-7-27 14:13 | 只看该作者
发现了,是KEIL的BUG!

ex_timebase_hw.JPG (123.62 KB )

ex_timebase_hw.JPG

使用特权

评论回复
12
香水城| | 2010-7-27 14:36 | 只看该作者
不要模拟,直接在芯片上跑。
香水城 发表于 2010-7-27 14:03


记住我这句话!!  :lol

使用特权

评论回复
13
dfsa| | 2010-7-27 21:43 | 只看该作者
定时器这玩意是挺烦的,功能多,要慢慢看手册,实践一下

使用特权

评论回复
14
mcu520| | 2010-11-18 19:58 | 只看该作者
mark

使用特权

评论回复
15
mcu520| | 2010-11-18 19:58 | 只看该作者
mark

使用特权

评论回复
16
lxyppc| | 2010-11-18 21:26 | 只看该作者
调定时器,最好写了代码放硬件上跑,用示波器看波形
把各种模式都试试看,看看波形会有什么样的变化,这样再回头看手册就容易理解了

使用特权

评论回复
17
lxyppc| | 2010-11-18 21:28 | 只看该作者
调定时器,最好写了代码放硬件上跑,用示波器看波形
把各种模式都试试看,看看波形会有什么样的变化,这样再回头看手册就容易理解了

使用特权

评论回复
18
desomond| | 2011-7-29 15:33 | 只看该作者
TIM_OCMode_Timing:在比较成功时不对输出引脚的状态产生影响,适合于做定时使用。
香水城 发表于 2010-7-27 11:57

如若我用的是定时器通道1定时模式为TIM_OCMode_Timing模式,那么我通道1对应的引脚还可以用作其他输入输出吗?
按照香主的说法,我的理解是:此时timer只用作定时,并不作用于引脚,应该可以用作其他输入输出,不知理解是否正确

使用特权

评论回复
19
desomond| | 2011-7-29 16:08 | 只看该作者
输出比较模式

此项功能是用来控制一个输出波形,或者指示一段给定的的时间已经到时。 当计数器与捕获/比较寄存器的内容相同时,输出比较功能做如下操作:

● 将输出比较模式(TIMx_CCMRx寄存器中的OCxM位)和输出极性(TIMx_CCER寄存器中的CCxP位)定义的值输出到对应的引脚上。在比较匹配时,输出引脚可以保持它的电平(OCxM=000)、被设置成有效电平(OCxM=001)、被设置成无效电平(OCxM=010)或进行翻转(OCxM=011)。

● 设置中断状态寄存器中的标志位(TIMx_SR寄存器中的CCxIF位)。

● 若设置了相应的中断屏蔽(TIMx_DIER寄存器中的CCxIE位),则产生一个中断。

● 若设置了相应的使能位(TIMx_DIER寄存器中的CCxDE位,TIMx_CR2寄存器中的CCDS位选择DMA请求功能),则产生一个DMA请求。

说明书上是这样说的

使用特权

评论回复
20
木满天下| | 2011-11-25 15:00 | 只看该作者
Mark

使用特权

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

本版积分规则

196

主题

2726

帖子

0

粉丝