STM32 定时器输出比较非主动模式

发布者:Volare最新更新时间:2016-10-11 来源: eefocus关键字:STM32  定时器输出  非主动模式 手机看文章 扫描二维码
随时随地手机看文章
STM32的定时器可以工作在输出比较非主动模式TIM_OCMode_Inactive,这个模式下,当定时器的计数值达到比较值时就会强制将引脚电平拉低。但是由于定时器通道对应的引脚配置成GPIO_Mode_AF_PP时,它默认的电平时低电平,如果这时候工作在输出比较非主动模式,即时强制拉低,这样的话引脚一直是低电平,完全没有现象。由于水平所限,我也不知道该如何使用定时器输出比较非主动模式才能体现它的“非主动”这个特性。我下面要讲的例子虽然用的是定时器输出比较非主动模式来输出PWM波,但是完全体现不出这个特格特点来。还请见谅!
下面就讲讲定时器在输出比较非主动模式下如何生成PWM波的。还是基于我自己的规范工程!
1、工程的修改
1)这里用到了定时器,所以需要将stm32f10x_tim.h添加到STM32F10x_StdPeriod_Driver工程组中。
2)打开stm32f0x_conf.h文件,将其中原先被屏蔽的语句:#include "stm32f10x_tim.h"的注释去掉。
3)新建OCInactive.c与OCInactive.h两个文件,分别保存在BSP文件夹里下的src与inc中,然后在将OCInactive.c添加到BSP工程组。
 
2、OCInactive.c与OCInactive.h文件程序的编写
首先是引脚的初始化程序。上面说过,如果初始化定时器各通道对应的引脚的话,则完全没有现象。所以,需要选取其他的引脚。这里选择PC6、PC7、PC8、PC9这4个引脚来输出PWM波。要将这4个引脚配置成输出推挽模式。代码如下:

/*************************************************************
Function : OCActive_GPIO_Init
Description: 输出比较主动模式定时器各通道引脚配置
Input : none
return : none
*************************************************************/
static void OCInactive_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//定时器各通道引脚配置成复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}

接下去需要配置下定时器了,对应的代码如下:

u16 CCR1_Val = 4500;
u16 CCR2_Val = 3000;
u16 CCR3_Val = 1500;
u16 CCR4_Val = 750;

/*************************************************************
Function : OCActive_TIM2_Init
Description: 定时器2配置成输出比较主动模式
Input : none
return : none
*************************************************************/
static void OCInactive_TIM2_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//初始化TIM2时钟

/* -------------------------------------------------------
TIM_OCMode_Inactive模式强制输出为高,
各通道引脚原先为低电平,经过下面延时后,跳变成高电平
在PC6引脚输出频率为12kHz,占空比为75%的PWM波
在PC7引脚输出频率为12kHz,占空比为50%的PWM波
在PC8引脚输出频率为12kHz,占空比为25%的PWM波
在PC9引脚输出频率为12kHz,占空比为12.5%的PWM波
---------------------------------------------------------*/
TIM_TimeBaseStructure.TIM_Period = 6000;//定时器计数周期
TIM_TimeBaseStructure.TIM_Prescaler = 1 - 1;//预分频
TIM_TimeBaseStructure.TIM_ClockDivision = 1 - 1;//时钟不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//增计数
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//初始化定时器


TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive;//输出比较主动模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出使能
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;//设置比较值(跳变值)
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//有效电平为高电平
TIM_OC1Init(TIM2, &TIM_OCInitStructure);//初始化输出比较寄存器
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);//关闭预装载

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出使能
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;//设置比较值(跳变值)
TIM_OC2Init(TIM2, &TIM_OCInitStructure);//初始化输出比较寄存器
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出使能
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;//设置比较值(跳变值)
TIM_OC3Init(TIM2, &TIM_OCInitStructure);//初始化输出比较寄存器
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出使能
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;//设置比较值(跳变值)
TIM_OC4Init(TIM2, &TIM_OCInitStructure);//初始化输出比较寄存器
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable);

TIM_ARRPreloadConfig(TIM2, ENABLE);//打开定时器2的自动重装功能
TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4 | TIM_IT_Update, ENABLE);//清除中断标志
GPIO_SetBits(GPIOC, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9);//将这几个引脚置1
TIM_Cmd(TIM2, ENABLE);//打开定时器2
}

先是配置好定时器的时基,这里不对时钟频率做任何分频,增计数,并设置周期值为6000,所以定时器的频率为72M/6000=12kHz。接着配置个通道,将个通道都配置成输出比较非主动模式,并且设置比较值分别为4500、3000、1500、750,所以可以计算得到对应的占空比分别为75%、50%、25%、12.5%。然后打开各通道的输出比较中断,并将引脚的电平高(说起来跟TIM_OCMode_PWM2模式差不多)。最后打开定时器。
接着还要配置下定时器的中断,设置TIM2的中断优先级为1,配置代码如下:

/*************************************************************
Function : OCInactive_Int_Config
Description: 定时器2中断配置
Input : none
return : none
*************************************************************/
static void OCInactive_Int_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//中断优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);
}

还要编写一个总函数:OCInactive_Init()来初始化下相关的全部代码,如下:

/*************************************************************
Function : OCActive_Init
Description: 输出比较主动M模式初始化
Input : none
return : none
*************************************************************/
void OCInactive_Init(void)
{
OCInactive_GPIO_Init();
OCInactive_TIM2_Init();
OCInactive_Int_Config();
}

最后是OCInactive.h,代码如下:

#ifndef __OCINACTIVE_H__
#define __OCINACTIVE_H__
#include "stm32f10x.h"

void OCInactive_Init(void);

#endif

3、stm32f10x_it.c的修改
要编写一个TIM2的中断服务函数,然后在中断函数中做些文章,代码如下:

/*************************************************************
Function : TIM2_IRQHandler
Description: 定时器2中断复位程序
Input : none
return : none
*************************************************************/
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) //通道1检测到比较事件
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); //清除标志位
GPIO_ResetBits(GPIOC, GPIO_Pin_6); //输出低电平
}
if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)//通道1检测到比较事件
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);//清除标志位
GPIO_ResetBits(GPIOC, GPIO_Pin_7);//输出低电平
}
if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)//通道1检测到比较事件
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);//清除标志位
GPIO_ResetBits(GPIOC, GPIO_Pin_8); //输出低电平
}
if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET) //通道1检测到比较事件
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);//清除标志位
GPIO_ResetBits(GPIOC, GPIO_Pin_9); //输出低电平
}
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)//检测到更新事件
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清除标志位
GPIO_SetBits(GPIOC, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9);//输出高电平
}
}

上面代码就是引脚输出PWM的关键所在。当发生输出比较事件时,就将引脚拉低,而发生更新事件的时候,又将引脚拉高。举通道1为例来说,当定时器的计数值小于4500时,PC6引脚为高电平,当定时器的计数值为4500时,将引脚电平拉低,当定时器的计数值等于6000时,又就将PC6引脚拉高,这样就是一个周期PWM波了。
 
4、main函数的编写
main函数很简单,只是调用一些初始化函数,代码如下:

/*************************************************************
Function : main
Description: main入口
Input : none
return : none
*************************************************************/
int main(void)
{
BSP_Init();
OCInactive_Init();
PRINTF("\nmain() is running!\r\n");
while(1)
{
LED1_Toggle();
Delay_ms(1000);
}
}

5、测试
示波器的探头分别测试PC6、PC7、PC8、PC9这4个引脚,在示波器中可以观察到给引脚上分别输出了:
PC6引脚上输出频率为12kHz,占空比为75%的PWM波形,如下图所示:
STM32 定时器输出比较非主动模式 - ziye334 - ziye334的博客
PC7引脚上输出频率为12kHz,占空比为50%的PWM波形,如下图所示:
STM32 定时器输出比较非主动模式 - ziye334 - ziye334的博客
PC8引脚上输出频率为12kHz,占空比为25%的PWM波形,如下图所示:
STM32 定时器输出比较非主动模式 - ziye334 - ziye334的博客
PC9引脚上输出频率为12kHz,占空比为12.5%的PWM波形,如下图所示:
STM32 定时器输出比较非主动模式 - ziye334 - ziye334的博客

关键字:STM32  定时器输出  非主动模式 引用地址:STM32 定时器输出比较非主动模式

上一篇:STM32 定时器输出比较翻转模式
下一篇:STM32 定时器输出比较主动模式

推荐阅读最新更新时间:2024-03-16 15:14

stm32入门笔记(二)printf不定向直接使用问题
我们很多时候可能直接调用 printf,然后系统会出现各种各样的问题。 那么究竟是为什么呢? 因为我们需要将这个东西实现在,我们必须定义printf输出的端口 int fputc(int ch, FILE *f) { while(!(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == SET)) { USART_SendData(USART1, (u8) ch); } return ch; } 这才是c里面的标准输出函数。 当然,我一直都在为keil没有代码补全而烦恼,然后经过同事的指点,我发现是有这个功能的。 configuration
[单片机]
<font color='red'>stm32</font>入门笔记(二)printf不定向直接使用问题
stm32驱动TB6600控制42/57步进电机的案例(TIM中断和PWM实验)
步进电机的简单使用 接线: TB6600驱动盒的详细说明: 程序设计: 工程文件: 做毕业设计要用到57步进电机,所以花了两天时间做了一下电机函数 从淘宝查的资料: 接线如图: 接线: DIR- && PUL- 接 单片机GND DIR+ 接 PA1 PUL+ 接 PA0 驱动盒TB6600 VCC 24V 驱动盒TB6600 GND 24V的GND 我测出来的 A组(绿+蓝- ) B组(黄+红-) 如何确定AB两组看这个: 关于42步进电机驱动——基于STM32 HAL库实现 接线方法 TB6600驱动盒的详细说明: 先冲英说明: Microstep Driver 微步驱动程序 Microstep 微步
[单片机]
<font color='red'>stm32</font>驱动TB6600控制42/57步进电机的案例(TIM中断和PWM实验)
基于STM32动态密码锁(手机APP)
1. 前言 前一版设计了一款物联网的密码锁,采用MQTT协议连接物联网服务器进行交互,这一版是本地动态密码锁。采用局域网方式完成网络连接,与门锁进行交互,通信设置,生成密码种子,进行动态密匙比对。 这款智能电子密码锁,以STM32单片机为主控制器,由触摸矩阵键盘、ESP8266、步进电机等模块组成,具有手机APP控制、随机密码生成等功能。 当前支持的开锁方式: (1)手机APP远程开锁。支持手机APP远程开锁。手机APP连接上ESP8266创建的WIFI热点和TCP服务器,可以在手机APP上对设备端的RTC时间进行校准,设备唯一ID获取,生成随机开锁密码。 (2)随机密码开锁。手机APP与本地设备采用时间、作为算法种子
[单片机]
基于<font color='red'>STM32</font>动态密码锁(手机APP)
STM32 MCU内置的一些主要硬件安全属性
对于功能安全,ST MCU从芯片内置的硬件安全属性,经过认证的软件自检库和完备的安全文档三个层面来支持STM32用户在系统级进行开发,达到要求的功能安全等级。 下表中列出了STM32MCU内置的一些主要硬件安全属性。下面我们一起来看看这些属性在功能安全中的用处。 双看门狗:独立看门狗和窗口看门狗 看门狗是我们常用到的针对CPU运行状态监测的手段之一。它本质上就是一个定时器,启动之后,需要不断的去刷新(我们通常把这个动作叫做“喂狗”),否则当看门狗的定时器减到规定的值后,就会引起系统复位。我们可以利用它来检测程序是否跑飞,并通过芯片复位,来让系统恢复到正常状态。 STM32 MCU提供两个看门狗,独立看门狗和窗口看门狗。
[单片机]
STM32之TFT-LCD液晶学习
TFT-LCD即薄膜晶体管液晶显示器。其英文全称为:Thin Film Transistor-Liquid Crystal Display。TFT-LCD与无源TN-LCD、STN-LCD的简单矩阵不同,它在液晶显示屏的每一个象素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。TFT-LCD也被叫做真彩液晶显示器。 TFT液晶原理: *背光模组:提供光源 *上下偏光片,TFT Glass Substrate, 液晶:形成偏振光,控制光线的通过与否 *彩色滤光片:提供TFT LCD R/G/B(三原色)的来源 *ITO透明导电层:提供透明的导电通路 *
[单片机]
<font color='red'>STM32</font>之TFT-LCD液晶学习
STM32输入上拉下拉 寄存器怎么设置实现
在输出模式下:ODR是数据输出寄存器, 但是在 输入模式下,同时也用来配置上拉下拉设置。 在Alientek的源码中的按键输入实验中有如下一段初始化代码: void KEY_Init(void){ RCC- APB2ENR|=1 2; //使能PORTA时钟 GPIOA- CRL&=0XFFFFFFF0;//PA0设置成输入 GPIOA- CRL|=0X00000008; GPIOA- CRH&=0X0F0FFFFF;//PA13,15设置成输入 GPIOA- CRH|=0X80800000; GPIOA- ODR|=1 13; //PA13上拉,PA0默认下拉
[单片机]
<font color='red'>STM32</font>输入上拉下拉 寄存器怎么设置实现
外部中断相关分析
//======================================================// **基于STM32的按键控制与外部中断实例详解 **为了减少重复的内容,所以将外部中断的例程与按键控制实例 放在一起学习。 一开始先在51黑论坛率先上传了本文,上传时间不分什么顺序,只是希望在学习中慢慢写下自己的思路。 //======================================================// /********************************************************/ 因为涉及的内容较多,这里大体说一下整片文章的内容分布: 1)
[单片机]
外部中断相关分析
ST 最新STM32 Primer开发工具可玩Maze和Breakout
完整、独立、预编程的评估工具套件,既有充满趣味性的功能介绍,又有严肃的开发工具,可以链接到在线开发社区 中国,2007年10月15日 — 意法半导体(纽约证券交易所代码:STM)今天推出了一套价格低廉的开发工具,这款代号为STM32 Primer开发工具是一套完整的学习与娱乐相结合的趣味性应用开发工具,用于ST的STM32系列基于具有突破性的ARM Cortex-M3内核的闪存微控制器。这套工具包含一个创新的用户界面、多个游戏和向新用户介绍该系列产品的产品入门功能,以及用于高级开发和编程的Raisonance软件工具。 STM32 Primer是一个手持评估开发工具,力图通过简单和有趣的介绍,让用户了解STM32的强大功能。紧
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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