OpenEdv-开源电子网

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

求助,关于pwm发送脉冲问题

[复制链接]

1

主题

3

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2020-11-19
在线时间
17 小时
发表于 2021-1-26 22:21:25 | 显示全部楼层 |阅读模式
1金钱
我看了原子哥的pwm输出实验后,结合网上的一些资料,在stm32f407zgt6的芯片上做了一个能输出1HZ——1MHZ的程序,然后想要移植到stm32f407igt6芯片上,那个板子的晶振好像是12mhz的,然后输出现象是我的程序要输出1HZ的波形变成了1.5HZ的波形。然后我看百度说要改system_sm32f4xx.c  文件,将  #define HSE_BYPASS_INPUT_FREQUENCY   8000000改为了12000000,结果是程序是输出1HZ了,可是上线的1MHZ到不了了。改了半天也没成功,我试了半天好像只能达到800kHZ左右。有没有大佬知道这该怎么解决。代码如下:
#include "pwm.h"
#include "led.h"
#include "usart.h"


//TIM14 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM14_PWM_Init()
{                                                          
        //此部分需手动修改IO口设置
  uint32_t temp32;
  uint32_t uhTimerfrequency;
  uint16_t uhTimerPeriod;
  uint16_t uhTimerPulse;       
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);          //TIM14时钟使能   
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);         //使能PORTF时钟       
       
        GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOA7复用为定时器14
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //GPIOA7
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;        //速度100MHz
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
        GPIO_Init(GPIOF,&GPIO_InitStructure);              //初始化PA7


       
        uhTimerfrequency = 200000;
        temp32 = ((SystemCoreClock / 2) / uhTimerfrequency);
  if (temp32 > 65535)
                temp32 = 65535;
  uhTimerPeriod = (uint16_t) temp32;
  uhTimerPulse  = uhTimerPeriod * 50 / 100;
        TIM_TimeBaseStructure.TIM_Prescaler=0;  //定时器分频
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseStructure.TIM_Period=uhTimerPeriod-1;   //自动重装载值
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
       
        TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定时器14
       
        //初始化TIM14 Channel1 PWM模式         
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
        TIM_OC1Init(TIM14, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 4OC1

        TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);  //使能TIM14在CCR1上的预装载寄存器

  TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能
       
        TIM_Cmd(TIM14, ENABLE);  //使能TIM14

                                                                                  
}  


void StdPeriph_TIM14_PWM_Update(uint32_t TIM14_PWM_FQ,uint32_t TIM14_PWM_Pulse)
{
          uint32_t TIM14_PWM_FQ_Old  = 0;
          uint32_t TIM14_PWM_Pulse_Old = 0;
    uint32_t temp32;
    uint32_t uhTimerfrequency;
    uint32_t uhTimerPeriod;
    uint32_t uhTimerPrescaler;
    uint32_t uhTimerPulse;
    if ((TIM14_PWM_FQ_Old != TIM14_PWM_FQ) || (TIM14_PWM_Pulse_Old != TIM14_PWM_Pulse))
                        {
        TIM14_PWM_FQ_Old  =  TIM14_PWM_FQ;
        TIM14_PWM_Pulse_Old = TIM14_PWM_Pulse;
        if (TIM14_PWM_FQ >= 4000) {
            uhTimerfrequency = TIM14_PWM_FQ;  /* 定时器计时频率和PWM频率相等 */
            uhTimerPrescaler = 1;    /* 实际频率TIM14_PWM_FQ较大时,TIM14设置分频为1(不分频)   */
        } else {
            uhTimerfrequency = 4000; /* 实际频率TIM14_PWM_FQ较小时,和4000Hz的频率比较,看相差几倍 */
            uhTimerPrescaler = 4000 / TIM14_PWM_FQ;  /* 实际频率和4000相差的倍数作为TIM2的分频设置值 */
            uhTimerfrequency = uhTimerPrescaler * TIM14_PWM_FQ; /* TIM14分频后,计时周期变长,需要将uhTimerfrequency倍频  */
        }

        /* TIM14的周期要通过倍频uhTimerfrequency来计算,uhTimerPeriod = 84MHz / uhTimerfrequency */
        temp32 = ((SystemCoreClock / 2) / uhTimerfrequency);
        if (temp32 > 65535) temp32 = 65535;
        uhTimerPeriod = (uint16_t) temp32;

        if (TIM14_PWM_Pulse > 100) TIM14_PWM_Pulse = 100;
        uhTimerPulse = uhTimerPeriod * TIM14_PWM_Pulse / 100;

        TIM14->ARR  = uhTimerPeriod - 1;
        TIM14->PSC  = uhTimerPrescaler - 1;
        TIM14->CCR1 = uhTimerPulse;
        TIM14->EGR  = TIM_PSCReloadMode_Update;
    }
}


最佳答案

查看完整内容[请看2#楼]

直接把系统时钟改慢, 那AHB1的时钟也按比例的慢下来的, IO的速度会受AHB1时钟所限制的
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4105
金钱
4105
注册时间
2018-8-14
在线时间
696 小时
发表于 2021-1-26 22:21:26 | 显示全部楼层
直接把系统时钟改慢, 那AHB1的时钟也按比例的慢下来的, IO的速度会受AHB1时钟所限制的
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2020-11-19
在线时间
17 小时
 楼主| 发表于 2021-1-27 10:55:06 | 显示全部楼层
@正点原子 原子哥帮忙看一下啊
回复

使用道具 举报

3

主题

2178

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3323
金钱
3323
注册时间
2013-7-19
在线时间
195 小时
发表于 2021-1-27 18:57:17 | 显示全部楼层
用cubemx生成试试
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-28 21:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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