STM32-定时器-定时器中断-PWM调光

1、TIM

定时器

定时器是一种电子设备或软件组件,用于在预定时间后触发一个事件或操作。它可以基于时钟信号或其他周期性信号来工作,并且可以用来测量时间间隔、生成延时、触发中断等。

时钟信号

时钟信号是一种周期性的电信号,用于同步电路中的操作。它通常是一个方波信号,有高电平和低电平两种状态,这两种状态周期性地交替出现。时钟信号的频率(即每秒的周期数)决定了电路或设备可以执行操作的速度。例如,在一个微处理器中,时钟信号驱动CPU的指令执行流程,每个时钟周期CPU可以完成一定数量的操作。

脉冲信号

脉冲信号是一种短暂存在的电信号,其形状通常类似于一个快速上升然后快速下降的尖峰。脉冲信号可以由时钟信号生成,但不一定是周期性的。脉冲信号通常用于触发某些事件或操作,例如触发数字电路中的门电路或控制模拟电路中的开关。

周期

周期是指一个事件或信号重复发生的时间间隔。对于时钟信号来说,周期就是两个相邻的时钟周期(即相邻的高电平到高电平或低电平到低电平的时间间隔)之间的时间长度。周期的倒数就是频率,即每秒钟发生的周期数。

频率与周期

  • 频率(Hz):定义为每秒内周期性事件(如时钟信号的周期)发生的次数。例如,100Hz表示每秒有100个完整的周期。
  • 周期时间(秒):是频率的倒数,表示一个完整周期所需的时间。计算公式为 T=f1,其中 f 是频率(Hz),T 是周期时间(秒)。因此,对于100Hz的频率,周期时间为 1001=0.01 秒。

时钟信号的调整:倍频与分频

  • 倍频:是指将时钟信号的频率提高至原始频率的整数倍。这通常通过相位锁定环(PLL)或其他频率合成技术实现,以增加系统处理速度。
  • 分频:则是将时钟信号的频率降低到原始频率的某个分数。这有助于在需要较低操作速度或功耗的应用中优化性能。

时钟信号的重要性

时钟信号是数字电子系统中至关重要的组成部分,它驱动着系统的同步操作。以下是时钟信号在寄存器操作中的关键作用:

  • 寄存器与触发器:寄存器通常由多个触发器(特别是D触发器)组成,用于存储二进制数据(0或1)。每个触发器都有一个时钟输入端,用于控制数据的加载或更新。
  • D触发器:D触发器是一种具有记忆功能的数字电路元件,其输出(Q)在时钟信号的每个上升沿(或下降沿,取决于触发器的类型)时更新为输入(D)的值。
  • 寄存器操作:为了修改寄存器的值,必须提供一个时钟信号的上升沿(或指定的边沿)。在时钟信号的每个有效边沿,寄存器中的每个D触发器都会将其输入值(D)捕获到其输出(Q)。因此,时钟信号的频率(即上升沿的数量)直接决定了寄存器在单位时间内能够修改其值的次数。
  • 执行指令:在微处理器或数字信号处理器中,时钟信号驱动着指令的执行流程。更高的时钟频率意味着处理器能够在相同的时间内执行更多的指令,从而提高整体性能。
  • 频率与周期:频率(Hz)是每秒周期性事件发生的次数,周期时间(秒)是其倒数,表示一个完整周期所需的时间。
  • 时钟信号的调整:通过倍频技术提高时钟频率,或通过分频技术降低时钟频率,以适应不同的系统需求。
  • 时钟信号的重要性:在数字电子系统中,时钟信号是同步操作的基石。它控制着寄存器的数据更新,进而影响指令的执行速度和系统的整体性能。每个时钟信号的上升沿(或指定边沿)都
  • 触发一次数据加载或更新操作,因此时钟频率直接决定了单位时间内可执行的指令数量。

STM32 时钟树:

STM32时钟树是STM32微控制器中的一个关键组成部分,它负责将时钟信号分配和扩展到整个系统的各个模块和部分。以下是对STM32时钟树的详细解析:

一、时钟树的基本概念

时钟(Clock):在数字电路和计算机系统中,时钟是一种周期性的信号,用于同步和协调系统中各个部分的操作。时钟信号通常是一个方波信号,具有固定的周期和占空比。

时钟树(Clock Tree):在数字系统或芯片中,时钟树是指将一个主时钟信号分配和扩展到整个系统中各个模块和部分的一种层次结构。时钟树的目的是确保系统中所有的时钟域都能够按照规定的时序要求同步运行。

STM32时钟树的组成

STM32时钟树主要由时钟源、时钟分频器/倍频器、时钟输出等部分组成。

  1. 时钟源
  • 高速内部时钟(HSI):由内部RC振荡器产生,通常为8MHz,但不稳定,可直接作为系统时钟或在2分频后作为PLL输入。
  • 高速外部时钟(HSE):使用外部晶振,通过OSC_IN和OSC_OUT引脚引入,晶振频率范围为4~16MHz,通常采用8MHz。
  • 低速内部时钟(LSI):由内部RC振荡器产生,频率约为40kHz,主要用于实时时钟(RTC)和独立看门狗(IWDG)。
  • 低速外部时钟(LSE):使用外部晶振,通过OSC32_IN和OSC32_OUT引脚引入,通常采用32.768kHz晶振,也主要用于RTC和IWDG。
  1. 时钟分频器/倍频器
  • 分频器:用于将输入时钟信号分频,即减小其频率,以满足不同模块或外设的时钟需求。
  • 倍频器:通常指锁相环(PLL),用于将输入时钟信号倍频,即增加其频率,以满足系统对更高时钟频率的需求。
  1. 时钟输出
  • 时钟信号经过分频/倍频处理后,被分配到各个总线(如AHB、APB等)和外设上,确保它们能够按照正确的时序运行。

三、STM32时钟树的配置过程

STM32时钟树的配置通常通过软件完成,具体步骤如下:

  1. 配置时钟源
  • 使用HAL库或STM32CubeMX等工具配置HSI、HSE、LSI、LSE等时钟源。
  • 选择合适的时钟源作为系统时钟的输入。
  1. 配置PLL
  • 如果需要更高的系统时钟频率,可以配置PLL的倍频系数和分频系数。
  • 将PLL的输出作为系统时钟(SYSCLK)的输入。
  1. 配置总线时钟和外设时钟
  • 根据需要配置AHB、APB等总线的时钟频率。
  • 使能并配置外设的时钟,确保它们能够正常工作。

锁相环:

1、倍频

2、避免相位差

锁相环(Phase Locked Loop, PLL)是一种利用相位同步产生的电压去调谐压控振荡器(VCO)以产生目标频率的负反馈控制系统。以下是关于锁相环的详细解析:

一、锁相环的组成

锁相环主要由三个基本部分组成:鉴相器(Phase Detector, PD)、环路滤波器(Loop Filter, LF)和压控振荡器(Voltage-Controlled Oscillator, VCO)。

  1. 鉴相器:鉴相器用于检测输入信号和输出信号之间的相位差,并将这个相位差转换成电压信号输出。这个电压信号与相位差成正比,反映了两个信号之间的相位关系。
  2. 环路滤波器:环路滤波器是一个低通滤波器,用于滤除鉴相器输出信号中的高频成分和噪声,只保留低频成分。这样,滤波后的信号就可以作为压控振荡器的控制电压。
  3. 压控振荡器:压控振荡器是一个电压-频率转换器,其输出信号的频率与输入的控制电压成正比。在锁相环中,压控振荡器根据环路滤波器输出的控制电压来调整其输出信号的频率和相位,以跟踪输入信号的频率和相位。

二、锁相环的工作原理

锁相环的工作原理可以概括为以下几个步骤:

  1. 相位检测:鉴相器检测输入信号和压控振荡器输出信号之间的相位差,并输出一个与相位差成正比的电压信号。
  2. 滤波:环路滤波器滤除鉴相器输出信号中的高频成分和噪声,形成控制电压。
  3. 振荡控制:控制电压作用于压控振荡器,调整其输出信号的频率和相位,以减小与输入信号之间的相位差。
  4. 反馈:压控振荡器的输出信号再次被鉴相器检测,并与输入信号进行比较。这个过程反复进行,直到输出信号的频率和相位与输入信号完全同步。

Systeminit();

SystemInit(); 这个函数在STM32微控制器的启动过程中扮演着重要的角色。这个函数通常是由启动文件(如startup_stm32fxxx.s,其中xxx代表具体的STM32系列型号)自动调用的,作为系统启动时的第一个C语言函数。它的主要目的是初始化系统时钟(System Clock)和配置一些关键的硬件参数,以确保微控制器能够按照预期的频率和配置运行。

具体来说,SystemInit(); 函数执行以下任务(但可能因不同的STM32系列和库版本而有所不同):

  1. 时钟系统初始化:设置系统时钟源(如HSI、HSE、PLL等),并配置时钟分频器,以生成CPU、AHB总线、APB总线等所需的时钟频率。这是确保微控制器以正确速度运行的关键步骤。
  2. NVIC(嵌套向量中断控制器)配置:虽然SystemInit(); 函数本身可能不直接配置NVIC,但它为后续的NVIC配置(如中断优先级设置)提供了必要的时钟和硬件基础。
  3. 复位向量表重定位(在某些情况下):虽然这通常不是SystemInit(); 的直接职责,但在某些启动流程中,可能会涉及到将复位向量表从Flash的默认位置重定位到SRAM或其他位置,以提高中断响应速度。
  4. 其他必要的硬件初始化:根据具体的STM32系列和库版本,SystemInit(); 还可能执行一些其他的硬件初始化操作,如配置Flash访问延迟、启用或禁用某些外设的时钟等。

在微控制器(如STM32系列)中,定时器是一个非常重要的组件,用于提供精确的时间基准,用于时间测量、延时、定时中断等功能。以下是对不同类型定时器、滴答定时器、看门狗定时器(WWDG和IWDG)以及实时时钟(RTC)的规范笔记。

定时器

基本定时器
  • 功能:基本定时器主要用于提供基本的定时功能,如生成简单的延时或周期性的中断。
  • 特点
    • 通常具有较少的通道和功能。
    • 可能不支持输入捕获、输出比较等高级功能。
    • 适用于需要简单定时控制的场景。
通用定时器
  • 功能:通用定时器提供了更全面的定时和计数功能,包括输入捕获、输出比较、PWM生成等。
  • 特点
    • 比基本定时器具有更多的特性和通道。
    • 可用于生成精确的延时、测量脉冲宽度、控制PWM输出等。
    • 广泛应用于需要复杂定时控制的应用中。
高级定时器
  • 功能:高级定时器是功能最强大的定时器,提供了几乎所有通用定时器的功能,并增加了额外的特性,如死区时间生成、互补输出等。
  • 特点
    • 通常用于需要高精度和复杂控制的应用,如电机控制、音频处理等。
    • 具有更高的性能和更多的资源。

M3:滴答定时器(SysTick Timer)

  • 功能:SysTick定时器是ARM Cortex-M3(及后续版本)内核中的一个24位倒计时定时器,主要用于生成操作系统时钟节拍(tick)或实现简单的延时函数。
  • 特点
    • 直接由内核控制,无需外部配置。
    • 通常用于操作系统的时基(time base)或简单的软件延时。
    • 可通过编程配置其定时周期和中断使能。

WWDG:窗口看门狗

  • 功能:窗口看门狗(Window Watchdog)是一种用于监测软件错误的定时器。当程序因为某种原因(如陷入死循环)而未能按预期刷新看门狗时,看门狗会触发系统复位。
  • 特点
    • 有一个更新窗口,只有在这个窗口内更新看门狗才有效,这有助于防止在中断服务例程中意外复位系统。
    • 适用于需要高可靠性保护的场景。

IWDG:独立看门狗

  • 功能:独立看门狗(Independent Watchdog)是独立于系统时钟的看门狗定时器,它使用自己的低速内部振荡器作为时钟源。
  • 特点
    • 不受系统时钟故障的影响,增加了系统的可靠性。
    • 通常用于系统严重错误时的最终保护手段。

RTC:实时时钟

  • 功能:实时时钟(Real-Time Clock)用于提供当前的日期和时间信息,并能在系统断电时保持时间和日期的准确性(如果配备了后备电池)。
  • 特点
    • 通常具有独立的振荡器(如32.768 kHz晶振),以保持时间的准确性。
    • 支持闹钟功能,可用于定时唤醒系统。
    • 广泛应用于需要精确时间记录的应用中,如日志记录、时间戳生成等。
      在STM32微控制器中,定时器(TIM)是一个非常重要的外设,用于实现定时、延时、PWM生成等多种功能。根据复杂度和应用场景的不同,STM32的定时器被分为高级定时器、通用定时器和基本定时器三种类型。以下是针对您提到的TIM1-8、高级定时器1和8、基本定时器6和7以及通用定时器2-5的更新中断的规范笔记:

一、定时器分类与特性

1. 高级定时器(TIM1和TIM8)
  • 特性
    • 16位递增、递减、中心对齐计数器。
    • 16位可编程预分频器,用于对计数器时钟频率进行分频。
    • 多达4个独立通道,支持输入捕获、输出比较、PWM生成(边缘或中间对齐模式)、单脉冲模式输出。
    • 死区时间可编程的互补输出。
    • 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器。
    • 刹车输入信号可以将定时器输出信号置于复位状态或已知状态。
    • 触发DAC、ADC的同步电路。
    • 支持增量(正交)编码器和霍尔传感器电路。
    • 可以在更新事件、触发事件、输入捕获、输出比较时生成中断/DMA请求。
  • 更新中断:当计数器达到上溢(向上计数模式)或下溢(向下计数模式)时,会触发更新中断。如果启用了重复计数器,则需要在重复计数器减至0并再次发生上溢或下溢时才会触发更新中断。
2. 基本定时器(TIM6和TIM7)
  • 特性
    • 16位自动装载累加计数器。
    • 16位可编程预分频器。
    • 主要用于生成简单的定时功能,不支持输入捕获、输出比较等复杂功能。
    • 触发DAC的同步电路。
    • 在更新事件(计数器溢出)时产生中断/DMA请求。
  • 更新中断:当计数器溢出时,会触发更新中断。
3. 通用定时器(TIM2-TIM5)
  • 特性
    • 16位向上、向下、向上/向下自动装载计数器。
    • 16位可编程预分频器。
    • 4个独立通道,支持输入捕获、输出比较、PWM生成(边缘或中间对齐模式)、单脉冲模式输出。
    • 使用外部信号控制定时器和定时器互连的同步电路。
    • 可以在更新事件、触发事件、输入捕获、输出比较时生成中断/DMA请求。
    • 支持增量(正交)编码器和霍尔传感器电路。
  • 更新中断:与高级定时器类似,当计数器达到上溢或下溢时,会触发更新中断。

二、更新中断

  1. 中断触发条件
    • 当定时器计数器达到上溢(向上计数模式)或下溢(向下计数模式)时,会触发更新中断。
    • 如果启用了重复计数器,则需要在重复计数器减至0并再次发生上溢或下溢时才会触发更新中断。
  2. 中断服务程序(ISR)
    • 在中断服务程序中,需要首先检查中断标志位(如更新中断标志位UIF),以确认是否确实发生了期望的中断。
    • 清除中断标志位,以便允许下一次中断的发生。
    • 执行与中断相关的处理代码,如读取计数器值、更新定时器配置等。
  3. 中断优先级与嵌套
    • STM32的中断系统支持中断优先级和嵌套功能。可以根据需要配置不同定时器的中断优先级,以确保关键任务的及时响应。
    • 在高优先级中断处理过程中,低优先级的中断可能会被阻塞或延迟处理。
  4. 中断配置
    • 在初始化定时器时,需要配置中断相关的寄存器(如TIMx_DIER),以启用所需的中断类型(如更新中断)。
    • 同时,还需要配置NVIC(嵌套向量中断控制器)来使能对应的中断线路,并设置中断的优先级。

定时器中断代码案例:

TIM_TimeBaseInitTypeDef 是STM32标准外设库(或HAL库,取决于具体版本)中用于配置定时器(Timer)基本参数的结构体类型。这个结构体包含了定时器初始化所需的关键参数,如预分频值、计数模式、计数周期等。下面是对 TIM_TimeBaseInitTypeDef 结构体各成员的详细解释:

TIM_TimeBaseInitTypeDef 结构体成员

|---|-------------------------------------------------------------|
| | typedef struct |
| | { |
| | uint16_t TIM_Prescaler; // 定时器的预分频值 |
| | uint16_t TIM_CounterMode; // 定时器的计数模式 |
| | uint16_t TIM_Period; // 定时器的计数周期 |
| | uint16_t TIM_ClockDivision;// 定时器的时钟分频 |
| | uint8_t TIM_RepetitionCounter; // 重复计数器的值(仅适用于TIM1和TIM8) |
| | } TIM_TimeBaseInitTypeDef; |

成员详解
  1. TIM_Prescaler(预分频值)
    • 用于将定时器输入时钟进行分频,以控制计数频率。预分频值决定了定时器的计数速度,从而实现不同的定时精度和计数范围。其取值范围通常为0x0000到0xFFFF。
  2. TIM_CounterMode(计数模式)
    • 定义了定时器的计数模式,包括向上计数、向下计数和中央对齐计数等模式。这些模式决定了定时器如何根据时钟信号增加或减少其计数值。
  3. TIM_Period(计数周期)
    • 定时器的计数周期,即计数器达到此值后会产生溢出(或下溢),并触发更新事件或中断。其取值范围也是0x0000到0xFFFF。
  4. TIM_ClockDivision(时钟分频)
    • 用于进一步分频计数器的时钟,以便更精细地控制定时器的操作。时钟分频的设置可以影响定时器的各种功能,如更新事件、触发事件等的频率。
  5. TIM_RepetitionCounter(重复计数器)
    • 这是一个特殊的成员,仅适用于高级定时器(如TIM1和TIM8)。它用于设定计数器的重复计数次数,即在每次达到计数周期后,重复计数器会递减,并在减至0时再次触发更新事件。这对于需要生成多个连续定时周期的应用非常有用。
cpp 复制代码
void tim2Init(void){
	//在APB1总线上打开时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	//定时器tim2的初始化
	//72Mhz,psc =7200; 
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	//输入捕获的滤波器有关
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;  
	//CNT计数器的计数模式,up++
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//自动装载值 ARR=10000
	TIM_TimeBaseInitStructure.TIM_Period = 9999;
	//PSC预分频器
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7199;
	//高级定时器 记录复位次数
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	//使能 更新 中断  计数溢出时触发
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	
	//NVIC设置
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;
	NVIC_Init(&NVIC_InitStructure);
	TIM_Cmd(TIM2,ENABLE);
}

TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

  • TIM_ITConfig:这是一个函数,用于配置定时器中断。它允许你启用或禁用定时器的一个或多个中断源。

  • TIM2:这是你要配置中断的定时器的标识符。STM32微控制器通常包含多个定时器,它们通过不同的标识符(如TIM1、TIM2、TIM3等)进行区分。

  • TIM_IT_Update:这是一个宏定义,代表更新中断。在定时器中,更新中断通常是在计数器上溢或下溢时触发的,具体取决于定时器的计数模式。对于向上计数模式,这通常发生在计数器从最大值(例如,在16位定时器中为65535)回绕到0时。

  • ENABLE:这是一个宏定义,用于启用功能。在STM32的库中,ENABLE通常被定义为1或类似的值,而DISABLE则被定义为0。通过传递ENABLE作为参数,你告诉TIM_ITConfig函数要启用指定的中断。

因此,TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); 这行代码的作用是启用定时器TIM2的更新中断。一旦启用,每当TIM2的计数器达到其配置的周期值并溢出时,就会触发一个中断请求(IRQ),CPU随后可以跳转到相应的中断服务例程(ISR)来处理这个中断。

TIM_GetITStatus

函数用于检查指定的定时器中断是否已发生(即中断标志是否被设置)

TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

这行代码用于清除定时器TIM2的更新中断挂起位(Pending Bit)。


PSC预分频器:

分频后的时钟信号CK_CNT的计算公式为:

CK_CNT=PSC+1TIMxCLK​

PSC预分频器是定时器内部的一个组件,其主要作用是将输入到定时器的时钟信号进行分频,从而得到一个适合计数器计数的时钟信号。由于嵌入式系统的主时钟频率通常很高,直接使用这个频率进行计数会导致定时器的值迅速溢出,无法进行长时间的定时或延时操作。通过预分频器,开发者可以根据需要选择合适的分频系数,从而得到所需的计数频率。

因为分频是从0开始计数的,所以实际分频系数是7199+1

比较寄存器(Compare Register)

是定时器(Timer)或计数器(Counter)内部的一个重要组成部分,其主要功能是与定时器或计数器内部的另一个寄存器(通常是计数器寄存器)中的值进行比较。以下是对比较寄存器的详细解释:

一、定义与作用

比较寄存器用于存储一个预设的值,这个值通常是用户根据需要设定的。当定时器或计数器接收到时钟信号(可以是内部时钟或外部输入信号)并开始计数时,其内部的计数器寄存器会不断递增或递减。当计数器寄存器的值达到与比较寄存器中预设的值相匹配时,定时器或计数器会触发一个中断或事件,以通知CPU或相关硬件执行特定的操作。

二、工作原理

  1. 初始化:在定时器或计数器开始工作之前,用户需要通过软件或硬件方式将预设的值写入比较寄存器。
  2. 计数:定时器或计数器接收到时钟信号后,其内部的计数器寄存器开始按照设定的速率递增或递减。
  3. 比较:在计数过程中,定时器或计数器会不断将计数器寄存器的当前值与比较寄存器中的预设值进行比较。
  4. 触发中断/事件 :当计数器寄存器的值达到与比较寄存器中的预设值相匹配时,定时器或计数器会触发一个中断或事件。这个中断或事件会通知CPU或相关硬件执行特定的操作,如更新系统时间、执行周期性任务等。

通过比较寄存器生成PWM(脉冲宽度调制)信号是一种常见的做法,

特别是在微控制器和定时器/计数器模块中。PWM信号是一种通过改变脉冲宽度(占空比)来模拟模拟信号的技术,广泛应用于电机控制、LED亮度调节、音频放大等领域。

以下是通过比较寄存器生成PWM信号的基本步骤和原理:

1. 初始化比较寄存器和定时器/计数器

  • 设置比较寄存器的值:这个值决定了PWM信号的占空比。占空比是PWM信号中高电平(或有效电平)持续的时间与整个周期时间的比例。
  • 配置定时器/计数器:设置定时器/计数器的模式(如向上计数、向下计数或上下计数)、时钟源(内部时钟、外部时钟等)和周期(即PWM信号的频率)。

2. 计数器递增/递减

定时器/计数器开始工作后,其内部的计数器寄存器会根据配置的时钟源和模式递增或递减。

3. 比较与输出

  • 当计数器寄存器的值小于或等于比较寄存器的值时,PWM输出为高电平(或有效电平)。
  • 当计数器寄存器的值大于比较寄存器的值时,PWM输出为低电平(或无效电平)。
  • 计数器达到最大值(或最小值,取决于计数模式)后会重置并重新开始计数,形成一个周期性的PWM信号。

4. 调整占空比

通过改变比较寄存器的值,可以调整PWM信号的占空比。占空比越高,高电平(或有效电平)持续的时间就越长;占空比越低,高电平(或有效电平)持续的时间就越短。

5. 频率调整

PWM信号的频率通常由定时器/计数器的周期决定。调整定时器/计数器的周期(通过改变其预分频器、计数值等)可以改变PWM信号的频率。

6. 中断(可选)

在某些情况下,可能需要使用中断来同步PWM信号与其他任务或事件。例如,可以在每个PWM周期结束时触发一个中断,以便在中断服务例程中执行特定的操作。

PWM(脉冲宽度调制)信号的上下文中,占空比通常定义为有效电平(在大多数情况下是高电平)的时间与整个周期时间的比例。这个比例决定了PWM信号的平均电压或功率水平,因为PWM信号被用来模拟一个介于0和最大电压之间的电压值。

PWM信号的基本特性

  • 周期(T):PWM信号完成一个完整的高电平和低电平循环所需的时间。
  • 高电平时间(Ton):在每个周期内,信号处于高电平(有效电平)的时间段。
  • 低电平时间(Toff):在每个周期内,信号处于低电平(非有效电平)的时间段。
  • 占空比(D):定义为高电平时间(Ton)与周期时间(T)的比值,即 D = Ton / T。占空比是一个介于0和1之间的数值,也可以用百分比来表示(即 D * 100%)。

如何调整占空比

在大多数微控制器和定时器/计数器模块中,你可以通过编程来设置比较寄存器的值,从而控制PWM信号的占空比。比较寄存器的值决定了何时从高电平切换到低电平(或反之),进而影响了高电平时间(Ton)的长度。

应用示例

  • LED亮度控制:通过调整PWM信号的占空比,可以控制LED的亮度。占空比越高,LED越亮;占空比越低,LED越暗。
  • 电机速度控制:在电机控制中,PWM信号用于调节电机的平均电压,从而控制电机的转速。占空比的变化会改变电机的速度。
  • 音频放大:在音频放大电路中,PWM信号可以用于模拟音频信号的幅度,并通过滤波器转换为模拟信号来驱动扬声器。占空比的变化对应于音频信号的幅度变化。

DC调光原理

  • 功率控制:屏幕亮度基本上可以量化为屏幕的功率。功率P由电压U和电流I的乘积决定(P=UI)。DC调光通过调整电流(或电压,但通常调整电流更为常见)来改变屏幕的功率,从而调整亮度。
  • 亮度调节:当需要更高的亮度时,DC调光会增加电流;当需要降低亮度时,会减少电流。这种调节方式简单直接,且能够保持屏幕色彩的一致性。

DC调光与PWM调光的对比

  • PWM调光:脉冲宽度调制(Pulse Width Modulation)调光并不改变屏幕的功率,而是通过极快地"亮-灭-亮-灭"交替闪烁来调整亮度。这种方式在亮和灭的时间比例上实现亮度调节,但可能引发频闪问题。
  • DC调光优势:在低亮度下,DC调光能够保持较好的色彩均匀性,避免像PWM调光那样在低亮度下可能出现的色彩偏差。同时,DC调光不存在频闪现象,对眼睛更为友好。

使用PWM实现呼吸灯:

  1. 初始化定时器:配置定时器的基本时间参数,如预分频器(PSC)、自动重载寄存器(ARR)和时钟源。

  2. 配置输出比较通道:选择TIM3的第三个输出比较通道(如果可用),并配置其输出比较模式为PWM模式1或PWM模式2。

  3. 设置捕获/比较寄存器CCR3:将CCR3的值设置为PWM周期中的一个点,这个点将决定PWM信号的占空比。占空比是PWM信号中高电平时间占总周期时间的比例。

  4. 使能输出:确保定时器的输出比较通道已使能,并且与PWM输出引脚相连的GPIO端口也已正确配置为输出模式。

  5. 启动定时器:启动定时器,使其开始计数并生成PWM信号。

  6. 调整占空比:通过修改CCR3的值,可以调整PWM信号的占空比。增加CCR3的值将增加高电平的时间,从而增加占空比;减少CCR3的值将减少高电平的时间,从而降低占空比。

通过改变PWM信号的占空比(即高电平持续的时间与整个周期时间的比例)来控制LED灯的亮度变化,从而模拟出呼吸的效果。

原理简述:

  1. PWM信号:PWM信号是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。

  2. 呼吸灯效果:呼吸灯效果是通过逐渐改变LED的亮度来实现的,从暗到亮,再从亮到暗,形成一个循环,就像呼吸一样。这种亮度的变化是通过改变PWM信号的占空比来实现的。占空比越大,LED的平均亮度就越高;占空比越小,LED的平均亮度就越低。

在本次实验中采用PB0口控制占空比,控制stm32上PC13的输入;(PC13的灯低电平点亮)

pb0采用复用推挽输出,(复用定时器tim3的通道);

定时器tim3初始化;

输出通道初始化:

TIM_OCInitTypeDef

是STM32标准外设库(或HAL库,从STM32Cube开始)中用于配置定时器输出比较(Output Compare, OC)功能的结构体。输出比较功能允许定时器在计数器达到预设值时输出一个信号,这个信号可以是高电平、低电平、翻转(toggle)或者无动作(none),具体取决于配置。这个功能常用于生成PWM(脉冲宽度调制)信号、测量时间间隔或产生精确的时序控制等。

TIM_OCInitTypeDef 结构体通常包含以下成员(具体成员可能因库版本或具体STM32系列而异):

  • TIM_OCMode:输出比较模式,定义当输出比较匹配时定时器如何动作(例如,设置为PWM模式1、PWM模式2、定时模式等)。
  • TIM_OutputState:输出比较通道的状态,使能或禁用输出。
  • TIM_OutputNState(如果可用):互补输出比较通道的状态,同样使能或禁用输出(对于高级定时器而言)。
  • TIM_Pulse:在定时模式下,输出比较匹配时产生的脉冲宽度(以定时器计数器计数为单位)。在PWM模式下,这个值通常与自动重载寄存器(TIM_ARR)的值一起决定PWM信号的占空比。
  • TIM_OCPolarity:输出比较极性,定义输出比较匹配时输出是高电平还是低电平(或翻转)。
  • TIM_OCNPolarity(如果可用):互补输出比较极性,定义互补输出通道的输出极性。
  • TIM_OCIdleState:输出比较空闲状态,定义定时器在非活动(空闲)状态下输出比较通道的电平。
  • TIM_OCNIdleState(如果可用):互补输出比较空闲状态,定义互补输出通道在非活动(空闲)状态下的电平。
cpp 复制代码
void tim3Init(void){
	//在APB1总线上打开时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	//PB0--复用推挽输出ADC1,使用PB0输出占空比控制led
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);	
	//定时器tim2的初始化
	//72Mhz,psc =7200; 10ms
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	//输入捕获的滤波器有关,设置不分频;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;  
	//CNT计数器的计数模式,up++

	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//自动装载值 ARR = 99,定时器的计数周期,到达99触发中断
	
	TIM_TimeBaseInitStructure.TIM_Period = 99;
	//PSC预分频器,控制计数频率
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7199;
	//高级定时器 记录复位次数
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//初始化定时器
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	//输出通道初始化
	TIM_OCInitTypeDef TIM_OCInitStructure;
	//输出比较模式,定义当输出比较匹配时定时器的动作;
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	//输出比较极性,定义输出比较匹配时是高电平还是低电平
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_Low;
	//输出比较空闲状态,定义定时器在非活动状态下输出比较通道的电平
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	//输出比较匹配时产生的脉冲宽度,PWM模式下这个值和ARR一起决定占空比
	TIM_OCInitStructure.TIM_Pulse = 0;
	//初始化定时器的第三个输出比较通道
	TIM_OC3Init(TIM3,&TIM_OCInitStructure);
	//使能tim3;
	TIM_Cmd(TIM3,ENABLE);
}
代码,输出通道的初始化:

//输出比较模式,定义当输出比较匹配时定时器的动作;PWM1:CNT低于CCR时输出有效电平

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

定时器tim3的初始化:

调整占空比

STM32F103C8T6的引脚定义:

相关推荐
scan12 小时前
单片机串口接收状态机STM32
stm32·单片机·串口·51·串口接收
Qingniu012 小时前
【青牛科技】应用方案 | RTC实时时钟芯片D8563和D1302
科技·单片机·嵌入式硬件·实时音视频·安防·工控·储能
Mortal_hhh4 小时前
VScode的C/C++点击转到定义,不是跳转定义而是跳转声明怎么办?(内附详细做法)
ide·vscode·stm32·编辑器
深圳市青牛科技实业有限公司4 小时前
【青牛科技】应用方案|D2587A高压大电流DC-DC
人工智能·科技·单片机·嵌入式硬件·机器人·安防监控
Mr.谢尔比5 小时前
电赛入门之软件stm32keil+cubemx
stm32·单片机·嵌入式硬件·mcu·信息与通信·信号处理
LightningJie5 小时前
STM32中ARR(自动重装寄存器)为什么要减1
stm32·单片机·嵌入式硬件
鹿屿二向箔5 小时前
STM32外设之SPI的介绍
stm32
西瓜籽@6 小时前
STM32——毕设基于单片机的多功能节能窗控制系统
stm32·单片机·课程设计
远翔调光芯片^138287988728 小时前
远翔升压恒流芯片FP7209X与FP7209M什么区别?做以下应用市场摄影补光灯、便携灯、智能家居(调光)市场、太阳能、车灯、洗墙灯、舞台灯必看!
科技·单片机·智能家居·能源
极客小张9 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩