GD32 PWM

PWM_F450.cpp

#include "PWM_F450.hpp"
#include "main.h"

bool flag = 0;

//PE9
void PWM_T0CH0_F450::Init(uint16_t _pwmFq)
{
	pwmfq = 20000;
	fullPwm = 8400;
	rcu_periph_clock_enable(RCU_GPIOE);
	gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9);
	gpio_af_set(GPIOE, GPIO_AF_1, GPIO_PIN_9);
	
	/* -----------------------------------------------------------------------
	TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles:
	TIMER1CLK = SystemCoreClock / 200 = 1MHz

	TIMER1 channel1 duty cycle = (4000/ 16000)* 100  = 25%
	TIMER1 channel2 duty cycle = (8000/ 16000)* 100  = 50%
	TIMER1 channel3 duty cycle = (12000/ 16000)* 100 = 75%
	----------------------------------------------------------------------- */
	timer_oc_parameter_struct timer_ocintpara;
	timer_parameter_struct timer_initpara;

	rcu_periph_clock_enable(RCU_TIMER0);
	rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);

	if (flag == 0)
	{
		timer_deinit(TIMER0);
		flag = 1;
	}
	timer_primary_output_config(TIMER0,ENABLE);
	/* TIMER1 configuration */
	timer_initpara.prescaler         = 99;
	timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
	timer_initpara.period            = 99;
	timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
	timer_initpara.repetitioncounter = 0;
	timer_init(TIMER0,&timer_initpara);

	/* CH1,CH2 and CH3 configuration in PWM mode */
	timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
	timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
	timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
	timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
	timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
	timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
	timer_channel_output_config(TIMER0,TIMER_CH_0,&timer_ocintpara);

	/* CH2 configuration in PWM mode1,duty cycle 50% */
	timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0,0);
	timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
	timer_channel_output_shadow_config(TIMER0,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);

	/* auto-reload preload enable */
	timer_auto_reload_shadow_enable(TIMER0);
	/* auto-reload preload enable */
	timer_enable(TIMER0);
}

void PWM_T0CH0_F450::StartPwM(void)
{
	
}

void PWM_T0CH0_F450::SetPWM(uint16_t _pwm)
{
  /* CH0 configuration in PWM mode1,duty cycle 25% */
	timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0,_pwm);
	timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
	timer_channel_output_shadow_config(TIMER0,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);
}

//PE11
void PWM_T0CH1_F450::Init(uint16_t _pwmFq)
{
	pwmfq = 20000;
	fullPwm = 8400;
	
	rcu_periph_clock_enable(RCU_GPIOE);
	gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_11);
	gpio_af_set(GPIOE, GPIO_AF_1, GPIO_PIN_11);
	
	/* -----------------------------------------------------------------------
	TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles:
	TIMER1CLK = SystemCoreClock / 200 = 1MHz

	TIMER1 channel1 duty cycle = (4000/ 16000)* 100  = 25%
	TIMER1 channel2 duty cycle = (8000/ 16000)* 100  = 50%
	TIMER1 channel3 duty cycle = (12000/ 16000)* 100 = 75%
	----------------------------------------------------------------------- */
	timer_oc_parameter_struct timer_ocintpara;
	timer_parameter_struct timer_initpara;

	rcu_periph_clock_enable(RCU_TIMER0);
	rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);

	if (flag == 0)
	{
		timer_deinit(TIMER0);
		flag = 1;
	}
	timer_primary_output_config(TIMER0,ENABLE);	
	/* TIMER1 configuration */
	timer_initpara.prescaler         = 99;
	timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
	timer_initpara.period            = 99;
	timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
	timer_initpara.repetitioncounter = 0;
	timer_init(TIMER0,&timer_initpara);

	/* CH1,CH2 and CH3 configuration in PWM mode */
	timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
	timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
	timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
	timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
	timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
	timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
	timer_channel_output_config(TIMER0,TIMER_CH_1,&timer_ocintpara);
	
	/* CH1 configuration in PWM mode1,duty cycle 25% */
	timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1,0);
	timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0);
	timer_channel_output_shadow_config(TIMER0,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);

	/* auto-reload preload enable */
	timer_auto_reload_shadow_enable(TIMER0);
	/* auto-reload preload enable */
	timer_enable(TIMER0);
}

void PWM_T0CH1_F450::StartPwM(void)
{
}

void PWM_T0CH1_F450::SetPWM(uint16_t _pwm)
{
   /* CH1 configuration in PWM mode1,duty cycle 25% */
	timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1,_pwm);
	timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0);
	timer_channel_output_shadow_config(TIMER0,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);
}

//PE13
void PWM_T0CH2_F450::Init(uint16_t _pwmFq)
{
	pwmfq = 20000;
	fullPwm = 8400;
	rcu_periph_clock_enable(RCU_GPIOE);
	gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_13);
	gpio_af_set(GPIOE, GPIO_AF_1, GPIO_PIN_13);
	
	/* -----------------------------------------------------------------------
	TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles:
	TIMER1CLK = SystemCoreClock / 200 = 1MHz

	TIMER1 channel1 duty cycle = (4000/ 16000)* 100  = 25%
	TIMER1 channel2 duty cycle = (8000/ 16000)* 100  = 50%
	TIMER1 channel3 duty cycle = (12000/ 16000)* 100 = 75%
	----------------------------------------------------------------------- */
	timer_oc_parameter_struct timer_ocintpara;
	timer_parameter_struct timer_initpara;

	rcu_periph_clock_enable(RCU_TIMER0);
	rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);

	if (flag == 0)
	{
		timer_deinit(TIMER0);
		flag = 1;
	}
	timer_primary_output_config(TIMER0,ENABLE);
	/* TIMER1 configuration */
	timer_initpara.prescaler         = 99;
	timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
	timer_initpara.period            = 99;
	timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
	timer_initpara.repetitioncounter = 0;
	timer_init(TIMER0,&timer_initpara);

	/* CH1,CH2 and CH3 configuration in PWM mode */
	timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
	timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
	timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
	timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
	timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
	timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
	timer_channel_output_config(TIMER0,TIMER_CH_2,&timer_ocintpara);

	/* CH2 configuration in PWM mode1,duty cycle 50% */
	timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2,0);
	timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0);
	timer_channel_output_shadow_config(TIMER0,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);

	/* auto-reload preload enable */
	timer_auto_reload_shadow_enable(TIMER0);
	/* auto-reload preload enable */
	timer_enable(TIMER0);
}

void PWM_T0CH2_F450::StartPwM(void)
{
}

void PWM_T0CH2_F450::SetPWM(uint16_t _pwm)
{
  timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2,_pwm);
	timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0);
	timer_channel_output_shadow_config(TIMER0,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);
}

//PE14
void PWM_T0CH3_F450::Init(uint16_t _pwmFq)
{
	pwmfq = 20000;
	fullPwm = 8400;
	rcu_periph_clock_enable(RCU_GPIOE);
	gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_14);
	gpio_af_set(GPIOE, GPIO_AF_1, GPIO_PIN_14);
	
	/* -----------------------------------------------------------------------
	TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles:
	TIMER1CLK = SystemCoreClock / 200 = 1MHz

	TIMER1 channel1 duty cycle = (4000/ 16000)* 100  = 25%
	TIMER1 channel2 duty cycle = (8000/ 16000)* 100  = 50%
	TIMER1 channel3 duty cycle = (12000/ 16000)* 100 = 75%
	----------------------------------------------------------------------- */
	timer_oc_parameter_struct timer_ocintpara;
	timer_parameter_struct timer_initpara;

	rcu_periph_clock_enable(RCU_TIMER0);
	rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);

	if (flag == 0)
	{
		timer_deinit(TIMER0);
		flag = 1;
	}
	timer_primary_output_config(TIMER0,ENABLE);
	/* TIMER1 configuration */
	timer_initpara.prescaler         = 99;
	timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
	timer_initpara.period            = 99;
	timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
	timer_initpara.repetitioncounter = 0;
	timer_init(TIMER0,&timer_initpara);

	/* CH1,CH2 and CH3 configuration in PWM mode */
	timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
	timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
	timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
	timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
	timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
	timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
	timer_channel_output_config(TIMER0,TIMER_CH_3,&timer_ocintpara);

	/* CH3 configuration in PWM mode1,duty cycle 75% */
	timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_3,0);
	timer_channel_output_mode_config(TIMER0,TIMER_CH_3,TIMER_OC_MODE_PWM0);
	timer_channel_output_shadow_config(TIMER0,TIMER_CH_3,TIMER_OC_SHADOW_DISABLE);

	/* auto-reload preload enable */
	timer_auto_reload_shadow_enable(TIMER0);
//	/* auto-reload preload enable */
	timer_enable(TIMER0);
}

void PWM_T0CH3_F450::StartPwM(void)
{
}

void PWM_T0CH3_F450::SetPWM(uint16_t _pwm)
{
  timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_3,_pwm);
	timer_channel_output_mode_config(TIMER0,TIMER_CH_3,TIMER_OC_MODE_PWM0);
	timer_channel_output_shadow_config(TIMER0,TIMER_CH_3,TIMER_OC_SHADOW_DISABLE);
}

PWM_F450.hpp

#pragma once

#include "bsp/bsp.hpp"

class PWM_T0CH0_F450 : public PWM
{
public:
    PWM_T0CH0_F450() {}
    void Init(uint16_t _pwmFq);
    void StartPwM(void);
    void SetPWM(uint16_t _pwm);
};


class PWM_T0CH1_F450 : public PWM
{
public:
    PWM_T0CH1_F450() {}
    void Init(uint16_t _pwmFq);
    void StartPwM(void);
    void SetPWM(uint16_t _pwm);
};


class PWM_T0CH2_F450 : public PWM
{
public:
    PWM_T0CH2_F450() {}
    void Init(uint16_t _pwmFq);
    void StartPwM(void);
    void SetPWM(uint16_t _pwm);
};


class PWM_T0CH3_F450 : public PWM
{
public:
    PWM_T0CH3_F450() {}
    void Init(uint16_t _pwmFq);
    void StartPwM(void);
    void SetPWM(uint16_t _pwm);
};

PWM

#pragma once

#include <stdint.h>

class PWM
{
    public:
    PWM(){}
    uint16_t fullPwm;
    uint16_t pwmfq;
    virtual void Init(uint16_t _pwmFq){}
    virtual void StartPwM(void){}
    virtual void SetPWM(uint16_t _pwm){}
};

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
电压源设计思路介绍: 1、改高精度电压源基于GD32F190设计完成。利用GD190内部的高精度OPAMP,对经过整流后的直流电压进行电压采样,对比取样后的电压,通过GD190内部的DAC控制场效应管的导通,从而控制输出电压的大小。 2、 另一方面,通过GD190内部12位的ADC对采样电压采样,然后将采样的结果显示到LCD5110,而且可以通过小红板上面的按键调节输出电压的大小。 GD32开发板资料汇总详见链接: 高精度电压源硬件设计框图:https://www.cirmall.com/circuit/3721/ 高电压源视频展示: 设计心得总结: 1、本案例的核心在于软件PWM的生成,100路8分辨率PWM输出对于普通单片机来说还是有一定的压力,还要同时处理DMX512数据的接收,得益于GD32F207的120M运行速度,可以在短时间内处理更多的指令,将100路PWM计数变量分成10组,通过轮流的方式更新每一组IO的计数变量,同时更新IO的状态,有效的减少中断处理的数据量,缩短处理时间,本案例中实现了8位分辨率400HZ以上的PWM输出,用来控制调光灯,完全不会出现闪烁的情况。串口中断方式接收DMX512数据帧,即时保存在DMX512的缓冲区中,按DMX512数据每秒40帧的更新速度,最多在第2帧数据到来时可以把当前状态更新到所控制的灯上。 2、本案例控制IO输出采用了数据表映射的方式,可以任意修改IO所对应DMX512数据字节,操作时读取数据表里的映射数据,直接操作GPIO控制寄存器,也有效的减少操作指令,提高了操作效率。 3、采用高频率的单片机模拟多路PWM的方式,取代市场上现有的使用FPGA的方案,在满足性能的同时有效的降低了产品的设计复杂程度和产品成本。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值