硬汉嵌入式论坛

 找回密码
 立即注册
查看: 11572|回复: 12
收起左侧

[TIMER] STM32H7的定时器输出100MHz的PWM效果

  [复制链接]

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
121537
QQ
发表于 2018-4-29 02:47:13 | 显示全部楼层 |阅读模式
    测试PWM输出100MHz方波的效果,因为我的示波器是200MHz带宽,1Gsps采样率的,用来采样100MHz方波的话,仅可以采集到基波(一次谐波,100MHz),而三次谐波(300MHz),五次谐波(500MHz),以此类推都是采集不到的(幅值严重削弱),所以最终的采集应该就是一个标准的100MHz正弦波,实际测试效果完美,就是个100MHz的正弦波。
黄色的是波形,红色的是FFT幅值谱。


回复

使用道具 举报

57

主题

914

回帖

1085

积分

至尊会员

积分
1085
发表于 2018-4-29 09:41:07 | 显示全部楼层
硬汉你熬夜到几点啊。。。。
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
121537
QQ
 楼主| 发表于 2018-4-29 10:09:54 | 显示全部楼层
roguebear 发表于 2018-4-29 09:41
硬汉你熬夜到几点啊。。。。

晚3点,早8点
回复

使用道具 举报

731

主题

3832

回帖

6050

积分

论坛元老

自定义头衔

积分
6050
发表于 2018-5-1 09:38:44 | 显示全部楼层

保重龙体呀
回复

使用道具 举报

57

主题

914

回帖

1085

积分

至尊会员

积分
1085
发表于 2018-5-1 10:18:07 | 显示全部楼层

保重龙根啊
回复

使用道具 举报

1

主题

70

回帖

73

积分

初级会员

积分
73
发表于 2018-5-3 10:31:25 | 显示全部楼层

是 早3点,晚8点?
回复

使用道具 举报

7

主题

52

回帖

73

积分

初级会员

积分
73
发表于 2018-5-3 11:42:46 | 显示全部楼层
硬汉,真硬
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
121537
QQ
 楼主| 发表于 2018-12-13 18:09:05 | 显示全部楼层
备份下输出100MHz PWM的效果。


        /*##-1- 配置定时器外设 #######################################*/
        htim1.Instance = TIM1;
        htim1.Init.Prescaler = 0;
        htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
        htim1.Init.Period = 1;
        htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
        htim1.Init.RepetitionCounter = 0;
        htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
        
        /*##-2- 使能定时器 ##########################################*/
        if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
        {
                Error_Handler(__FILE__, __LINE__);
        }
        
        /* 配置模式 */
        sConfigOC.OCMode = TIM_OCMODE_PWM1;
        sConfigOC.Pulse = 1;
        sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
        sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
        sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
        sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
        sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
        if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
        {
                Error_Handler(__FILE__, __LINE__);
        }
        
         /* 配置PWM 通道 */
        sConfigOC.Pulse = htim1.Init.Period /2;
        if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
        {
                Error_Handler(__FILE__, __LINE__);
        }
        
        /* 开启PWM输出 */
        if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1) != HAL_OK)
        {
                Error_Handler(__FILE__, __LINE__);
        }


回复

使用道具 举报

3

主题

35

回帖

44

积分

新手上路

积分
44
发表于 2018-12-13 20:39:22 | 显示全部楼层
嗯嗯,保重龙体
回复

使用道具 举报

0

主题

4

回帖

4

积分

新手上路

积分
4
发表于 2018-12-19 14:55:28 | 显示全部楼层
牛气 牛气!讲讲吃啥能这样啊  硬汉  我们也要来一份
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2026-1-29 18:51:36 | 显示全部楼层
硬汉哥,为什么我用HRTIM输出30MHZ的方波都不行,固定50占空比的,输出出来的都是像三角形的,难道是探头的问题吗.。 还是因为用的是开发板,走线不规范导致的。示波器参数350MHz ,,2GSa/s

#include "./BSP/hf_pwm.h"

HRTIM_HandleTypeDef hhrtim;

void HF_PWM_Init(void)
{
    HRTIM_TimeBaseCfgTypeDef sTimeBaseCfg = {0};
    HRTIM_TimerCfgTypeDef sTimerCfg = {0};
    HRTIM_CompareCfgTypeDef sCompareCfg = {0};
    HRTIM_OutputCfgTypeDef sOutputCfg = {0};

    // 1. 开启时钟并复位模块
    __HAL_RCC_HRTIM1_CLK_ENABLE();
    __HAL_RCC_HRTIM1_FORCE_RESET();
    __HAL_RCC_HRTIM1_RELEASE_RESET();
    __HAL_RCC_GPIOA_CLK_ENABLE();
   
    // 2. 配置 GPIO: PA8 -> AF2 (HRTIM1_CHB2)
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_8;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF2_HRTIM1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // 3. HRTIM 基础初始化
    hhrtim.Instance = HRTIM1;
    hhrtim.Init.HRTIMInterruptResquests = HRTIM_IT_NONE;
    hhrtim.Init.SyncOptions = HRTIM_SYNCOPTION_NONE;
    HAL_StatusTypeDef status = HAL_HRTIM_Init(&hhrtim);
    if (status != HAL_OK) return;

    // 4. 配置主定时器 (Master Timer) - 有些版本需要主定时器初始化
    HRTIM_TimerCfgTypeDef sMasterTimerCfg = {0};
    sMasterTimerCfg.InterruptRequests = HRTIM_IT_NONE;
    sMasterTimerCfg.DMARequests = HRTIM_IT_NONE;
    sMasterTimerCfg.StartOnSync = HRTIM_SYNCSTART_DISABLED;
    sMasterTimerCfg.ResetOnSync = HRTIM_SYNCRESET_DISABLED;
    sMasterTimerCfg.DACSynchro = HRTIM_DACSYNC_NONE;
    sMasterTimerCfg.PreloadEnable = HRTIM_PRELOAD_ENABLED;
    sMasterTimerCfg.UpdateGating = HRTIM_UPDATEGATING_INDEPENDENT;
    sMasterTimerCfg.BurstMode = HRTIM_TIMERBURSTMODE_MAINTAINCLOCK;
    sMasterTimerCfg.RepetitionUpdate = HRTIM_UPDATEONREPETITION_DISABLED;
    HAL_HRTIM_WaveformTimerConfig(&hhrtim, HRTIM_TIMERINDEX_MASTER, &sMasterTimerCfg);

    // 5. 配置时基 (Time Base) - 关键:设置为连续模式
    sTimeBaseCfg.Period = 0xFFDF; // 初始周期
    sTimeBaseCfg.RepetitionCounter = 0;
    sTimeBaseCfg.PrescalerRatio = HRTIM_PRESCALERRATIO_DIV1;
    sTimeBaseCfg.Mode = HRTIM_MODE_CONTINUOUS;
    HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, &sTimeBaseCfg);

    // 5. 定时器 B 配置 (Timer B)
    sTimerCfg.InterruptRequests = HRTIM_TIM_IT_NONE;
    sTimerCfg.DMARequests = HRTIM_TIM_DMA_NONE;
    sTimerCfg.HalfModeEnable = HRTIM_HALFMODE_DISABLED;
    sTimerCfg.StartOnSync = HRTIM_SYNCSTART_DISABLED;
    sTimerCfg.ResetOnSync = HRTIM_SYNCRESET_DISABLED;
    sTimerCfg.DACSynchro = HRTIM_DACSYNC_NONE;
    sTimerCfg.PreloadEnable = HRTIM_PRELOAD_ENABLED;
    sTimerCfg.UpdateGating = HRTIM_UPDATEGATING_INDEPENDENT;
    sTimerCfg.UpdateTrigger = HRTIM_TIMUPDATETRIGGER_NONE;
    sTimerCfg.ResetTrigger = HRTIM_TIMRESETTRIGGER_NONE;
    sTimerCfg.ResetUpdate = HRTIM_TIMUPDATEONRESET_DISABLED;
    sTimerCfg.PushPull = HRTIM_TIMPUSHPULLMODE_DISABLED;
    sTimerCfg.FaultEnable = HRTIM_TIMFAULTENABLE_NONE;
    sTimerCfg.FaultLock = HRTIM_TIMFAULTLOCK_READWRITE;
    sTimerCfg.DeadTimeInsertion = HRTIM_TIMDEADTIMEINSERTION_DISABLED;
    sTimerCfg.DelayedProtectionMode = HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DISABLED;
    sTimerCfg.BurstMode = HRTIM_TIMERBURSTMODE_MAINTAINCLOCK;
    sTimerCfg.RepetitionUpdate = HRTIM_UPDATEONREPETITION_DISABLED;
    HAL_HRTIM_WaveformTimerConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, &sTimerCfg);

    // 6. 比较单元配置 (用于控制占空比)
    sCompareCfg.CompareValue = 0x7FFF;
    HAL_HRTIM_WaveformCompareConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, HRTIM_COMPAREUNIT_1, &sCompareCfg);

    // 7. 输出配置 (CHB2)
    sOutputCfg.Polarity = HRTIM_OUTPUTPOLARITY_HIGH;
    sOutputCfg.IdleMode = HRTIM_OUTPUTIDLEMODE_NONE;
    sOutputCfg.IdleLevel = HRTIM_OUTPUTIDLELEVEL_INACTIVE;
    sOutputCfg.FaultLevel = HRTIM_OUTPUTFAULTLEVEL_NONE;
    sOutputCfg.ChopperModeEnable = HRTIM_OUTPUTCHOPPERMODE_DISABLED;
    sOutputCfg.BurstModeEntryDelayed = HRTIM_OUTPUTBURSTMODEENTRY_REGULAR;
   
    // 设置输出逻辑:周期匹配时置高,比较匹配时复位
    sOutputCfg.SetSource = HRTIM_OUTPUTSET_TIMPER;   
    sOutputCfg.ResetSource = HRTIM_OUTPUTRESET_TIMCMP1;
    HAL_HRTIM_WaveformOutputConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, HRTIM_OUTPUT_TB2, &sOutputCfg);

    // 8. 设置初始频率并启动
    HF_PWM_Set_Freq(30000000);

    // 启动输出和计数器
    HAL_HRTIM_WaveformOutputStart(&hhrtim, HRTIM_OUTPUT_TB2);
    HAL_HRTIM_WaveformCountStart(&hhrtim, HRTIM_TIMERID_TIMER_B);
    HAL_HRTIM_WaveformCountStart(&hhrtim, HRTIM_TIMERID_MASTER); // 启动主定时器
   
    // 强制更新以生效
    HAL_HRTIM_SoftwareUpdate(&hhrtim, HRTIM_TIMERUPDATE_B | HRTIM_TIMERUPDATE_MASTER);
}

void HF_PWM_Set_Freq(uint32_t freq_hz)
{
    if (freq_hz == 0) return;

    // HRTIM 在 H743 上没有 DLL 32倍频,其计数频率等于 CPU 时钟 (400MHz)
    // Period = 400000000 / freq_hz
    uint32_t period = (uint32_t)(400000000ULL / freq_hz);
   
    if (period > 0xFFDF) period = 0xFFDF;
    if (period < 1) period = 1;

    __HAL_HRTIM_SETPERIOD(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, period);
    __HAL_HRTIM_SETCOMPARE(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, HRTIM_COMPAREUNIT_1, period / 2);
   
    // 强制更新寄存器以立即生效
    HAL_HRTIM_SoftwareUpdate(&hhrtim, HRTIM_TIMERUPDATE_B);
}

main文件涉及到的如下

// 3. 配置 HRTIM1 时钟源为 CPU 时钟 (400MHz)
    RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_HRTIM1;
    PeriphClkInitStruct.Hrtim1ClockSelection = RCC_HRTIM1CLK_CPUCLK;
    if (HAL_RCCEx_PeriphCLKConfig(&eriphClkInitStruct) != HAL_OK) Error_Handler();
805a94a227ef997b2a07bdaebf24fda5.jpg
89bcfab46aadc1c2562b04ac01d6793c.jpg
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2026-1-29 18:52:55 | 显示全部楼层
开发板是老师买的,是STM32H743IITX
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
121537
QQ
 楼主| 发表于 2026-1-30 00:54:04 | 显示全部楼层
778899 发表于 2026-1-29 18:52
开发板是老师买的,是STM32H743IITX

我这个是普通定时器测试的,你用TIM1,按照我8楼的代码测试下正常不

回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-3-14 07:32 , Processed in 0.460351 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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