首页 > 其他分享 >STM32定时器输出PWM脉冲

STM32定时器输出PWM脉冲

时间:2023-07-29 09:22:06浏览次数:41  
标签:定时器 STM32 TIM 占空比 GPIO PWM 时钟

一、什么是PWM脉冲?

PWM (Pulse Width Modulation) 脉冲宽度调制,通常应用于惯性系统中,(不是不能即停的设备,因为如果设备不具有关心,那么运动是断断续续的,不具有连续性),通过脉宽调节输出不同的波形作用域受控对象。

二、 PWM中三个重要的参数

1.频率=1/Ts ;这个很好理解,就是在单位时间内输出的波形的个数啦。

 

2.占空比= Ton/Ts; 在一个脉冲周期内,脉冲波形中高电平的宽度占整个周期内波形宽度的比值。

3.分辨率=占空比变化步距,指PWM最小能设定到的高电平时间所占周期的比例,也即最小占空比,意思就是把一个周期的时间分成了多少份,如果是10份,那么占空比的精度就为10%。如果分成1000份,那么占空比的精度就为0.1%。譬如频率为600HZ的PWM,若最小能给到的时钟是60kHZ,则分辨率即为(1/60k)/(1/600)=1%。在同一个系统中,由于时钟不变,提高频率,则周期变小,分辨率会变大。(前面的话可能不太好理解,那我就以自己的大白话给大家解说一下吧: 说白了其意思就是说把一个波形脉冲分成了多少分,例如分辨率为0.1%,那就是把一个波形脉冲分割成了1000分,分别由不同份数的高低电平组个,例如占空比为50%d的脉冲,那就是有500份高电平,500份低电平,注意是连续的)

三、 PWM脉冲输出配置(重点来啦)

事实上,需要输出PWM脉冲,仅需要进行两部分寄存器的配置,分别是时基单元(前面定时器中断的时候已经详细说过这里不再赘述)、输出比较单元的配置。首先看一下基本的结构如图3所示。

定时器在不断进行计数,其CNT不断增大,(我这里说的是向上计数),同在不断的与CRR(使用者自己设定的值)寄存器的值进行比较,通过比较与CRR的值大小关系,与设定的模式进行工作,具体的模式如图4所示。

本试验使用的是PWM1 模式,计数的方式使用向上计数。其中计数从0到A点的工程中CNT<CRR,输出有效电平(高电平),A点到B点过程中CNT>=RCC,输出无效电平(低电平),这就完成了一个波形输出,不断的循环便能输出一系列波形。

 

四、 具体程序

好了废话不多说下面我们一起来看看具体的代码吧。这里是输出占空比 0---->100,100--->0不断变化的的脉冲波,其频率为1000HZ,分辨率为1%.

CODE  :PWM.c

#include"pwm.h"
void PwmInit(void)
{
//打开定时器时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //定时器2是通用定时器,其时钟挂在到APB1时钟线上
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA,ENABLE); //打开对应的GPIO的时钟,注意这里不同的外设可能挂载的时钟不同,所以需要看原理图,


GPIO_DeInit(GPIOA);// 注意这里的函数非常的重要,这里是将对应的GPIO端口初始化成默认的样子,因为这个端口可能在以前使用过,其他的配置可能发生了改变
GPIO_InitTypeDef GPIOC_LED_PWM_Init; // 定义GPIO的结构体,也就是外设的结构体
GPIOC_LED_PWM_Init.GPIO_Pin= GPIO_Pin_0; // 配置需要使用的引脚
GPIOC_LED_PWM_Init.GPIO_Mode=GPIO_Mode_AF_PP; //配置引脚的输出的模式,这里使用大额CH1输出波形,所以是复用模式
GPIOC_LED_PWM_Init.GPIO_Speed=GPIO_Speed_50MHz; // 配置输出的频率,这个在输入的时候不需要配置
GPIO_Init(GPIOA ,&GPIOC_LED_PWM_Init); // 使用初始化函数初始化刚刚定义的结构体,以及对应的GPIO端口
//配置定时器2的时钟源来自内部时钟源,其实这里系统默认的就是内部时钟,所以这一步配置可以省去
TIM_InternalClockConfig(TIM2);
//定时器结构体配置
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1 ; //内部时钟分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period=100-1; //定时器溢出值
TIM_TimeBaseInitStructure.TIM_Prescaler=720-1; //分频系数
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0; //这里使用的是通用定时器没有复用计数功能,这里设置为0
//配置定时器2初始化
TIM_TimeBaseInit(TIM2 ,&TIM_TimeBaseInitStructure);
TIM_Cmd(TIM2,ENABLE); //使能定时器

//配置比较输出单元
TIM_OCInitTypeDef PwmStruct;
TIM_OCStructInit(&PwmStruct); //给结构体赋初值,保证结构体中每一个变量都有初始值,防止使用高级定时器的时钟时出现错误,应为通用定时器不具有某一个功能
PwmStruct.TIM_OCMode=TIM_OCMode_PWM1; // 输出模式
PwmStruct.TIM_Pulse=0; //CCR
PwmStruct.TIM_OutputState=ENABLE; // PWM 输出使能
PwmStruct.TIM_OCPolarity= TIM_OCPolarity_High;
TIM_OC1Init(TIM2,&PwmStruct);
}
//程序运行过程中设置不同的占空比
void PWM_SetCompare1(uint16_t Compare)
{

TIM_SetCompare1(TIM2 ,Compare);

}

 CODE :main.c

int main(){
Led_funcing();
PwmInit();
uint8_t i;
while(1)
{
for(i=0;i<=100;i++)
{
PWM_SetCompare1(i);
delay(100);
}
for(i=0;i<=100;i++)
{
PWM_SetCompare1(100-i);
delay(100);
}
}
}

有条件的宝宝可以使用LED灯 马达自己模拟一下,我是用的是仿真模式输出。

 好啦,今天就给大家分享到这里,如有错误和不合理的地方请大家指正。

 

标签:定时器,STM32,TIM,占空比,GPIO,PWM,时钟
From: https://www.cnblogs.com/Nic-zhang/p/17589275.html

相关文章

  • STM32使用硬件IIC读取SHTC3温湿度传感器 显示在OLED屏上
    STM32使用硬件I2C读取SHTC3温湿度传感器的数据并显示在0.96寸OLED屏上。我用的是STM32F103C8T6,程序用的是ST标准库写的。实现效果图I2C协议简介I2C通讯协议(Inter-IntegratedCircuit)是由Phiilps公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要USART、CAN等通讯协议的外......
  • STM32读取SHT3x系列温湿度传感器,标准库和HAL库
    STM32读取SHT3x系列(SHT30、SHT31、SHT35)温湿度传感器的数据并显示在0.96寸OLED屏上。我下面提供两份代码,一份是标准库使用硬件I2C的,另一份是HAL库使用软件模拟IIC的。我用的单片机是STM32F103C8T6,温湿度传感器是SHT30。STM32软件I2C读取AM2320温湿度传感器数据:https://blog.zerun......
  • STM32定时器(TIM)中断
    一、什么是定时器中断?大白话理解:使用一个定时器进行计时(计数),数数的方式可以从上到下(从设定值到0),也可从下到上(从0到设定值),或者中间计数(一般用不上,记住前面两者解决大部分问题,)要学会释怀自己,哈哈(允许我找个不会的借口)。当计数完成以后,将会发出冲断请求(就是给中断控制系统说,我想......
  • ST官方基于米尔STM32MP135开发板培训课程(一)
    本文将以Myirtech的MYD-YF13X以及STM32MP135F-DK为例,讲解如何使用STM32CubeMX结合Developerpackage实现最小系统启动。    1.开发准备1.1Developer package准备a.Developerpackage下载:‍https://www.st.com/en/embedded-software/stm32mp1dev.html‍b.解压后进入......
  • 使用 QEMU 代替 STM32 开发版本 docker 一键启动
    dockerfile#Compileandinstallqemu_stm32fromfedora:28RUNdnfinstall-y\arm-none-eabi-gcc\arm-none-eabi-newlib\findutils\gcc\git\glib2-devel\libfdt-devel\......
  • STM32 HAL库更改PWM频率的方法
    项目上用到了步进电机,控制方式为STEP/DIR。电机的STEP由PWM提供,于是控制步进电机的速度就靠PWM的频率高低来实现。实现频率更改的函数为。__HAL_TIM_SET_PRESCALER(__HANDLE__,__PRESC__);该函数可以直接更改Prescaler(PSC)预分频寄存器的数值,达成改变时钟频率的目的。举例:更......
  • 06. 系统滴答定时器
    一、SysTick定时器简介  SysTick,即系统滴答定时器,是属于CM3内核中的一个外设,内嵌在NVIC中。系统定时器是一个24bit的向下递减的计数器,SysTick的时钟源自HCLK。当计数值减到0时,将从RELOAD寄存器中自动重装载定时初值,开始新一轮计数。只要不把它在SysTick控制及状......
  • 记一次 MDK 开发 STM32WB15 时遇到的玄学BUG
    使用STM32WB15CCU6开发BLE应用调试自建的工程时,莫名报错Jlink和ST-LINK/V2都是一样的结果于是开始测试例程,开始也是正常,但是找不到自建工程的问题,开始对比代码,逐步替换然而并没有效果......
  • 4 STM32MP1 Linux系统启动过程
    1.ROM代码  这是ST官方写的代码,在STM32MP1出厂时就已经烧录进去,不能被修改。ROM代码是上电以后首先执行的程序,它的主要工作就是读取STM32MP1的BOOT引脚电平,然后根据电平来判断当前启动设备,最后从选定的启动设备里面读取FSBL代码,将FSBL代码放在对应的RAM空间。  STM32MP1启......
  • STM32F103C8在Keil5中烧录后串口工具无法接收到数据(已解决)
    烧录后串口无法接收到数据(默认硬件连线是正确的,只考虑软件配置问题)在通过Keil5烧录程序并成功后,发现串口没有接收到数据烧录成功未报错串口工具无法接收到数据点击魔法棒,进入Debug-Settings,查看Pack-DebugDescription中的Enable是否勾上,发现√上后拔掉下载器并重新插......