STM32实现PWM输出频率1kHz占空比50%的方波和呼吸灯

这篇具有很好参考价值的文章主要介绍了STM32实现PWM输出频率1kHz占空比50%的方波和呼吸灯。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

板子:野火指南者
芯片:STM32f103VET6
PWM通道:TIM3的通道1和通道3
GPIO:PA6和PB0


前言

本文主要讲需要怎么做,简要讲解原理,提供全部代码,有利于快速上手。


一、PWM输出1kHz方波的实现

1.选一个可以输出PWM的GPIO

打开STM32f103VET6的芯片数据手册,打开目录Pinouts and pindescriptions——High-density STM32F103xC/D/E pin definitions,如图所示。
STM32实现PWM输出频率1kHz占空比50%的方波和呼吸灯,stm32,单片机,嵌入式硬件

这里选择可以复用为TIM3通道1的PA6,如图所示。
STM32实现PWM输出频率1kHz占空比50%的方波和呼吸灯,stm32,单片机,嵌入式硬件

2.写代码:初始化GPIO

打开GPIOA的时钟和复用时钟,初始化PA6为复用推挽输出。

static void TIM3_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);//打开GPIO时钟和复用时钟
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;							//配置为复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

3.配置定时器模式

简要介绍一下部分参数。

首先是时基初始化结构体的TIM_Period,它代表定时器的计数周期,即时钟跳动多少次后溢出,这里赋值为1000-1。

其次是时基初始化结构体的TIM_Prescaler,它代表定时器的预分频系数,定时器的时钟是72MHz,所以这里填72-1,所以TIM3的时钟为72÷72=1MHz,时钟周期为10-6s,那么一个计数周期需要10-6x1000=10-3s,即频率为103Hz=1kHz。

最后是输出比较初始化结构体的TIM_Pulse,它代表比较值,在PWM模式1下,当定时器的计数值小于比较值时输出有效电平,例程中有效电平是低电平(TIM_OCPolarity_Low),这里设置比较值为500,而定时器的计数周期为1000,当计数值小于比较值500时输出低电平,大于500时输出高电平,而计数周期为10-3s,因此生成了频率为1kHz、占空比为50%的方波。

static void TIM3_Mode_Config(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	TIM_TimeBaseStructure.TIM_Period = (1000-1);       				//当定时器从0计数到 TIM_Period+1 ,为一个定时周期
  	TIM_TimeBaseStructure.TIM_Prescaler = (72-1);	    			//设置预分频
  	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;		//设置时钟分频系数:不分频(这里用不到)
  	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  	//向上计数模式
  	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;	    		//配置为PWM模式1
  	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//使能输出
  	TIM_OCInitStructure.TIM_Pulse = 500;				 			//设置初始PWM脉冲宽度为0	
  	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;  	  	//当定时器计数值小于比较值时为低电平

  	TIM_OC1Init ( TIM3, &TIM_OCInitStructure );	 					//使能通道,通道几就是OCx,例如通道2就是TIM_OC2Init
	

  	TIM_OC1PreloadConfig ( TIM3, TIM_OCPreload_Enable );			//使能预装载	

  	TIM_ARRPreloadConfig(TIM3, ENABLE);			 					//使能TIM重载寄存器ARR

  /* TIM3 enable counter */
  	TIM_Cmd(TIM3, ENABLE);
}

4.下载程序观察现象

STM32实现PWM输出频率1kHz占空比50%的方波和呼吸灯,stm32,单片机,嵌入式硬件

二、呼吸灯的实现

如果我们用PWM来控制LED,在一段波形中高电平占比越多,人眼看到LED就越亮,我们只要不停的改变高电平的占比,LED就会一会变亮一会变暗,就形成了呼吸灯。呼吸灯的编程要点就是使用定时器中断,实现每隔一定时间就进入中断改变PWM的比较值,使输出波形占空比不断变化。
这里我们选择可以复用为TIM3的通道3的PB0控制LED。
STM32实现PWM输出频率1kHz占空比50%的方波和呼吸灯,stm32,单片机,嵌入式硬件

1.计算获取PWM数据表

既然要在中断里经常改变PWM的占空比,总不可能实时计算吧,肯定需要提前计算好放入STM32中,需要时直接调用即可,我们可以采样在[0,10)范围下的2x和(10,20)2(20-x),在函数上取100个点。
STM32实现PWM输出频率1kHz占空比50%的方波和呼吸灯,stm32,单片机,嵌入式硬件
编写c语言函数如下。

#include <stdio.h>
#include <math.h>

int main()
{
	float i = 0;
	int indexWave[100], x=0;
	for(i=0;i<10;i+=0.2)
	{
		indexWave[x++]=(int)(pow(2,i));
	}
   for (x=0;x<=50;x++)
   {
	   printf("%d, ", indexWave[x]);
   }
	printf("\r\n");
	x=50;
   for(i=10;i<20;i+=0.2)
	{
		indexWave[x++]=(int)(pow(2,(20-i)));
	}
   for (x=51;x<100;x++)
   {
	   printf("%d, ", indexWave[x]);
   }

   return 0;
}

将打印出来的数据存入STM32。

2.初始化GPIO

同上

static void TIM3_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

3.配置NVIC

	NVIC_InitTypeDef NVIC_Initstructure;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	
	NVIC_Initstructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_Initstructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_Initstructure.NVIC_IRQChannelCmd = ENABLE;
	
	NVIC_Init(&NVIC_Initstructure);

4.配置TIM3模式

TIM_Period配置为1024-1,与PWM数据最大值相同。

	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	TIM_TimeBaseStructure.TIM_Period = (1024-1);       				//当定时器从0计数到 TIM_Period+1 ,为一个定时周期
  	TIM_TimeBaseStructure.TIM_Prescaler = (72-1);	    			//设置预分频
  	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;		//设置时钟分频系数:不分频(这里用不到)
  	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  	//向上计数模式
 	 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;	    		//配置为PWM模式1,CNT比比较值小为有效电平
  	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//使能输出
  	TIM_OCInitStructure.TIM_Pulse = 500;				 			//设置初始PWM脉冲宽度为0	
  	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;  	  	//当定时器计数值小于比较值时为低电平

  	TIM_OC3Init ( TIM3, &TIM_OCInitStructure );	 					//使能通道, 通道几就是OCx,例如通道2就是	TIM_OC2Init
	

  	TIM_OC3PreloadConfig ( TIM3, TIM_OCPreload_Enable );			//使能预装载	

  	TIM_ARRPreloadConfig(TIM3, ENABLE);			 					//使能TIM重载寄存器ARR

  /* TIM3 enable counter */
  	TIM_Cmd(TIM3, ENABLE);
	
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	
	TIM3_NVIC_Config();

总结

完整工程连接:百度网盘下载链接文章来源地址https://www.toymoban.com/news/detail-755687.html

到了这里,关于STM32实现PWM输出频率1kHz占空比50%的方波和呼吸灯的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包