OpenEdv-开源电子网

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

关于输出比较产生特定占空比、相位差方波的问题

[复制链接]

2

主题

3

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2025-7-31
在线时间
5 小时
发表于 4 天前 | 显示全部楼层 |阅读模式
12金钱
大佬们,我在论坛上面看到一篇关于设置相位差的文章,就准备复现一下。
这篇文章:http://www.openedv.com/forum.php?mod=viewthread&tid=296687&highlight=%CF%E0%CE%BB%B2%EE我是准备输出四路占空比、相位差固定的脉冲,周期2us。但是最后输出结果周期快3us了,占空比和冲相位差也和自己预想的不一样,
代码来来回回改了好多遍,也没有找到问题,各位大佬能不能看看我的配置哪方面不对。
代码如下:
#include "./SYSTEM/delay/delay.h"
#include "stm32h750xx.h"
        GPIO_InitTypeDef gpio_init_struct = {0};//初始化GPIO的结构体
        TIM_HandleTypeDef g_tim6_int_handle = {0};//初始化定时器6的结构体
        TIM_HandleTypeDef g_tim3_int_handle = {0};//初始化定时器3的结构体
        TIM_OC_InitTypeDef tim3_oc_pwm_struct = {0};//定时器3通道配置
        //设置标志位
        uint8_t TIM3_CH1_Flag = 0;       
        uint8_t TIM3_CH2_Flag = 0;       
        uint8_t TIM3_CH3_Flag = 0;       
        uint8_t TIM3_CH4_Flag = 0;
void Mohe_init(void)
{
       
        //GPIO初始化
        //开启GPIO端口时钟
        S_TOTAL_GPIO_CLK_ENABLE();

        gpio_init_struct.Pin = S1_GPIO_PIN | S2_GPIO_PIN | S3_GPIO_PIN | S4_GPIO_PIN;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;
        gpio_init_struct.Pull = GPIO_NOPULL;//输出可以不设置上拉下拉
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM;
        gpio_init_struct.Alternate = GPIO_AF2_TIM3;
        HAL_GPIO_Init(S_TOTAL_GPIO_PORT, &gpio_init_struct);

        TIM3_CLK_ENABLE();//开启定时器时钟
        g_tim3_int_handle.Instance = TIM3;
        g_tim3_int_handle.Init.Prescaler = 1 - 1;                       /* 预分频系数 */
        g_tim3_int_handle.Init.CounterMode = TIM_COUNTERMODE_UP;    /* 计数模式 */
    g_tim3_int_handle.Init.Period = 65535;                    /* 重装载值 */
        g_tim3_int_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;//不分频
    g_tim3_int_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;//自动重载值不使能
    HAL_TIM_OC_Init(&g_tim3_int_handle);                      /* 定时器初始化 */
//        __HAL_TIM_ENABLE_IT(&g_tim3_int_handle, TIM_IT_UPDATE);                                  /* 使能定时器更新中断 */
        HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);                                        /* 配置中断优先级并使能中断 */
        HAL_NVIC_EnableIRQ(TIM3_IRQn);
        //定时器3的通道
        //TIM_CHANNEL_1
        tim3_oc_pwm_struct.OCMode = TIM_OCMODE_TOGGLE;                                            /* 输出翻转模式 */
    tim3_oc_pwm_struct.Pulse = 1 - 1 + 96;     //crr不能超过arr                                         /* 占空比 */
    tim3_oc_pwm_struct.OCPolarity = TIM_OCPOLARITY_LOW;                                     /* 有效电平 */
        tim3_oc_pwm_struct.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_OC_ConfigChannel(&g_tim3_int_handle, &tim3_oc_pwm_struct, TIM_CHANNEL_1);  /* 配置定时器PWM通道 */
    HAL_TIM_OC_Start_IT(&g_tim3_int_handle, TIM_CHANNEL_1);  
        //TIM_CHANNEL_2
       
        tim3_oc_pwm_struct.OCMode = TIM_OCMODE_TOGGLE;                                            /* 输出翻转模式 */
    tim3_oc_pwm_struct.Pulse = 109 - 1 + 96;     //crr不能超过arr                                         /* 占空比 */
    tim3_oc_pwm_struct.OCPolarity = TIM_OCPOLARITY_LOW;                                     /* 有效电平 */
        tim3_oc_pwm_struct.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_OC_ConfigChannel(&g_tim3_int_handle, &tim3_oc_pwm_struct, TIM_CHANNEL_2);  /* 配置定时器PWM通道 */
    HAL_TIM_OC_Start_IT(&g_tim3_int_handle, TIM_CHANNEL_2);  
        //TIM_CHANNEL_3
       
        tim3_oc_pwm_struct.OCMode = TIM_OCMODE_TOGGLE;                                            /* 输出翻转模式 */
    tim3_oc_pwm_struct.Pulse = 217 - 1 + 96;     //crr不能超过arr                                         /* 占空比 */
    tim3_oc_pwm_struct.OCPolarity = TIM_OCPOLARITY_LOW;                                     /* 有效电平 */
        tim3_oc_pwm_struct.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_OC_ConfigChannel(&g_tim3_int_handle, &tim3_oc_pwm_struct, TIM_CHANNEL_3);  /* 配置定时器PWM通道 */
    HAL_TIM_OC_Start_IT(&g_tim3_int_handle, TIM_CHANNEL_3);
        //TIM_CHANNEL_4

        tim3_oc_pwm_struct.OCMode = TIM_OCMODE_TOGGLE;                                            /* 输出翻转模式 */
    tim3_oc_pwm_struct.Pulse = 325 - 1 + 96;                                                                                                                - 1;     //crr不能超过arr                                         /* 占空比 */
    tim3_oc_pwm_struct.OCPolarity = TIM_OCPOLARITY_LOW;                                     /* 有效电平 */
        tim3_oc_pwm_struct.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_OC_ConfigChannel(&g_tim3_int_handle, &tim3_oc_pwm_struct, TIM_CHANNEL_4);  /* 配置定时器PWM通道 */
    HAL_TIM_OC_Start_IT(&g_tim3_int_handle, TIM_CHANNEL_4);  
}
//定时器3中断服务函数
void TIM3_IRQHandler(void)//定时器中断服务函数
{
    HAL_TIM_IRQHandler(&g_tim3_int_handle);
}
//定时器回调函数
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)//定时器回调函数
{
        uint32_t current_cnt = g_tim3_int_handle.Instance->CNT;
        uint32_t next_crr;
        if(htim->Instance == TIM3)
        {
                if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)       
                {
                        TIM3_CH1_Flag = !TIM3_CH1_Flag;
                        next_crr = current_cnt + (TIM3_CH1_Flag ? 96 : 384);
                        if(next_crr>65535)
                        {
                                next_crr -= 65536;
                        }
                        __HAL_TIM_SET_COMPARE(&g_tim3_int_handle, TIM_CHANNEL_1, next_crr);
                }
                else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)       
                {
                        TIM3_CH2_Flag = !TIM3_CH2_Flag;
                        next_crr = current_cnt + (TIM3_CH2_Flag ? 96 : 384);
                        if(next_crr>65535)
                        {
                                next_crr -= 65536;
                        }
                        __HAL_TIM_SET_COMPARE(&g_tim3_int_handle, TIM_CHANNEL_2, next_crr);
                }
                else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)       
                {
                        TIM3_CH3_Flag = !TIM3_CH3_Flag;
                        next_crr = current_cnt + (TIM3_CH3_Flag ? 96 : 384);
                        if(next_crr>65535)
                        {
                                next_crr -= 65536;
                        }
                        __HAL_TIM_SET_COMPARE(&g_tim3_int_handle, TIM_CHANNEL_3, next_crr);
                }
                else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)       
                {
                        TIM3_CH4_Flag = !TIM3_CH4_Flag;
                        next_crr = current_cnt + (TIM3_CH4_Flag ? 96 : 384);
                        if(next_crr>65535)
                        {
                                next_crr -= 65536;
                        }
                        __HAL_TIM_SET_COMPARE(&g_tim3_int_handle, TIM_CHANNEL_4, next_crr);
                }
        }
}

最佳答案

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

用定时器的主从模式完成,不要在中断中实现,内核参与了计算会消耗时间,导致时序慢慢的就会跟不上了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

466

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4650
金钱
4650
注册时间
2018-5-14
在线时间
982 小时
发表于 4 天前 | 显示全部楼层
用定时器的主从模式完成,不要在中断中实现,内核参与了计算会消耗时间,导致时序慢慢的就会跟不上了
回复

使用道具 举报

2

主题

3

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2025-7-31
在线时间
5 小时
 楼主| 发表于 3 天前 | 显示全部楼层
姚先起 发表于 2025-8-12 16:00
用定时器的主从模式完成,不要在中断中实现,内核参与了计算会消耗时间,导致时序慢慢的就会跟不上了

是这样的,我又试了试,频率高了就开始有误差
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-8-16 20:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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