STM32快速复习(三)定时器中断(TIM)部分二 配置输出比较模块

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

TIM的 OC(Output Compare)输出比较 主要用于输出PWM波形,PWM又是驱动电机的必要条件(智能车、机器人等),所以应用广泛。输出比较功能 可以通过比较 CNT计数器 与 CCR捕获/比较寄存器 的大小,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。

PWM是电路中重要的一类知识点。
举个例子,呼吸灯,电风扇的一二三档,等等。都是用到了PWM的知识,也是面试以及工作中最常用的知识点。属于不会不行的。

每个高级定时器和通用定时器都拥有4个输出比较通道
高级定时器的前3个通道额外拥有死区生成和互补输出的功能


一、输出比较是什么?输出比较作用?

用PWM来进行讲解,会使用PWM,会进行设置。基本上就将输出比较理解了!
在这里插入图片描述
PWM参数计算
PWM频率: Freq = CK_PSC / (PSC + 1) / (ARR + 1)
PWM占空比: Duty = CCR / (ARR + 1)
PWM分辨率: Reso = 1 / (ARR + 1)

在这里插入图片描述
蓝色为CNT计数,根据频率自动计数,黄色为ARR自动重装值。通过设置红色(CCR比较值)来控制一个周期内的高低电平来达到控制PWM占空比的效果
输出比较单元为代码设置,看懂逻辑即可,再结合后续代码,能看懂就算理解。
在这里插入图片描述
通用定时器和高级定时器电路原理图如下
在这里插入图片描述
在这里插入图片描述

二、使用步骤

(1)TIM_OC1Init 【常用】:配置第一路输出比较模块。TIM_OC2Init、TIM_OC3Init、TIM_OC4Init 则分别是配置第二、三、四路。
(2)TIM_OCStructInit 【常用】:给输出比较结构体赋一个默认值。
(3)TIM_CtrlPWMOutputs 【重要】:仅高级定时器使用,使用高级定时器输出PWM波时,必须调用此函数,否则PWM将不能正常输出。
(4)TIM_ForcedOC1Config 【不常用】:配置强制输出模式,但由于占空比100%输出高电平、0%输出低电平,与强制输出高、低电平等价,所以使用不多。第二、三、四路同理。
(5)TIM_OC1PreloadConfig 【不常用】:用于配置CCR寄存器的预装功能,即CCR的影子寄存器。不会立即生效,而是在更新时间后才会生效。第二、三、四路同理。
(6)TIM_CCPreloadControl :一次性设置所有的4路输出比较通道寄存器CCR的预装载方式,也就是是否启用影子寄存器。
(7)TIM_OC1FastConfig 【不常用】:用于配置快速使能,在参考手册“14.3.10单脉冲模式”有介绍。第二、三、四路同理。
(8)TIM_ClearOC1Ref 【不常用】:在参考手册“14.3.11在外部事件时清除OCxREF信号”有介绍。第二、三、四路同理。
(9)TIM_OC1PolarityConfig 、 TIM_OC1NPolarityConfig :用于单独设置输出比较的极性,第二、三、四路同理。带N的函数就是高级定时器里互补通道的配置。这个极性设置与 输
出比较模块结构体 中的设置极性相同。一般来说结构体中的参数都有一个专门的函数用于修改。
(10)TIM_CCxCmd 、 TIM_CCxNCmd :用于单独修改输出使能参数。
(11)TIM_SelectOCxM :用于单独更改输出比较模式的函数。
(12)TIM_SetCompare1 【重要】:用于单独更改CCR寄存器的值,可以更改PWM波的占空比。第二、三、四路同理。

1.主函数控制占空比

代码如下(示例):

 #include "stm32f10x.h"                  // Device header
 #include "PWM.h"
 #include "Delay.h"
 int main(void){
    uint16_t pwm_duty = 0;//PWM波的占空比
    uint8_t  pwm_flag = 1;//占空比变化控制信号,1升0降

    //PWM初始化
    PWM_Init();
    
    while(1){
        
        Delay_ms(5);//0.5s完成100个占空比变化
        //调整占空比
        if(pwm_flag==1){
            if(pwm_duty<100){
                pwm_duty++;
            //    
            }else if(pwm_duty==100){
                pwm_flag = 0;
            }else{
                pwm_duty = 0;
                pwm_flag = 1;
            }
        }else if(pwm_flag == 0){
            if(pwm_duty >0 && pwm_duty<=100){
                pwm_duty--;
          //
            }else if(pwm_duty==0){
                pwm_flag = 1;
            }else{
                pwm_duty = 0;
                pwm_flag = 1;
            }
        }else{
            pwm_duty = 0;
            pwm_flag = 1;
    }
        //改变占空比
        PWM_SetDuty(pwm_duty);
    };
     }

2.占空比示例(配置输出比较模块)

代码如下(示例):

#include "stm32f10x.h"                  // Device header
 //TIM输出比较模式-PWM初始化
void PWM_Init(void){
    //1.配置RCC
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
 //    //隐:引脚重映射,将PA0映射到PA15
 //    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//引脚重映射会使用AFIO
 //    GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);//参考手册“8.3.7定时器复用功能重映射”
 //    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//PA15、PB3、PB4变成普通IO口
    //2.选择时基单元时钟
    TIM_InternalClockConfig(TIM2);
    //3.配置时基单元-10kHz
    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 = 72-1;//预分频
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x0000;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
    //4.配置运行控制
    TIM_Cmd(TIM2, ENABLE);
    //5.配置输出捕获电路
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCStructInit(&TIM_OCInitStructure);//后续即使用到高级定时器初始化,也不会出错
    TIM_OCInitStructure.TIM_OCMode      = TIM_OCMode_PWM1;      //PWM模式1
    TIM_OCInitStructure.TIM_OCPolarity  = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse       = 0x0000;                 //占空比
    TIM_OC1Init(TIM2, &TIM_OCInitStructure);
    //7.配置GPIO-PA0
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;      //GPIO_Pin_15-引脚重映射
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 }
 //设置PWM波的占空比
//范围是0~100
 void PWM_SetDuty(uint16_t pwm_duty){
    TIM_SetCompare1(TIM2, pwm_duty);
 }```


---

# 总结
1. 在Hardware文件夹创建了PWM.h和PWM.c。
2. 输出比较电路的OC1输出怎么映射到GPIO引脚上呢?
 其实在引脚定义表上就已经固定好了,OC1输出固定是PA0。但是配置GPIO时注意配置成“复用推挽输出”模式,因为GPIO输出框图中显示,只有复用输出模式才能使信号来自片上外设。
3. 引脚重映射。进行引脚重映射时,需要不断对照参考手册及引脚定义表。
若对 调试端口 进行引脚重映射,需要三步:
开启AFIO时钟,进行引脚重映射,解除调试端口复用。
4. 若想对 定时器和其他外设的复用引脚 进行重映射,那就只需要前两步即可。

设置出一个正确的占空比电路即可。实际使用中还是要结合当下电路。
放假后第一天,有些敷衍,估计后续会再补充些。
  • 22
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是STM32F103 TIM1定时器中断配置代码示例: ```c #include "stm32f10x.h" void TIM1_UP_IRQHandler(void) // TIM1 中断处理函数 { if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) // 判断是否是更新中断 { // 在这里编写中断处理程序 // ... TIM_ClearITPendingBit(TIM1, TIM_IT_Update); // 清除中断标志位 } } int main(void) { // 使能 TIM1 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // TIM1 配置 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 999; // 定时器自动重装值 TIM_TimeBaseStructure.TIM_Prescaler = 7199; // 定时器时钟预分频值 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 定时器向上计数模式 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 定时器时钟分割 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // TIM1 中断配置 NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; // 定时器中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ 通道使能 NVIC_Init(&NVIC_InitStructure); TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); // TIM1 更新中断使能 TIM_Cmd(TIM1, ENABLE); // TIM1 使能 while (1) { // 在这里编写主程序 // ... } } ``` 在上面的代码中,我们先使能了TIM1的时钟,并配置定时器的一些参数。然后,我们配置TIM1的中断,并在中断处理函数中编写了中断处理程序。最后,我们使能了TIM1,并在主程序中编写了主程序的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值