OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10410|回复: 3

定时器时钟源的疑问,原子哥请进

[复制链接]

2

主题

7

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2012-3-9
在线时间
0 小时
发表于 2012-4-12 14:04:47 | 显示全部楼层 |阅读模式

由于做的下玩意需要使用到pwm输出,于是看了下《STM32不完全手册》PWM章节的内容,书中提到如果APB1的分频系数不为1,TIM2-TIM7的时钟为APB1的2倍。
TIMX的定时公式:Time = (arr * (psc + 1)) / SYSCLK        本开发板APB1的是分频系数为2,所以TIM2-TIM7的时钟源应该是72M
我现在需要使用到20KHz的PWM输出,我使用TIM2提供PWM,占空比调节范围为100,即arr为100,这样psc应该为36-1      分频后TIM2的时钟应该是72/36=2M
但是在使用过程中发现pwm的频率  并不是20K     用示波器一看是10K ,怀疑普通定时器的时钟源是72M吗
因为高级定时器TIM1由APB2提供时钟为72M,所以用同样的参数配置TIM1  相对比一下是否会产生同样频率的输出

配置的函数如下:
void MAL_Timer1PWM_Init(uint16 arr, uint16 psc)
{
     //Enable Timer2 Clock and GPIOA Clock
     APB2PeripheralClock_Enable(APB2PeripheralClock_TIM1);
     APB2PeripheralClock_Enable(APB2PeripheralClock_GPIOA);

     //GPIO config
     MAL_GPIO_Mode_Set(GPIO_A, GPIO_Mode_AF_PP, 8);     //PA_8 -> GPIO_Mode_AF_PP
     BIT_SET(GPIOA->BRR, 8);
    
     BIT_SET(TIM1->BDTR, 15);

     TIM1->ARR = arr;  
     TIM1->SC = psc;

     //PWM config CH1
     TIM1->CCMR1 |= 6<<4;            //OC1M  -> 110(PWM1)
     BIT_SET(TIM1->CCMR1, 3);       //OC1PE -> 1
     BIT_SET(TIM1->CCER, 0);         //OC1 -> 1

     BIT_SET(TIM1->CR1, 7);          //APRE Enable
     BIT_SET(TIM1->CR1, 0);          //Timer Enable
}

void MAL_Timer2PWM_Init(uint16 arr, uint16 psc)
{
     //Enable Timer2 Clock and GPIOA Clock
     APB1PeripheralClock_Enable(APB1PeripheralClock_TIM2);
     APB2PeripheralClock_Enable(APB2PeripheralClock_GPIOA);

     //GPIO config
     MAL_GPIO_Mode_Set(GPIO_A, GPIO_Mode_AF_PP, 1);     //PA_1 -> GPIO_Mode_AF_PP
     BIT_SET(GPIOA->BRR, 1);

     MAL_GPIO_Mode_Set(GPIO_A, GPIO_Mode_AF_PP, 2);   //PA_2 -> GPIO_Mode_AF_PP
     BIT_SET(GPIOA->BRR, 2);
    
     TIM2->ARR = arr;  
     TIM2->SC = psc;

     //PWM config CH2
     TIM2->CCMR1 |= 6<<12;    //OC2M  -> 110(PWM1)
     BIT_SET(TIM2->CCMR1, 11);   //OC2PE -> 1
     BIT_SET(TIM2->CCER, 4);    //OC2 -> 1


     BIT_SET(TIM2->CR1, 7);    //APRE Enable
     BIT_SET(TIM2->CR1, 0);    //Timer Enable


void Motor_RS380_Init(void)
{
     MAL_Timer1PWM_Init(100, 35);
     MAL_Timer2PWM_Init(100, 35);  

     TIM1->CCR1 = 50;           
     TIM2->CCR2 = 50;      
}

先通过Simulator模式看一下输出:


上面为TIM2  CH2产生的PWM
下面为TIM1  CH1产生的PWM

2个定时器的配置参数完全一样
同样50%的占空比
但是可以从图中看出TIM1输出的PWM
比TIM2输出的PWM频率高了1倍
从时间上来看  TIM1输出的频率是20K
TIM2输出的频率为10K

这样来算的TIM2的时钟源应该是36M啊
而不是72M
TIM1的时钟源是72M















再把开发板接到示波器上看一下




示波器也显示  TIM2输出的是10K   而TIM1刚好是TIM2的2倍

求原子哥以及各位高人讲解一下    TIM2的时钟源究竟是36M还是72M   还是我配置的哪里有问题

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-4-12 14:20:51 | 显示全部楼层
1,时钟频率直接可以在软件仿真的时候看到的.TIM2,你可以进去peripherals里面看.TIM1的也可以看.
2,你的函数都被你自己封装了一层,不太好说.你看看我们代码.虽然是tim3的,但是和tim2是基本完全一样,只需要看时钟初始化部分即可.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2012-3-9
在线时间
0 小时
 楼主| 发表于 2012-4-12 14:38:41 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
在初始化中 设置了  io模式  arr寄存器   psc寄存器  WM模式、使能位、输出位   启动定时器  应该没问题 
Time = (arr * (psc + 1)) / SYSCLK按照这个公式算下来的   arr = 100   psc = 35    如果按照72M来算的话应该是20K
但是实际是输出了10K          好郁闷啊
回复 支持 反对

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2012-3-9
在线时间
0 小时
 楼主| 发表于 2012-4-12 15:08:28 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
真是郁闷啊,总算找到原因了,我在初始化时钟的时候将APB1总线4分频了,这样TIM2-TIM7就是18M的2倍就是36M
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-22 09:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表