#include "User_PWMOut.h"
#include "hal.h"
#include "stm32f4xx_conf.h"
#include "stm32f4xx_rcc.h"
#include "conf_general.h"
// #define USERPWM_USE_HWPWM
// 使用硬件定时器会与VESC程序冲突,这里放弃使用硬件PWM
#ifdef USERPWM_USE_HWPWM
#define PERIOD_US 1000 // PWM信号周期
static void STM32_TIM3_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
// 设置引脚为复用输出功能
palSetPadMode(GPIOB, 4, PAL_MODE_ALTERNATE(GPIO_AF_TIM3) |
PAL_STM32_OSPEED_HIGHEST |
PAL_STM32_PUDR_FLOATING);
palSetPadMode(GPIOB, 5, PAL_MODE_ALTERNATE(GPIO_AF_TIM3) |
PAL_STM32_OSPEED_HIGHEST |
PAL_STM32_PUDR_FLOATING);
// 初始化TIM3
TIM_TimeBaseStructure.TIM_Period = PERIOD_US - 1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler = SYSTEM_CORE_CLOCK/1000000 - 1; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM3 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //根据指定的参数初始化外设TIM3 OC1
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据指定的参数初始化外设TIM3 OC2
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
TIM3->CNT = 0;
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}
static void STM32_TIM4_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器3时钟
//设置引脚为复用输出功能
palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(GPIO_AF_TIM4) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUDR_FLOATING);
//初始化TIM4
TIM_TimeBaseStructure.TIM_Period = PERIOD_US - 1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler = SYSTEM_CORE_CLOCK / 1000000 - 1; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM4, &TIM_OCInitStructure); //根据指定的参数初始化外设TIM3 OC1
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
TIM4->CNT = 0;
TIM_Cmd(TIM4, ENABLE); //使能TIM3
}
// 指定PWM序号与占空比
void UserPWM_SetDuty(int PWMNum, float Duty)
{
int CCR;
if (Duty < 0)
{
Duty = 0;
}
else if (Duty > 1)
{
Duty = 1;
}
CCR = (int)(Duty * PERIOD_US);
switch (PWMNum)
{
case 1:
TIM_SetCompare1(TIM3, CCR);
break;
case 2:
TIM_SetCompare2(TIM3, CCR);
break;
case 3:
TIM_SetCompare1(TIM4, CCR);
break;
default:
break;
}
}
// 使用硬件定时器时此函数不需要运行
void UserPWM_OutputCtrl(void)
{
;
}
// 初始化用户PWM
void UserPWM_Init(void)
{
STM32_TIM3_Init();
STM32_TIM4_Init();
UserPWM_SetDuty(1, 0.5f);
UserPWM_SetDuty(2, 0.5f);
UserPWM_SetDuty(3, 0.5f);
}
#else
#define PWM1_GPIOPORT GPIOB
#define PWM1_GPIOPIN 4
#define PWM2_GPIOPORT GPIOB
#define PWM2_GPIOPIN 5
#define PWM3_GPIOPORT GPIOB
#define PWM3_GPIOPIN 6
#define RGB_R_PWMNUM 2
#define RGB_G_PWMNUM 3
#define RGB_B_PWMNUM 1
// GPIO操作函数
#define PWM1_EN palSetPad(GPIOB, 4)
#define PWM1_DIS palClearPad(GPIOB, 4)
#define PWM2_EN palSetPad(GPIOB, 5)
#define PWM2_DIS palClearPad(GPIOB, 5)
#define PWM3_EN palSetPad(GPIOB, 6)
#define PWM3_DIS palClearPad(GPIOB, 6)
#define USERPWM_RESOLUTION 40 // PWM占空比分辨率
static int UserPWMCNT;
static int UserPWMCCR[3];
static int UserPWMCCR_PreLoad[3];
// 在FOC处理时顺便调用即可
void UserPWM_OutputCtrl(void)
{
if (UserPWMCNT < USERPWM_RESOLUTION - 1)
{
UserPWMCNT++;
if (UserPWMCNT == UserPWMCCR[0])
{
PWM1_DIS;
}
if (UserPWMCNT == UserPWMCCR[1])
{
PWM2_DIS;
}
if (UserPWMCNT == UserPWMCCR[2])
{
PWM3_DIS;
}
}
else
{
UserPWMCNT = 0;
UserPWMCCR[0] = UserPWMCCR_PreLoad[0];
UserPWMCCR[1] = UserPWMCCR_PreLoad[1];
UserPWMCCR[2] = UserPWMCCR_PreLoad[2];
if (UserPWMCCR[0] > 0)
PWM1_EN;
else
PWM1_DIS;
if (UserPWMCCR[1] > 0)
PWM2_EN;
else
PWM2_DIS;
if (UserPWMCCR[2] > 0)
PWM3_EN;
else
PWM3_DIS;
}
}
// 指定PWM序号与占空比
void UserPWM_SetDuty(int PWMNum, float Duty)
{
int CCR;
if (Duty < 0)
{
Duty = 0;
}
else if (Duty > 1)
{
Duty = 1;
}
CCR = (int)(Duty * USERPWM_RESOLUTION);
switch (PWMNum)
{
case 1:
UserPWMCCR_PreLoad[0] = CCR;
break;
case 2:
UserPWMCCR_PreLoad[1] = CCR;
break;
case 3:
UserPWMCCR_PreLoad[2] = CCR;
break;
default:
break;
}
}
// 按RGB进行占空比设定
void UserPWM_SetRGB(float R,float G,float B)
{
UserPWM_SetDuty(RGB_R_PWMNUM, R);
UserPWM_SetDuty(RGB_G_PWMNUM, G);
UserPWM_SetDuty(RGB_B_PWMNUM, B);
}
// 初始化用户PWM
void UserPWM_Init(void)
{
UserPWMCNT = 0;
UserPWMCCR[0] = 0;
UserPWMCCR[1] = 0;
UserPWMCCR[2] = 0;
UserPWMCCR_PreLoad[0] = 0;
UserPWMCCR_PreLoad[1] = 0;
UserPWMCCR_PreLoad[2] = 0;
palSetPadMode(PWM1_GPIOPORT, PWM1_GPIOPIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
PWM1_DIS;
palSetPadMode(PWM2_GPIOPORT, PWM2_GPIOPIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
PWM2_DIS;
palSetPadMode(PWM3_GPIOPORT, PWM3_GPIOPIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
PWM3_DIS;
}
#endif
RGB驱动.rar
需积分: 9 126 浏览量
2022-10-07
20:15:35
上传
评论
收藏 4KB RAR 举报
m0_73988179
- 粉丝: 0
- 资源: 2
最新资源
- 基于Typescript和PHP的编程知识储备库设计源码 - study-php
- Screenshot_2024-05-28-11-40-58-177_com.tencent.mm.jpg
- 基于Dart的Flutter小提琴调音器APP设计源码 - violinhelper
- 基于JavaScript和CSS的随寻订购网页设计源码 - web-order
- 基于MATLAB的声纹识别系统设计源码 - VoiceprintRecognition
- 基于Java的微服务插件集合设计源码 - wsy-plugins
- 基于Vue和微信小程序的监理日志系统设计源码 - supervisionLog
- 基于Java和LCN分布式事务框架的设计源码 - tx-lcn
- 基于Java和JavaScript的茶叶评级管理系统设计源码 - tea
- IMG_5680.JPG
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论0