STM32定时器输出PWM

最新更新时间:2022-01-18来源: eefocus关键字:STM32  定时器输出  PWM 手机看文章 扫描二维码
随时随地手机看文章

一、PWM

1.定义

英文全称:PULSE WIDTH MODULATION,脉冲宽度调制。

脉冲:频率,方波

宽度:占空比(duty),高电平的宽度


2.用途

(1)控制输出的电压和电流

(2)灯光的亮度

(3)电机


二、编程细节

PWM输出是没有中断触发的,PWM由硬件输出波形,用了中断反而会影响系统定时的效率。


所以,记住以后使用定时器输出PWM都不需要使用到中断


1.如配置STM32F407的TIM14的通道1,10ms即100Hz.


1ms = 0.01s=100HZ

84000000 /8400 = 10000

10000/x = 100

x=100

得到周期8400-1,分频系数10-1


基本配置如下

2.然后还要再配置定时器的输出功能,可以参考固件库手册的例子TIM_PWMOutPut,

这里涉及到了一个寄存器

TIMx_CCMR1:capture/compare mode register 1 --捕获/比较模式寄存器1

在这里插入图片描述

从上图可以看出,我们设置占空比是可以动态调整的,关键就在于设置中间这个比较值的大小。

我们会使用到下面这个函数设置TIMx通道1比较值函数,如果使用到通道2,改1为2即可。

假如100hz内,比较值设置为80hz,那么0-79为高电平,80-100为低电平。


void TIM_SetCompare1(TIM_TypeDef* TIMx,uint16_t Comarex);


/* PWM1 Mode configuration: Channel1 */

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//pwm模式1,解释如上图所示

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//允许输出

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//有效的时候,输出高电平

TIM_OC1Init(TIM14, &TIM_OCInitStructure);

TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);//因为要周期性输出,所以要自动重装载初值,不断输出PWM脉冲

TIM_ARRPreloadConfig(TIM14,ENABLE);//自动重载使能


3.下面讲一下设置gpio的注意事项

(1)将引脚设置为复用功能

(2)将引脚与定时器进行绑定,告知是复用定时器功能


GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM14);


(3)最好是按照固件库手册的例程来写,有些定时器使能需要配置下面这个函数


TIM_CtrlPWMOutputs(TIM1,ENABLE);


4.主函数部分


uint32_t pwm_cmp = 0;//新建一个比较值

添加两个延时函数


while(1)

{

for(pwm_cmp =1;pwm_cmp<100;pwm_cmp++)

{

//设置比较值,查看所接的LED渐灭,因为0点亮

//如果想要渐亮,设置pwm_cmp为从100--1即可

TIM_SetCompare1(TIM14,pwm_cmp);

delay_ms(10);

}

for(pwm_cmp=99;pwm_cmp>0;pwm_cmp--)

{

TIM_SetCompare1(TIM14,pwm_cmp);

delay_ms(10);

}

}


下面是使用野火开发板STM32F429写的PWM输出


#include "stm32f4xx.h"



//R 红色灯

#define LED1_PIN                  GPIO_Pin_10                 

#define LED1_GPIO_PORT            GPIOH                      

#define LED1_GPIO_CLK             RCC_AHB1Periph_GPIOH


static __IO u32 TimingDelay;

 

/**

  * @brief  启动系统滴答定时器 SysTick

  * @param  无

  * @retval 无

  */

void SysTick_Init(void)

{

/* SystemFrequency / 1000    1ms中断一次

* SystemFrequency / 100000 10us中断一次

* SystemFrequency / 1000000 1us中断一次

*/

if (SysTick_Config(SystemCoreClock / 100000))

/* Capture error */ 

while (1);

}

}


/**

  * @brief   us延时程序,10us为一个单位

  * @param  

  * @arg nTime: Delay_us( 1 ) 则实现的延时为 1 * 10us = 10us

  * @retval  无

  */

void Delay_us(__IO u32 nTime)

TimingDelay = nTime;


while(TimingDelay != 0);

}


/**

  * @brief  获取节拍程序

  * @param  无

  * @retval 无

  * @attention  在 SysTick 中断函数 SysTick_Handler()调用

  */

void TimingDelay_Decrement(void)

{

if (TimingDelay != 0x00)

TimingDelay--;

}

}


/*

1-初始化LED灯所在的GPIO引脚


PH10  定时器5的CH1 


2-查看说明手册,判断定时器是否有输出功能


16 位(TIM3 和 TIM4)或 32 位(TIM2 和 TIM5) 递增、递减和递增/递减自动重载计 

数器。

说明可用


3-编写GPIO初始化

4-编写定时器初始化

5-主函数调用

*/

void tim14_init(void)

{

/*定义一个GPIO_InitTypeDef类型的结构体*/

GPIO_InitTypeDef          GPIO_InitStructure;

TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;

TIM_OCInitTypeDef TIM_OCInitStructure;

/*开启LED相关的GPIO外设时钟*/

RCC_AHB1PeriphClockCmd ( LED1_GPIO_CLK, ENABLE); 

RCC_APB1PeriphClockCmd ( RCC_APB1Periph_TIM5, ENABLE); 


GPIO_PinAFConfig(GPIOH,GPIO_PinSource10,GPIO_AF_TIM5);

GPIO_InitStructure.GPIO_Pin = LED1_PIN; /*选择要控制的GPIO引脚*/

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;    /*设置引脚模式为输出模式*/

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;    /*设置引脚的输出类型为推挽输出*/

        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;    /*设置引脚为上拉模式*/

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; /*设置引脚速率为2MHz */   

GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure); /*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/

//90Mhz 设置到100HZ输出,90000000/9000/100 = 100hz

TIM_TimeBaseStructure.TIM_Period = 100-1;

  TIM_TimeBaseStructure.TIM_Prescaler = 9000-1;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OC1Init(TIM5,&TIM_OCInitStructure);

TIM_OC1PreloadConfig(TIM5,TIM_OCPreload_Enable);

TIM_ARRPreloadConfig(TIM5,ENABLE);

// 使能定时器

TIM_Cmd(TIM5, ENABLE);


}


int main(void)

{

uint32_t pwm_cmp = 0;//新建一个比较值

SysTick_Init();

tim14_init();


while(1)

{

for(pwm_cmp =1;pwm_cmp<100;pwm_cmp++)

{

//设置比较值,查看所接的LED渐灭,因为0点亮

//如果想要渐亮,设置pwm_cmp为从100--1即可

TIM_SetCompare1(TIM5,pwm_cmp);

Delay_us(5000);    // 1000 * 10us = 100ms

}

for(pwm_cmp=99;pwm_cmp>0;pwm_cmp--)

{

TIM_SetCompare1(TIM5,pwm_cmp);

Delay_us(5000);    // 100 * 10us = 1000us = 1ms    *100 = 100ms

}

}

}



/*********************************************END OF FILE**********************/


在stm32f4xx_it.c


void SysTick_Handler(void)

{

TimingDelay_Decrement();

}

关键字:STM32  定时器输出  PWM 编辑:什么鱼 引用地址:STM32定时器输出PWM

上一篇:STM32独立看门狗(宠物狗)
下一篇:STM32系统嘀嗒定时器实现1ms中断事件

推荐阅读

STM32学习日志——CAN通信实验
1、概述CAN是Controller Area Network的缩写,是ISO的国际标准化的串行通信协议。在当前的汽车产业中,有各种各样的电子控制系统,这些系统之间所用的数据类型及对可靠性的要求不尽相同。1986年电气商博世公司开发出面向汽车的CAN通信协议。现在,CAN的高性能和可靠性已被认同,并被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面。CAN控制器根据两根线上的电位差来判断总线电平。总线电平分为显性电平和隐形电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。CAN的特点:多主控制。总线空闲时,所有单元都可以发送消息;最先访问总线的单元优先;同时发送看ID优先级。消息的发送。所有消息以固定的格式
发表于 2023-01-13
STM32学习日志——基于NT35510驱动芯片的LCD屏显示
之前写过关于LCD屏的学习日志,当时学得很懵逼,最后先暂时跳过,把教材的例程当成库函数来用,等后面开窍了再回过头来学习一遍。回想大学学习51单片机的时候,也是觉得LCD屏很困难,我觉得新手很容易就在这里从就入门到放弃了,因为相比前面的知识,个人认为LCD算是一个比较复杂的外设,难度有阶梯式的上升。再加上学习的教材为了兼容各种驱动芯片,程序看起来比较乱。所以这次单把NT35100这款驱动芯片拎出来分析学习。这里使用的是ATK-4.3'TFTLCD模块,他是采用NT35510芯片驱动,分辨率为800*480,自带GRAM。ATK-4.3’ TFTLCD模块正面图一、引脚与GRAM它一共有34个引脚。原理图及引脚功能如下。因为LC
发表于 2023-01-13
STM32学习日志——按键的单击、双击、长按
前两天去面试的时候,面试官看了我的业余小设计,问了个问题,怎么实现按键的双击,当时的设计只有单击和长按的功能,当时没回答出来。回来后看了下资料,整理并尝试了一下。大概的思路是这样的,单击与长按的区别在于按下后弹起时间的长短,如果按键一直按着,且大于一个时间值,判断为长按;否则为非长按,那么就要继续判断是单击还是双击,区别在于弹起后的一个较短时间内是否再次被按下,如果是,则为双击,反之则为单击。不知道大佬们有没有更好的办法,可以指导下吗?主函数
发表于 2023-01-13
STM32学习日志——主函数框架:时间轮
读大学时候,老师曾教了一种叫时间轮的方法,当时没好好学习。自己在写程序时经常乱用延时,一方面占用CPU资源,原本单片机可以执行更多的任务,却被用来延时,特别浪费,另一方面可能出现各种各样的问题。使用时间轮的方法,可以使单片机像人一样,以时间为尺度,来规划任务。人可以决定今天几点吃饭,几点看书,几点睡觉。而单片机依靠定时器的中断,每隔0.5ms进入一次中断,可以设定在任意的时间点执行合适的任务,比如需要usart发送比较重要的数据的,可以让它以1ms间隔发送,比如不重要的数码管显示,可以让他200ms执行一次。而这个框架可以直接套用于主程序。配置定时器主程序框架主程序框架
发表于 2023-01-13
总结大佬经验,如何学习STM32?(入门、进阶)
一、想快速入门进阶,面向工作时先把工作中需要的东西学会,一项一项的来,比如先把GPIO弄清楚,怎么初始化,怎么输入输出,然后定时器、串口、ADC、DAC、DMA、SPI等等先把用得着的一个一个地做,都弄明白了再往一块整合,从简单到复杂,硬件操控起来了也就算对这种单片机入门了吧,软件方面,不管用什么单片机,用什么编译器,区别不大初学的最好还是买个开发板,不需要多高级的,有几个常用功能做出来,其它就容易了。--------hdxet关于初学者是否需要弄清底层函数问题:先玩起来再说底层函数,一般就用现成的库,绝大多数应用都没问题的,至于库里面是什么,先不管它,到了高级阶段再去看--------hdxet二、进阶步骤会点灯-入门;会使用各个
发表于 2023-01-13
一图搞懂单片机STM32的5个时钟源知识!
众所周知STM32有5个时钟源HSI、HSE、LSI、LSE、PLL,其实他只有四个,因为从上图中可以看到PLL都是由HSI或HSE提供的。其中,高速时钟(HSE和HSI)提供给芯片主体的主时钟.低速时钟(LSE和LSI)只是提供给芯片中的RTC(实时时钟)及独立看门狗使用,图中可以看出高速时钟也可以提供给RTC。内部时钟是在芯片内部RC振荡器产生的,起振较快,所以时钟在芯片刚上电的时候,默认使用内部高速时钟。而外部时钟信号是由外部的晶振输入的,在精度和稳定性上都有很大优势,所以上电之后我们再通过软件配置,转而采用外部时钟信号.高速外部时钟(HSE):以外部晶振作时钟源,晶振频率可取范围为4~16MHz,我们一般采用8MHz的晶振。
发表于 2023-01-13

推荐帖子

multisim 12的问题 急急急急急急急
下载12安装后进入显示无法连接datebase数据库,problem:Accessingthedatebase有大牛能解决吗?????? 而且卸载后重新安装也不好使点击确定后元件库里面什么都没有0.0multisim12的问题急急急急急急急
334550282 单片机
【雅特力开发板 AT32F421 测评】3、对外设位操作的疑问,难道不好用
本帖最后由ddllxxrr于2021-4-1116:38编辑 我觉得位操作十分简单,然而就是这个简单的操作,害了我一整天。我不得不宣布,对外设的位操作失败。我看了下例程提供的位操作是对RAM的,我觉得没有什么实用价值,谁会没有事跑到RAM去操作一个BIT。我要有价值的那就是象51单片机那样的位操作。我本来十分有把握的建了H文件内容如下: #ifndef__BITBAND__ #define__BITBAND__//#defineBITBAND(addr,
ddllxxrr 国产芯片交流
解决Simplicity Studio V3 windows版make运行出错的问题
在使用SimplicityStudioV3windows版时,在编译时遇到一个提示,make不能运行。错误提示如下: 搜索了一下,一般说需要用vs中的rebase重新设置。但是我没有安装庞大的vs,所以又继续查找。 后来在http://www.madwizard.org/electronics/articles/winavrvista发现有提示说问题在msys-1.0.dll上,替换这个文件就正常了。试了一下,果然如此。 为了防止以后外网可能会访问不了,所
dcexpert 单片机
EEworld Datasheet库 改版啦,欢迎纠错!
>>Datasheet 经过了将近一月的规划,设计,代码实现,内测等等繁复的流程,终于在今早与大家见面了, 希望你喜欢~ 多多纠错~~~ EEworldDatasheet库改版啦,欢迎纠错!
soso 下载中心专版
stm32f103的外部flash
请教一个问题,如果使用stm32f103ze的外部flash来存储程序,怎么用仿真器把程序下载到外部flash中?我用的ST-LINK-II,开发环境是IAR4.42,这个开发环境的flashloader中,只有对应于内部flash的,如果要下载到外部flash是不是要自己编写flashloader啊?stm32f103的外部flash
abcdtemp stm32/stm8
ATSAMD51 EVK 移植 Aduino 笔记
【ATSAMD51EVK在Aduino迎宾机器人移植时笔记-哔哩哔哩】https://www.bilibili.com/video/BV1aD4y1V73J/?buvid=XYB5BEEBCDEAF0E2655F6834F01BDC2673CFA&is_story_h5=false&mid=a6uhrPCQfVj6M3teRn1ZjQ%3D%3D&share_from=ugc&share_medium=android&share_plat=android
程英茂 Microchip MCU
小广播
设计资源 培训 开发板 精华推荐

何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2023 EEWORLD.com.cn, Inc. All rights reserved