打印
[STM32F1]

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

[复制链接]
3928|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wwzx2513|  楼主 | 2016-12-3 10:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
第一次发贴,不知道要悬赏分数,导致直接结贴,现在重发,不知道违反规则没有。
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   
}


真有些晕了,新手,请高手指教
沙发
mmuuss586| | 2016-12-3 12:32 | 只看该作者
你另外一个帖子不是问过了吗?
还问;

1、改成PWM输出频率啊;
2、中断操作的话,中断代码改成寄存器,中断会受到其它影响:比如其它中断;

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
wwzx2513 + 1 赞一个!
板凳
wwzx2513|  楼主 | 2016-12-3 14:48 | 只看该作者
mmuuss586 发表于 2016-12-3 12:32
你另外一个帖子不是问过了吗?
还问;

1:还问的原因这个贴子第一句就说明了,看别人回复才知道要悬赏分才不结贴(结贴和不结贴的区别我还没有分清楚,不是都能回复吗?)
2:PWM输出的频率没中断直接控制IO口的频率高,pwm72K,直接控制IO口280K;
3:代码改成寄存器肯定会快,但不会有几十M的差距,所以不用试了;
4:中断受其它中断影响,程序中只开了个SysTick_Init(),可能是受它影响了,但关了它程序不能运行了,单独开SystemInit()也不能运行,再试试

使用特权

评论回复
地板
Xflyan| | 2016-12-3 14:57 | 只看该作者
/* 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; // 向上计数模式

红色部分就是控制频率的,设置的是72K,当然输出72K了
把1000改成100,把CCRx_Val = 500 的,改成 50,看看是不是 720K了

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
wwzx2513 + 3 很给力!
5
wwzx2513|  楼主 | 2016-12-3 15:39 | 只看该作者
Xflyan 发表于 2016-12-3 14:57
/* Time base configuration */         
    TIM_TimeBaseStructure.TIM_Period        = (1000);         ...

我知道那是控制频率的,我曾经把 TIM_TimeBaseStructure.TIM_Period  改成 = 1,但忘记改CCRx_Val了,改了后正常,CCRx_Val不能大于TIM_Period设定的值,一粗心忘记改了,谢谢Xflyan,非常感谢回复的各位坛友,现在PWM能达到M级了,但直接控制IO口还不能,还要搞明白是怎么一回事,再次感谢Xflyan!

使用特权

评论回复
6
wwzx2513|  楼主 | 2016-12-3 15:46 | 只看该作者
再问一下怎么结贴,有20积分怎么给回复者

使用特权

评论回复
7
mmuuss586| | 2016-12-3 15:54 | 只看该作者
wwzx2513 发表于 2016-12-3 15:46
再问一下怎么结贴,有20积分怎么给回复者

给不给分数也没什么用;

280K和你的720K误差是有点大,你用中断输出1K频率看误差多少,如果误差小,那说明时钟的分频,计算方式是对的;

使用特权

评论回复
8
mmuuss586| | 2016-12-3 16:00 | 只看该作者
另外你定时器2时钟分频和计数器值都是1,按理可以输出频率可以到1M以上呢;
你实际用的都是1?

使用特权

评论回复
9
wwzx2513|  楼主 | 2016-12-3 16:16 | 只看该作者
mmuuss586 发表于 2016-12-3 15:54
给不给分数也没什么用;

280K和你的720K误差是有点大,你用中断输出1K频率看误差多少,如果误差小,那说 ...

    /* PWM信号电平跳变值 */
    u16 CCR1_Val = 3600;        
    u16 CCR2_Val = 3600;
    u16 CCR3_Val = 3600;
    u16 CCR4_Val = 3600;

    /* Time base configuration */         
    TIM_TimeBaseStructure.TIM_Period        = (7200 - 1);           // 当定时器从0计数到999,即为1000次,为一个定时周期
    TIM_TimeBaseStructure.TIM_Prescaler     = 9;                    // 设置预分频:不预分频,即为72MHz



PWM输出1K频率用示波器实测1.00020KHz,时钟的分频是没有问题的,TIM3运行也是正常的,只是昨天忘记改跳变值CCR1_Val了,现在能输出MHZ以上了,TIM2控制IO口输出的频率还有问题,只有280多KHZ

使用特权

评论回复
10
xyz549040622| | 2016-12-3 18:59 | 只看该作者
发帖一天后,在提醒下面有未结帖的,点击进去,分配分数,结贴就好了。

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
wwzx2513 + 3 很给力!
11
天云VC| | 2016-12-4 09:20 | 只看该作者
学习了

使用特权

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

本版积分规则

3

主题

239

帖子

1

粉丝