STM32F103输出最高频率的疑问

2019-07-14 16:00发布

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   
}


真有些晕了,新手,请高手指教
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
60user189
1楼-- · 2019-07-14 23:37
实测STM32F103输出PWM可以去到1M的频率,估计楼主设置错了吧。还有,直接模拟输出PWM的频率,见过论坛上有过测试,最高翻转速度大约有4M左右。
zhi168
2楼-- · 2019-07-15 05:15
顶                     
嘻嘻爱哈哈
3楼-- · 2019-07-15 07:35
 精彩回答 2  元偷偷看……
huazhe
4楼-- · 2019-07-15 10:52
pwm输出没理由才几十K,检查下代码,输出几M不是问题。

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

还有,你GPIO翻转是通过TIMER中断实现的,那GPIO翻转频率不就由TIMER的更新频率决定了吗?
andyfly7
5楼-- · 2019-07-15 11:30
GPIO翻转是通过TIMER中断实现的,那GPIO翻转频率不就由TIMER的更新频率决定
ctwewer
6楼-- · 2019-07-15 13:18
中断里的几个if就要占去多少个机器时钟周期了,如何能够提高执行速度呢?

一周热门 更多>