你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103输出最高频率的疑问,请高手解答

[复制链接]
wwzx2513 提问时间:2016-12-3 10:39 /
void TIM2_NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
   
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    NVIC_InitStructure.NVIC_IRQChannel                      = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority    = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority           = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd                   = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}


/*
* 函数名:TIM2_GPIO_Config
* 描述  :配置TIM2复用输出PWM时用到的I/O
* 输入  :无
* 输出  :无
* 调用  :内部调用
*/
static void TIM2_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;   
   
    /* GPIOB clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
   
    /*GPIOA Configuration: TIM2 channel 1 and 2 as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;       // 推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/*
* 函数名:TIM2_Mode_Config
* 描述  :配置TIM3输出的PWM信号的模式,如周期、极性、占空比
* 输入  :无
* 输出  :无
* 调用  :内部调用
*/
static void TIM2_Mode_Config(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   
    /* TIM2 clock enable */
    //PCLK1经过2倍频后作为TIM2的时钟源等于72MHz
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
    TIM2_NVIC_Configuration();
    TIM_DeInit(TIM2);
    TIM_TimeBaseStructure.TIM_Period        = (1);                  /* 自动重装载寄存器周期的值(计数值) */
    /* 累计 TIM_Period个频率后产生一个更新或者中断 */
    TIM_TimeBaseStructure.TIM_Prescaler     = (1);                  /* 时钟预分频数 72M/1== 72MHZ */
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;         /* 采样分频 */
    TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;   /* 向上计数模式 */
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
//    TIM_ClearFlag(TIM2, TIM_FLAG_Update);                         /* 清除溢出中断标志 */
    TIM_Cmd(TIM2, ENABLE);                                          /* 开启时钟 */
}


中断里面引脚输出电压翻转


void TIM2_IRQHandler(void)
{        
        if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET )
        {               
                TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);
        
        if(i++)
        {
            i = 0;
            GPIO_ResetBits(GPIOB,GPIO_Pin_5);
        }
        else
        {
            GPIO_SetBits(GPIOB, GPIO_Pin_5);
        }
        
        }
}

如果用PWM频率最高只有72KHz,因为要保证1%的占空比,所以72M/100=720KHZ,但没有用PWM,直接控制引脚,频率应该更快才对,怎么只有280K,最多288K,频率是在示波器上看到的,实测PWM最高只能
到72KHZ,这又是怎么回事?


static void TIM3_Mode_Config(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;

    /* PWM信号电平跳变值 */
    u16 CCR1_Val = 500;        
    u16 CCR2_Val = 500;
    u16 CCR3_Val = 500;
    u16 CCR4_Val = 500;
//  u16 CR1_Val = 500;        
//  u16 CCR2_Val = 375;
//  u16 CCR3_Val = 250;
//  u16 CCR4_Val = 125;

/* -----------------------------------------------------------------------
    TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
    TIM3CLK = 72 MHz, Prescaler = 0x0, TIM3 counter clock = 72 MHz
    TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)
    TIM3 Frequency = 72 KHz.
    TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
    TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
    TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
    TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
  ----------------------------------------------------------------------- */
   
    /* Time base configuration */         
    TIM_TimeBaseStructure.TIM_Period        = (1000);           // 当定时器从0计数到999,即为1000次,为一个定时周期
    TIM_TimeBaseStructure.TIM_Prescaler     = 0;                    // 设置预分频:不预分频,即为72MHz
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;        // 设置时钟分频系数:不分频
    TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Down; // 向上计数模式
   
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
   
    /* PWM1 Mode configuration: Channel1 */
    TIM_OCInitStructure.TIM_OCMode          = TIM_OCMode_PWM1;      // 配置为PWM模式1
    TIM_OCInitStructure.TIM_OutputState     = TIM_OutputState_Enable;   
    TIM_OCInitStructure.TIM_Pulse           = CCR1_Val;             // 设置跳变值,当计数器计数到这个值时,电平发生跳变
    TIM_OCInitStructure.TIM_OCPolarity      = TIM_OCPolarity_High;  // 当定时器计数值小于CCR1_Val时为高电平
   
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);    // 使能通道1
   
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
   
    /* PWM1 Mode configuration: Channel2 */
    TIM_OCInitStructure.TIM_OutputState     = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse           = CCR2_Val;             // 设置通道2的电平跳变值,输出另外一个占空比的PWM
   
    TIM_OC2Init(TIM3, &TIM_OCInitStructure);    // 使能通道2
   
    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
   
    /* PWM1 Mode configuration: Channel3 */
    TIM_OCInitStructure.TIM_OutputState     = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse           = CCR3_Val;             // 设置通道3的电平跳变值,输出另外一个占空比的PWM
   
    TIM_OC3Init(TIM3, &TIM_OCInitStructure);    // 使能通道3
   
    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
   
    /* PWM1 Mode configuration: Channel4 */
    TIM_OCInitStructure.TIM_OutputState     = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse           = CCR4_Val;             // 设置通道4的电平跳变值,输出另外一个占空比的PWM
   
    TIM_OC4Init(TIM3, &TIM_OCInitStructure);    // 使能通道4
   
    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
   
    TIM_ARRPreloadConfig(TIM3, ENABLE);         // 使能TIM3重载寄存器ARR
   
    /* TIM3 enable counter */
    TIM_Cmd(TIM3, ENABLE);                      // 使能定时器3   
}


真有些晕了,新手,请高手指教
收藏 2 评论19 发布时间:2016-12-3 10:39

举报

19个回答
johnson_gong 回答时间:2016-12-28 09:52:58
PWM的实现与TIM定时器计时相关联,这个定时器的频率与系统时钟有关

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

wenyangzeng 回答时间:2016-12-28 19:36:12
本帖最后由 wenyangzeng 于 2016-12-28 20:14 编辑

    不小心用1块STM32F0 Discovery板子和ST官方代码试了一下,这个72KHZ占空比1%的PWM很轻松就达到了呀,而且一点也不占用STM32F0时间,STM32F0该干啥就干啥。如果按楼主的IO口翻转工作模式,STM32F0非累死不可。
      顺便讨论一下楼主的观点:“如果用PWM频率最高只有72KHz,因为要保证1%的占空比,所以72M/100=720KHZ”。
      其实要输出72KHZ占空比1%,你就调整PWM频率为72KHZ就好,干吗要720KHZ呢?你在72KHZ里弄出个1%的占空比(720/72000)不就OK了!

无标题.png
这个DEMO输出了4路不同占空比的72KHZ,这是PB0的输出。同时STM32F103主频是72MHZ,STM32F030主频是48MHZ.
IMG_1441.JPG
        这么窄的脉冲,连示波器都发“抖”了




TIM_PWMOutput.rar

下载

1.64 MB, 下载次数: 56, 下载积分: ST金币 -1

评分

参与人数 1ST金币 +5 收起 理由
zero99 + 5

查看全部评分

xmshao 回答时间:2016-12-28 09:36:41
pwm输出没理由才几十K,检查下代码,输出几M不是问题。

然后你如果GPIO翻转的话,就不能用函数调用了,那速度就上不去,要直接操作寄存器。

还有,你GPIO翻转是通过TIMER中断实现的,那GPIO翻转频率不就由TIMER的更新频率决定了吗?

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

小小超 回答时间:2016-12-28 08:51:05
实测STM32F103输出PWM可以去到1M的频率,估计楼主设置错了吧。还有,直接模拟输出PWM的频率,见过论坛上有过测试,最高翻转速度大约有4M左右。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

z258121131 回答时间:2016-12-28 09:07:00
顶                     
Dylan疾风闪电 回答时间:2016-12-28 09:12:57
本帖最后由 Dylan疾风闪电 于 2016-12-28 09:15 编辑

检查一下SYSCLK(系统时钟)配置的是多少,然后计算产生中断的周期。
可以考虑的是配置存在问题。
----------------------------------------------
如果对寄存器理解比较薄弱,可以使用cube配置一个工程进行测试。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

cldym 回答时间:2016-12-28 09:44:14
GPIO翻转是通过TIMER中断实现的,那GPIO翻转频率不就由TIMER的更新频率决定

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

wenyangzeng 回答时间:2016-12-28 09:49:14
中断里的几个if就要占去多少个机器时钟周期了,如何能够提高执行速度呢?

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

无薪税绵 回答时间:2016-12-28 10:05:19
楼主是用多大的晶振的。
会不会是外部晶振的问题?

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

yhyeefocus 回答时间:2016-12-28 11:06:28
看帖学习      
sting 回答时间:2016-12-28 11:19:45
pwm、手动翻转,傻傻分不清楚
zbber 回答时间:2016-12-28 12:04:38
PWM的实现与TIM定时器计时相关联,这个定时器的频率与系统时钟有关
peter001 回答时间:2016-12-28 13:44:44
除非程序只做io翻转,通过定时器中断内翻转频率肯定上不了很高,需要配置pwm自动输出才行

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

五哥1 回答时间:2016-12-28 16:39:48
把硬件也发上来,把测试条件发全。
12下一页

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版