STM32定时器的几种输出模式

发布者:shmilyde最新更新时间:2023-08-22 来源: elecfans关键字:STM32  定时器  输出模式 手机看文章 扫描二维码
随时随地手机看文章

1 背景

最近有接触到通过可控硅的方式来控制交流风机或者电烙铁功率,STM32的定时器输出比较模式,刚好可以满足这种需求,借此机会总结一下定时器的几种输出模式。


2 STM32的定时器比较输出

STM32的定时器比较输出一共有8种,记录一下初始化方法和逻辑分析仪的波形。

在官网搜索对应的型号找到用户手册,比如STM32F103ZET6

找到比较模式相关配置的描述

TIMx capture/compare mode register 1 (TIMx_CCMR1)

Address offset: 0x18 Reset value: 0x0000

The channels can be used in input (capture mode) or in output (compare mode). The

direction of a channel is defined by configuring the corresponding CCxS bits. All the other

bits of this register have a different function in input and in output mode. For a given bit,

OCxx describes its function when the channel is configured in output, ICxx describes it

function when the channel is configured in input. Take care that the same bit can have a

different meaning for the input stage and for the output stage。

图片图片图片

图片

图片

2.1 OCxM 输出匹配模式

OC1M用于配置通道1,通道2则在OC2M上


2.1.1 TIM_OCMODE_TIMING

000:Frozen冻结模式

TIMx_CCR1和计数器TIMx_CNT之间的比较对输出没有影响


2.1.2 TIM_OCMODE_ACTIVE

001: Set channel 1 to active level on match。

匹配时将输出为有效电平,当TIMx_CNT=TIMx_CCR1时强制输出为高电平


2.1.3 TIM_OCMODE_INACTIVE

010: Set channel 1 to inactive level on match。

匹配时将输出为无效电平,当TIMx_CNT=TIMx_CCR1时强制输出为高低电平


2.1.4 TIM_OCMODE_TOGGLE

011: 当TIMx_CNT=TIMx_CCR1时电平翻转。


2.1.5 TIM_OCMODE_FORCED_INACTIVE

100: Force inactive level,强制输出为低电平(无效电平)


2.1.6 TIM_OCMODE_FORCED_ACTIVE

101: Force active level,强制输出为高电平(有效电平)


2.1.7 TIM_OCMODE_PWM1

110: PWM mode 1

当TIMx_CNT


2.1.8 TIM_OCMODE_PWM2

111: PWM mode 2

当TIMx_CNT


3 实测波形

在上电时默认会有个100ms的高电平,作为一个直观的起始信号,

预分频设置为(72000000/2000)-1,最大计数为415-1,则周期是(1*415/2000)=(0.207)s


3.1 TIM_OCMODE_TIMING

3.1.1初始化代码


void TIM1_PWM_Init(u16 arr,u16 psc)

{

    htim2.Instance = TIM2;

    htim2.Init.Prescaler = psc;

    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

    htim2.Init.Period = arr;

    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    htim2.Init.RepetitionCounter = 0;

    HAL_TIM_OC_Init(&htim2);

    sConfigOC.OCMode = TIM_OCMODE_TIMING;;

    sConfigOC.Pulse = 0;

    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

    HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

    TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//

    HAL_TIM_Base_Start_IT(&htim2);

}

3.1.2 波形

极性是高电平时,上电后100ms后一直保持低电平

图片

极性是低电平时,一直保持高电平

图片

3.2 TIM_OCMODE_ACTIVE

3.2.1初始化代码


void TIM1_PWM_Init(u16 arr,u16 psc)

{

    htim2.Instance = TIM2;

    htim2.Init.Prescaler = psc;

    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

    htim2.Init.Period = arr;

    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    htim2.Init.RepetitionCounter = 0;

    HAL_TIM_OC_Init(&htim2);

    sConfigOC.OCMode = TIM_OCMODE_ACTIVE;

    sConfigOC.Pulse = 0;

    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

    HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

    TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//

    HAL_TIM_Base_Start_IT(&htim2);

}

3.2.2 波形

极性是低电平时,会先输出脉宽为计数周期的高电平,当TIMx_CNT=TIMx_CCR2后输出一直为低电平(有效电平)

图片

极性是高电平时,会先输出脉宽为计数周期的低电平,当TIMx_CNT=TIMx_CCR2后输出一直为高电平(有效电平)

图片

3.3 TIM_OCMODE_INACTIVE

3.3.1初始化代码


void TIM1_PWM_Init(u16 arr,u16 psc)

{

    htim2.Instance = TIM2;

    htim2.Init.Prescaler = psc;

    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

    htim2.Init.Period = arr;

    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    htim2.Init.RepetitionCounter = 0;

    HAL_TIM_OC_Init(&htim2);

    sConfigOC.OCMode = TIM_OCMODE_INACTIVE;

    sConfigOC.Pulse = 0;

    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

    HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

    TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//

    HAL_TIM_Base_Start_IT(&htim2);

}

3.3.2 波形

极性是低电平时,当TIMx_CNT=TIMx_CCR2时会出现一个低电平,但持续时间很短,然后一直输出一个高电平(无效电平)


图片

极性是高电平时,一直输出为低电平(无效电平)

图片


3.4 TIM_OCMODE_TOGGLE

3.4.1初始化代码


void TIM1_PWM_Init(u16 arr,u16 psc)

{

    htim2.Instance = TIM2;

    htim2.Init.Prescaler = psc;

    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

    htim2.Init.Period = arr;

    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    htim2.Init.RepetitionCounter = 0;

    HAL_TIM_OC_Init(&htim2);

    sConfigOC.OCMode = TIM_OCMODE_TOGGLE;

    sConfigOC.Pulse = arr/2;

    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

    HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

    TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//

    HAL_TIM_Base_Start_IT(&htim2);

}

3.4.2 波形

极性是低电平时,会先输出一个脉宽为半个计数周期的高电平,然后一直不停地翻转出一个脉宽为一个计数周期的电平

图片

极性是高电平时,会先输出一个脉宽为半个计数周期的低电平,然后一直不停地翻转出一个脉宽为一个计数周期的电平

图片

3.5 TIM_OCMODE_PWM1

3.5.1初始化代码


void TIM1_PWM_Init(u16 arr,u16 psc)

{

    htim2.Instance = TIM2;

    htim2.Init.Prescaler = psc;

    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

    htim2.Init.Period = arr;

    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    htim2.Init.RepetitionCounter = 0;

    HAL_TIM_OC_Init(&htim2);

    sConfigOC.OCMode = TIM_OCMODE_PWM1;

    sConfigOC.Pulse = arr*2/3;

    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

    HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

    TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//

    HAL_TIM_Base_Start_IT(&htim2);

}

3.5.2 波形

极性是低电平时,当TIMx_CNT

图片

极性是高电平时,当TIMx_CNT


图片

3.6 TIM_OCMODE_PWM2

3.6.1初始化代码


void TIM1_PWM_Init(u16 arr,u16 psc)

{

    htim2.Instance = TIM2;

    htim2.Init.Prescaler = psc;

    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

    htim2.Init.Period = arr;

    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    htim2.Init.RepetitionCounter = 0;

    HAL_TIM_OC_Init(&htim2);

    sConfigOC.OCMode = TIM_OCMODE_PWM2;

    sConfigOC.Pulse = arr*2/3;

    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

    HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

    TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//

    HAL_TIM_Base_Start_IT(&htim2);

}

3.6.2 波形

极性是低电平时,当TIMx_CNT

图片

极性是高电平时,当TIMx_CNT

图片

3.7 TIM_OCMODE_FORCED_ACTIVE

3.7.1初始化代码


void TIM1_PWM_Init(u16 arr,u16 psc)

{

    htim2.Instance = TIM2;

    htim2.Init.Prescaler = psc;

    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

    htim2.Init.Period = arr;

    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    htim2.Init.RepetitionCounter = 0;

    HAL_TIM_OC_Init(&htim2);

    sConfigOC.OCMode = TIM_OCMODE_FORCED_ACTIVE;

    sConfigOC.Pulse = 0;

    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

    HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

    TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//

    HAL_TIM_Base_Start_IT(&htim2);

}

3.7.2 波形

极性是低电平时,一直输出为低电平(有效电平)。


图片


极性是高电平时,一直输出为高电平(有效电平)。


图片


3.8 TIM_OCMODE_FORCED_INACTIVE

3.8.1初始化代码


void TIM1_PWM_Init(u16 arr,u16 psc)

{

    htim2.Instance = TIM2;

    htim2.Init.Prescaler = psc;

    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

    htim2.Init.Period = arr;

    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    htim2.Init.RepetitionCounter = 0;

    HAL_TIM_OC_Init(&htim2);

    sConfigOC.OCMode = TIM_OCMODE_FORCED_INACTIVE;

    sConfigOC.Pulse = 0;

    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

    HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

    TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//

    HAL_TIM_Base_Start_IT(&htim2);

}

3.8.2 波形

极性是低电平时,一直输出为高电平(无效电平)。

图片

极性是高电平时,一直输出为低电平(无效电平)。

图片

4 应用场景

假设可控硅是低电平导通,我们需要在初始化时输出为高电平,在过零时输出一个低电平,电平的时间可控。

4.1 初始化定时器为TIM_OCMODE_INACTIVE模式


void TIM1_PWM_Init(u16 arr,u16 psc)

{

    htim2.Instance = TIM2;

    htim2.Init.Prescaler = psc;

    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

    htim2.Init.Period = arr;

    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    htim2.Init.RepetitionCounter = 0;

    HAL_TIM_OC_Init(&htim2);

    sConfigOC.OCMode = TIM_OCMODE_INACTIVE;

    sConfigOC.Pulse = 0;

    sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;

    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

    HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

    TIM_CCxChannelCmd(TIM2, TIM_CHANNEL_2, TIM_CCx_ENABLE);//

    HAL_TIM_Base_Start_IT(&htim2);

}

4.2 使用按键来模拟过零信号,平时输出为高电平(无效电平),当按键按下时,强制输出为低电平,并且脉宽为207.5*360/415=180ms,然后输出持续为高电平(无效电平)

[1] [2]
关键字:STM32  定时器  输出模式 引用地址:STM32定时器的几种输出模式

上一篇:STM32单片机使用RTOS的好处
下一篇:STM32芯片的那些系统级复位功能

推荐阅读最新更新时间:2024-11-08 12:11

中断定时器源程序-0-99秒可调时间
定时器基时0.1S在中断内实现,主程序中需要用到0~99秒可调的时间,主程序发出请求后定时器开始工作,我现在在做一个实验主程序中的按键去抖动,显示部分动态扫描的间隔还有其它地方要用到定时器,试过几种方法效果都不太理想,各位帮帮忙给上传个汇编源程序,先谢谢了. 12M晶震 0.1s =100ms =100000US 因为51单片机T0 T1作为16位定时器最大65535 那么 我们用一个16位的T0或者T1 定时50000US 既是50ms 65535-50000=13335 换成16进制3CAF 那么定时器的高字节和低字节位 TH0=3CH TL0=0AFH 这样T0的溢出时间就是50MS 那么在程序中 我们要用到1S的时间怎
[单片机]
stm32 直接读写寄存器代码风格总结
简单的总结了一下stm32 寄存器读写代码风格,以备后用: 根据memory mapping 直接写寄存器代码风格: #define GPIOA_BASE1 (uint32_t)0x40010800 #define GPIOA_CRH ((uint32_t*)(GPIOA_BASE1+0x04)) 转换为指针之后,直接读写: *GPIOA_CRH=0x000004B0; //A端口 //复用推挽输出 结构体指针解决连续多个寄存器读写设置: #define Usart1_BASE 0x40013800 typedef struct { __IO uint32_t SR; __IO
[单片机]
<font color='red'>stm32</font> 直接读写寄存器代码风格总结
stm32 DMA初始化选项研究
DMA比较好用,也比较简单,今天在做多通道ADC“连续”“扫描”采样时,对DMA有了更深一点的认识,今天给大家分享下: #define ADC1_DR_Address ((uint32_t)0x4001244C) unsigned short Buff ; ...... DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buff; DMA_InitStructure.
[单片机]
STM32填坑:时钟使能必须在外设初始化之前
最近在STM32上写了一份串口通信的程序,但下载复位后串口却不能工作,初始化的代码如下: //发送/接收的GPIO、串口和中断的初始化结构体 GPIO_InitTypeDef GPIO_InitStructureTx; GPIO_InitTypeDef GPIO_InitStructureRx; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //设置发送和接收引脚 GPIO_InitStructureTx.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructureRx.GPIO_Pin = GP
[单片机]
STM32 的中断配置很烦人怎么办?
能大家在进行STM32 中断配置的时候经常感觉非常麻烦,总是这里配置一下,那里配置一下,又很容易发生缺漏。 那我教大家一种非常容易的办法应付这种情况: 1. 首先,你把STM32 的中断看作是一个人进入一个公司就职; 2. 你要想进入一个公司工作,对于普通人(相当于普通的STM32 外设,例如GPIO、SPI 等)来说,那你要有两位业界大牛的推荐信(就是NVIC 和EXTI 的结构体配置和中断使能)。 但是对于大神(相当于systick 等内核中断)来说,他根本不需要别人的推荐信(不需配置NVIC 和EXTI),自己就可以直接进入公司就职。 3. 光有推荐信还不够,最起码自己要有一定的实力储备(就是中断源本身的中断
[单片机]
基于STM32单片机的火灾防盗系统设计
一.系统概述 本次式设计的系统是以 STM32 单片机作为核心控制器,可以控制烟雾传感器、火焰传感器对相关数据进行采集,可以通过红外对是否有人进行监测,当监测到火焰会控制短信提醒火灾危险,当红外识别到人且输入密码错误的时候会短信提醒有人闯入。需要有一个密码输入的功能。 二.仿真概述 1.系统内可以检测烟雾浓度、检测是否有火焰、检测是否有人,检测到火灾发生且有人闯入就会通过GSM进行远程提醒。使用矩阵键盘来输入密码的,当检测到人且密码输入不正确就会认为是有人闯入。 2. 调节烟雾传感器的滑动变阻器可以调节烟雾的模拟输出量,烟雾的改变可以在显示端体现。 3. 拨动人体检测的开关即模拟检测到人和检测不到人,在显示屏端也会相
[单片机]
基于<font color='red'>STM32</font>单片机的火灾防盗系统设计
STM32--GPIO口功能以及寄存器介绍
GPIO口功能介绍 每个GPI/O端口有两个32位配置寄存器(GPIOx_CRL【控制端口0~7】,GPIOx_CRH【如有,控制端口8~15】), 两个32位数据寄存器(GPIOx_IDR,GPIOx_ODR),(直接设置输入输出的状态,高低电平(0,1)) 一个32位置位/复位寄存器(GPIOx_BSRR),(高16位清零,低16位置1,均为1时有效,0不影响) 一个16位复位寄存器(GPIOx_BRR) ,(只清零,使用低16位) 一个32位锁定寄存器(GPIOx_LCKR)。(锁键) 如图为一个端口的基本结构,(具体的每个寄存器位的定义,请一定参考《STM32中文参考手册》)
[单片机]
STM32--GPIO口功能以及寄存器介绍
STM32四行【跳转程序】引申出来的几条重要知识点
1写在前面 上一篇文章《 STM32 IAP应用编程几个要点 》讲述的内容很多朋友都了解过,也都使用过ST官网提供的代码。但使用过的人有许多都没有深入了解,仅仅只是把代码下载到板卡中跑了一下而已(因为代码完全可以使用)。所以,很少有人研究其中细节的问题。 先看一下上图中四行跳转代码,接下来将围绕这四行代码拓展相关的内容。 2STM32是如何实现程序跳转的? 上图四行代码中有几个定义没有贴出来,下面一并贴出来: #define ApplicationAddress 0x8003000 typedef void (*pFunction)(void); pFunction Jump_To_Application; uint
[单片机]
<font color='red'>STM32</font>四行【跳转程序】引申出来的几条重要知识点
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved