OpenEdv-开源电子网

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

STM32F407在FreeRTOS下配置TIM4无法输出PWM,但是TIM1可以

[复制链接]

2

主题

4

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2020-4-10
在线时间
9 小时
发表于 2023-10-27 23:14:40 | 显示全部楼层 |阅读模式
6金钱
STM32F407在FreeRTOS下配置TIM4无法输出PWM,但是TIM1可以
以下是配置文件.h
#ifndef __SERVO_H
#define __SERVO_H

#include "./SYSTEM/sys/sys.h"

#define SERVO_GPIOE_PORT                    GPIOE
#define SERVO_GPIOE_PIN9                    GPIO_PIN_9
#define SERVO_GPIOE_PIN11                   GPIO_PIN_11
#define SERVO_GPIOE_PIN13                   GPIO_PIN_13
#define SERVO_GPIOE_PIN14                   GPIO_PIN_14
#define SERVO_GPIOE_CLK_ENABLE()            do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)     /* PE口时钟使能 */
#define SERVO_GPIOE_AFTIM1                  GPIO_AF1_TIM1

#define SERVO_GPIOD_PORT                    GPIOE
#define SERVO_GPIOD_PIN12                   GPIO_PIN_12
#define SERVO_GPIOD_PIN13                   GPIO_PIN_13
#define SERVO_GPIOD_CLK_ENABLE()            do{ __HAL_RCC_GPIOD_CLK_ENABLE(); }while(0)     /* PD口时钟使能 */
#define SERVO_GPIOD_AFTIM4                  GPIO_AF2_TIM4

#define SERVO_TIM1                         TIM1
#define SERVO_TIM4                         TIM4

#define SERVO_TIM1_CH1                     TIM_CHANNEL_1                                 
#define SERVO_TIM1_CCR1                    SERVO_TIM1->CCR1                              

#define SERVO_TIM1_CH2                     TIM_CHANNEL_2                                   
#define SERVO_TIM1_CCR2                    SERVO_TIM1->CCR2                              

#define SERVO_TIM1_CH3                     TIM_CHANNEL_3                                   
#define SERVO_TIM1_CCR3                    SERVO_TIM1->CCR3                              

#define SERVO_TIM1_CH4                     TIM_CHANNEL_4                                   
#define SERVO_TIM1_CCR4                    SERVO_TIM1->CCR4                              

#define SERVO_TIM1_CLK_ENABLE()            do{ __HAL_RCC_TIM1_CLK_ENABLE(); }while(0)      /* TIM1 时钟使能 */

#define SERVO_TIM4_CH1                     TIM_CHANNEL_1                                 
#define SERVO_TIM4_CCR1                    SERVO_TIM4->CCR1                              

#define SERVO_TIM4_CH2                     TIM_CHANNEL_2                                 
#define SERVO_TIM4_CCR2                    SERVO_TIM4->CCR2                              

#define SERVO_TIM4_CLK_ENABLE()            do{ __HAL_RCC_TIM4_CLK_ENABLE(); }while(0)      /* TIM4 时钟使能 */

extern TIM_HandleTypeDef g_tim1_handler;
extern TIM_HandleTypeDef g_tim4_handler;

void SERVO1_init(uint16_t arr, uint16_t psc);   /* SERVO1初始化 */
void SERVO2_init(uint16_t arr, uint16_t psc);   /* SERVO2初始化 */


以下是配置文件.c
#include "./BSP/SERVO/servo.h"

TIM_HandleTypeDef g_tim1_handler;     /* 定时器1句柄 */
TIM_HandleTypeDef g_tim4_handler;     /* 定时器4句柄 */
TIM_OC_InitTypeDef g_tim1_ch1handler; /* 定时器1通道1句柄 */
TIM_OC_InitTypeDef g_tim1_ch2handler; /* 定时器1通道2句柄 */
TIM_OC_InitTypeDef g_tim1_ch3handler; /* 定时器1通道3句柄 */
TIM_OC_InitTypeDef g_tim1_ch4handler; /* 定时器1通道4句柄 */
TIM_OC_InitTypeDef g_tim4_ch1handler; /* 定时器1通道1句柄 */
TIM_OC_InitTypeDef g_tim4_ch2handler; /* 定时器1通道2句柄 */

void SERVO1_init(uint16_t arr, uint16_t psc)
{
    g_tim1_handler.Instance = SERVO_TIM1;                  /* 定时器1 */
    g_tim1_handler.Init.Prescaler = psc;                    /* 定时器分频 */
    g_tim1_handler.Init.CounterMode = TIM_COUNTERMODE_UP;   /* 向上计数模式 */
    g_tim1_handler.Init.Period = arr;                       /* 自动重装载值 */
    HAL_TIM_PWM_Init(&g_tim1_handler);                      /* 初始化PWM */

    g_tim1_ch1handler.OCMode = TIM_OCMODE_PWM1;                                         /* CH1/2 PWM模式1 */
    g_tim1_ch1handler.Pulse = arr / 2;                                                  
    g_tim1_ch1handler.OCPolarity = TIM_OCPOLARITY_HIGH;                                 
    HAL_TIM_PWM_ConfigChannel(&g_tim1_handler, &g_tim1_ch1handler, SERVO_TIM1_CH1);    /* 配置TIM1通道1 */
       
        g_tim1_ch2handler.OCMode = TIM_OCMODE_PWM1;                                         /* CH1/2 PWM模式1 */
    g_tim1_ch2handler.Pulse = arr / 2;                                                  
    g_tim1_ch2handler.OCPolarity = TIM_OCPOLARITY_HIGH;                                 /* 输出比较极性为高 */
        HAL_TIM_PWM_ConfigChannel(&g_tim1_handler, &g_tim1_ch2handler, SERVO_TIM1_CH2);    /* 配置TIM1通道2 */
       
        g_tim1_ch3handler.OCMode = TIM_OCMODE_PWM1;                                         /* CH1/2 PWM模式1 */
    g_tim1_ch3handler.Pulse = arr / 2;                                                  
    g_tim1_ch3handler.OCPolarity = TIM_OCPOLARITY_HIGH;                                 /* 输出比较极性为高 */
        HAL_TIM_PWM_ConfigChannel(&g_tim1_handler, &g_tim1_ch3handler, SERVO_TIM1_CH3);    /* 配置TIM1通道3 */
       
        g_tim1_ch4handler.OCMode = TIM_OCMODE_PWM1;                                         /* CH1/2 PWM模式1 */
    g_tim1_ch4handler.Pulse = arr / 2;                                                  
    g_tim1_ch4handler.OCPolarity = TIM_OCPOLARITY_HIGH;                                 /* 输出比较极性为高 */
        HAL_TIM_PWM_ConfigChannel(&g_tim1_handler, &g_tim1_ch4handler, SERVO_TIM1_CH4);    /* 配置TIM1通道4 */

    HAL_TIM_PWM_Start(&g_tim1_handler, SERVO_TIM1_CH1);    /* 开启PWM通道1 */
        HAL_TIM_PWM_Start(&g_tim1_handler, SERVO_TIM1_CH2);    /* 开启PWM通道2 */
        HAL_TIM_PWM_Start(&g_tim1_handler, SERVO_TIM1_CH3);    /* 开启PWM通道3 */
        HAL_TIM_PWM_Start(&g_tim1_handler, SERVO_TIM1_CH4);    /* 开启PWM通道4 */
       

}

void SERVO2_init(uint16_t arr, uint16_t psc)
{
        g_tim4_handler.Instance = SERVO_TIM4;                  /* 定时器4 */
    g_tim4_handler.Init.Prescaler = psc;                    /* 定时器分频 */
    g_tim4_handler.Init.CounterMode = TIM_COUNTERMODE_UP;   /* 向上计数模式 */
    g_tim4_handler.Init.Period = arr;                       /* 自动重装载值 */
    HAL_TIM_PWM_Init(&g_tim4_handler);                      /* 初始化PWM */
       
        g_tim4_ch1handler.OCMode = TIM_OCMODE_PWM1;                                         /* CH1/2 PWM模式1 */
    g_tim4_ch1handler.Pulse = arr / 2;                                                  
    g_tim4_ch1handler.OCPolarity = TIM_OCPOLARITY_HIGH;                                
    HAL_TIM_PWM_ConfigChannel(&g_tim4_handler, &g_tim4_ch1handler, SERVO_TIM1_CH1);    /* 配置TIM4通道1 */
       
        g_tim4_ch2handler.OCMode = TIM_OCMODE_PWM1;                                         /* CH1/2 PWM模式1 */
    g_tim4_ch2handler.Pulse = arr / 2;                                                
    g_tim4_ch2handler.OCPolarity = TIM_OCPOLARITY_HIGH;                                
        HAL_TIM_PWM_ConfigChannel(&g_tim4_handler, &g_tim4_ch2handler, SERVO_TIM1_CH2);    /* 配置TIM4通道2 */
       
        HAL_TIM_PWM_Start(&g_tim4_handler, SERVO_TIM4_CH1);    /* 开启PWM通道1 */
        HAL_TIM_PWM_Start(&g_tim4_handler, SERVO_TIM4_CH2);    /* 开启PWM通道2 */
}

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
    GPIO_InitTypeDef gpio_init_struct;

    if (htim->Instance == SERVO_TIM1)
    {
        SERVO_TIM1_CLK_ENABLE();           /* 使能定时器 */
        SERVO_GPIOE_CLK_ENABLE();           /* PWM DAC GPIO 时钟使能 */

        gpio_init_struct.Pin = SERVO_GPIOE_PIN9;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;
        gpio_init_struct.Pull = GPIO_PULLUP;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
        gpio_init_struct.Alternate = SERVO_GPIOE_AFTIM1;
        HAL_GPIO_Init(SERVO_GPIOE_PORT, &gpio_init_struct);         /* TIMX PWM CHY 引脚模式设置 */
               
                gpio_init_struct.Pin = SERVO_GPIOE_PIN11;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;
        gpio_init_struct.Pull = GPIO_PULLUP;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
        gpio_init_struct.Alternate = SERVO_GPIOE_AFTIM1;
        HAL_GPIO_Init(SERVO_GPIOE_PORT, &gpio_init_struct);         /* TIMX PWM CHY 引脚模式设置 */
               
                gpio_init_struct.Pin = SERVO_GPIOE_PIN13;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;
        gpio_init_struct.Pull = GPIO_PULLUP;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
        gpio_init_struct.Alternate = SERVO_GPIOE_AFTIM1;
        HAL_GPIO_Init(SERVO_GPIOE_PORT, &gpio_init_struct);         /* TIMX PWM CHY 引脚模式设置 */
               
                gpio_init_struct.Pin = SERVO_GPIOE_PIN14;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;
        gpio_init_struct.Pull = GPIO_PULLUP;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
        gpio_init_struct.Alternate = SERVO_GPIOE_AFTIM1;
        HAL_GPIO_Init(SERVO_GPIOE_PORT, &gpio_init_struct);         /* TIMX PWM CHY 引脚模式设置 */
    }
       
            if (htim->Instance == SERVO_TIM4)
    {
        SERVO_TIM4_CLK_ENABLE();           /* 使能定时器 */
        SERVO_GPIOD_CLK_ENABLE();           /* PWM DAC GPIO 时钟使能 */

        gpio_init_struct.Pin = SERVO_GPIOD_PIN12;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;
        gpio_init_struct.Pull = GPIO_PULLUP;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
        gpio_init_struct.Alternate = SERVO_GPIOD_AFTIM4;
        HAL_GPIO_Init(SERVO_GPIOD_PORT, &gpio_init_struct);         /* TIMX PWM CHY 引脚模式设置 */
               
                gpio_init_struct.Pin = SERVO_GPIOD_PIN13;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;
        gpio_init_struct.Pull = GPIO_PULLUP;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
        gpio_init_struct.Alternate = SERVO_GPIOD_AFTIM4;
        HAL_GPIO_Init(SERVO_GPIOD_PORT, &gpio_init_struct);         /* TIMX PWM CHY 引脚模式设置 */
               
    }
}


主函数man.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"

#include "./MALLOC/malloc.h"
#include "freertos_demo.h"

#include "./BSP/SERVO/servo.h"

int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
    delay_init(168);                    /* 延时初始化 */
    usart_init(115200);                 /* 串口初始化为115200 */
    SERVO1_init(20000-1, 168-1);
    SERVO2_init(10000-1, 84-1);


    freertos_demo();                    /* 运行FreeRTOS例程 */
}
初始化以后TIM1的四个通道正常输出PWM,但是TIM4不能,请问各位大佬是什么地方出了问题?

最佳答案

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

查GPIOD和TIM4寄存器
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

11

主题

2130

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4724
金钱
4724
注册时间
2015-1-10
在线时间
590 小时
发表于 2023-10-27 23:14:41 | 显示全部楼层
回复

使用道具 举报

2

主题

4

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2020-4-10
在线时间
9 小时
 楼主| 发表于 2023-10-30 16:43:33 | 显示全部楼层

#define SERVO_GPIOE_PORT                    GPIOE
#define SERVO_GPIOE_PIN9                    GPIO_PIN_9
#define SERVO_GPIOE_PIN11                   GPIO_PIN_11
#define SERVO_GPIOE_PIN13                   GPIO_PIN_13
#define SERVO_GPIOE_PIN14                   GPIO_PIN_14
#define SERVO_GPIOE_CLK_ENABLE()            do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)     /* PE口时钟使能 */
#define SERVO_GPIOE_AFTIM1                  GPIO_AF1_TIM1

#define SERVO_GPIOD_PORT                    GPIOE
#define SERVO_GPIOD_PIN12                   GPIO_PIN_12
#define SERVO_GPIOD_PIN13                   GPIO_PIN_13
#define SERVO_GPIOD_CLK_ENABLE()            do{ __HAL_RCC_GPIOD_CLK_ENABLE(); }while(0)     /* PD口时钟使能 */
#define SERVO_GPIOD_AFTIM4                  GPIO_AF2_TIM4
问题已找到#define SERVO_GPIOE_PORT 和#define SERVO_GPIOD_PORT都定义为了GPIOE,后者修改为GPIOD后解决
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-24 01:28

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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