下面文字介绍可能与代码关联不大,但是可以了解一下文字的解释为STM32的
一、PWM介绍
脉冲宽度调制是利用的数字输出来对电路进行控制的一种非常有效的技术,广泛应用在从测量、到功率控制与变换的许多领域中。
脉冲宽度调制是一种模拟控制方式,其根据相应载荷的变化来调制基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的对模拟电路进行控制的一种非常有效的技术。
PWM控制技术以其控制简单,灵活和动态响应好的优点而成为技术最广泛应用的控制方式,也是人们研究的热点。由于当今科学技术的发展已经没有了学科之间的界限,结合现代控制理论思想或实现无谐振波开关技术将会成为PWM控制技术发展的主要方向之一。其根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字信号对模拟电路进行控制的一种非常有效的技术。
二、如何确定PWM频率
PWM的周期(频率)就是ARR值与PSC寄存器值相乘得来,但不是简单意义上的相乘,例如要设置PWM的频率参考上次通用中设置溢出时间的,例如输出100HZ频率的PWM,首先,确定Mx的,除非APB1的时钟分频数设置为1,否则通用定时器TIMx的时钟是APB1时钟的2倍,这时的TIMx时钟为72MHz,用这个TIMx时钟72MHz除以(PSC+1),得到定时器每隔多少秒涨一次,这里给PSC赋7199,计算得定时器每隔0.0001秒涨一次,即此时频率为10KHz,再把这个值乘以(ARR+1)得出PWM频率,假如ARR值为0,即0.0001*(0+1),则输出PWM频率为10KHz,再假如输出频率为100Hz的PWM,则将ARR寄存器设置为99即可。如果想调整PWM占空比精度,则只需降低PSC寄存器的值即可。
TIMx_CCRx寄存器,
确定PWM的占空比。
TIMx_CCR1—TIMx_CCR4确定定时器的CH1—CH4四路PWM的占空比。直接给该寄存器赋0—65535值即可确定占空比。
占空比计算方法:TIMx_CCRx的值除以ARR寄存器的值即为占空比,因为占空比在0—100%之间,所以一般TIMx_CCRx寄存器值不能超过ARR寄存器的值,否则可能会引起PWM的频率或占空比的准确性。
三、pwm频率、pwm的值区别
脉冲宽度调制(PWM)是英文“Pulse Width Modulation”的缩写,简称脉宽调制。
PWM值是在一个周期内,开关管导通时间长短相加的平均值。导通时间越长,则直流输出的平均值越大;PWM频率是一个周期内,导通时间与周期时间的一个比值。通常叫作占空比。
导通次数越多,则频率越大。它们之间的区别在于:在输出不变的情况下,前者体现在导通时间长短上,后者体现在导通次数上。
责任编辑 LK
四、pico代码
/**************************************************************************************/
//PWM中断回调函数
void on_pwm_wrap(void)
{
pwm_clear_irq(pwm_gpio_to_slice_num(PWM1));//清中断
// static int fade = 0;
// static bool going_up = true;
// if (going_up)
// {
// ++fade;
// if (fade > 255)
// {
// fade = 255;
// going_up = false;
// }
// } else {
// --fade;
// if (fade < 0)
// {
// fade = 0;
// going_up = true;
// }
// }
// printf("fade:%d\r\n",fade);
// pwm_set_gpio_level(PWM1, fade*fade); //设置引脚电平
}
void PWM_Init(void)
{
// Tell the LED pin that the PWM is in charge of its value.
gpio_set_function(PWM1, GPIO_FUNC_PWM);
// Figure out which slice we just connected to the LED pin
uint slice_num = pwm_gpio_to_slice_num(PWM1);
// // Mask our slice's IRQ output into the PWM block's single interrupt line,
// // and register our interrupt handler--注册中断
// pwm_clear_irq(slice_num);
// pwm_set_irq_enabled(slice_num, true);
// irq_set_exclusive_handler(PWM_IRQ_WRAP, on_pwm_wrap);
// irq_set_enabled(PWM_IRQ_WRAP, true);
// Get some sensible defaults for the slice configuration. By default, the
// counter is allowed to wrap over its maximum range (0 to 2**16-1)
static pwm_config config;
config = pwm_get_default_config();
// Set divider, reduces counter clock to sysclock/this value--分频
// pwm_config_set_clkdiv(&config, 1.f);
// Load the configuration into our PWM slice, and set it running.
pwm_init(slice_num, &config, true);
pwm_set_gpio_level(PWM1, 100*100);//设置pwm电平
}