STM32调制PWM生成三角波

STM32调制PWM生成三角波

​ 最近临近期末,课程电力电子大作业老师要求用单片机控制生成信号,经过H桥电路放大之后用RL电路滤波,负载两端的波形要求是三角波。要求不能用da直接输出,所以选用pwm调制的方式。

方案设计

​ 单片机选用stm32f103,用的是正点原子的板子啦。选32的原因就是32有专门的pwm控制器,功能非常的强大,相比51要用定时器自己写波形,方便的多。而且pwm的频率直接影响着生成波形的光滑程度。

程序框图

avatar

程序设计中用Time3的一个pwm通道来生成pwm波,然后用Time4来控制占空比的变化。

stm32生成pwm波的原理有很多博客写的很详细了,这里就不赘述了。

程序源码

主函数

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"
int i;
float pwmval;


 int main(void)
 {		
	u8 dir=1;
 	pwmval=99;	
	i=0;
	delay_init();	    	 //delay函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	 //设置NVIC中断分组2:2位抢占优先级,2位相应优先级
	uart_init(115200);	 //串口初始化115200
 	LED_Init();			     //LED端口初始化
 	TIM3_PWM_Init(99,71);	 //TIM3初始化 pwm频率=72000000/(71+1)/(99+1)=10Khz
	TIM4_Int_Init(99,71); //TIM4初始化 中断频率=72000000/(71+1)/(99+1) = 10Khz
   	while(1)
	{
												 
		TIM_SetCompare2(TIM3,pwmval);		   
	}	 
 }

//定时器4中断函数

void TIM4_IRQHandler(void)   //TIM4中断
{
	
	if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //检查TIM中断是否触发
		{
		TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIM4的中断待处理位
			i++;
			
			if(i<75)                           //前四分之三周期
				pwmval = pwmval-1.32;           //占空比递增到百分之一百
			else if(i=>75 && i<100)             //后四分之三周期
				pwmval = pwmval - 3.96;        //占空比递减至零
			else if(i == 100)                  
			{
				pwmval = 99;                   //重置占空比
				LED1=!LED1;                    //led闪烁,debug用
				i = 0;                         //计数重置
			}
		}
	
	
}

定时器中断函数

#include "timer.h"
#include "led.h"
#include "usart.h"

void TIM4_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能

	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动装载寄存器周期的值  
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //定时器时钟周期的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割TDTS=Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //初始化
 
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新

	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //抢占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC

	TIM_Cmd(TIM4, ENABLE);  //使能TIM4外设
							 
}





//TIM3pwm初始化
void TIM3_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	//使能定时器3时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
	
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //TIM3部分重映射 TIM3_CH2->PB5
 
   //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形GPIOB.5
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
 
   //初始化TIM3
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动装载寄存器周期的值  
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化
	
	//初始化TIM3 CH2 PWM
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCNPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //初始化

	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能CCR2上的预装载寄存器
 
	TIM_Cmd(TIM3, ENABLE);  
	

}

程序部分参考了很多正点原子的教学例程,用的是标准库。各种配置确实是有点繁琐,下一个项目可能会用HAL库尝试开发

H桥

​ 生成的PWM波形要变成想要的波形需要经过电感滤波,需要较大的电感和较大的电容,显然单片机的驱动能力的不够的,所以需要一个功率放大。

​ H桥选用的是L298N电机驱动芯片模块,市面上非常常见。

avatar

输出波形

负载的电流波形

avatar

avatar

负载的电压波形和电流波形对比

avatar

放大一点

avatar

总结

这次制作的稍微有点匆忙,毕竟是快要考试了,所以就忘了拍具体的硬件电路图

虽然制作之前就经过的仿真和理论学习,但是能够实际看到波形还是对这个理论有了更深刻的理解

STM32还是非常强大的,10k的pwm就可以看到非常漂亮的波形啦,相比51的波形要好看许多

程序比较简单,就写的有点随意了

鉴于本人水平有限,若文章中有错误的地方希望大家能帮我指正。

希望这篇文章对你们有帮助!

谢谢观看

考试了,所以就忘了拍具体的硬件电路图

虽然制作之前就经过的仿真和理论学习,但是能够实际看到波形还是对这个理论有了更深刻的理解

STM32还是非常强大的,10k的pwm就可以看到非常漂亮的波形啦,相比51的波形要好看许多

程序比较简单,就写的有点随意了

鉴于本人水平有限,若文章中有错误的地方希望大家能帮我指正。

希望这篇文章对你们有帮助!

谢谢观看

  • 9
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值