TIM—通用定时器

通用定时器的功能

在基本定时器功能的基础上新增功能:

通用定时器有4个独立通道,且每个通道都可以用于下面功能。

(1)输入捕获:测量输入信号的周期和占空比等。

(2)输出比较:产生输出特定的波形(根据自己需要设置)。

(3)输出PWM。

(4)单脉冲模式.

(5)级联。(一个定时器的溢出事件可以使能下一个定时器的计数器开始计数)

(6)可以触发DAC、ADC。

(7)支持编码器和霍尔传感器电路。

框图

时钟源

• 内部时钟源 CK_INT

• 外部时钟模式 1:外部输入引脚 TIx(x=1,2,3,4)

• 外部时钟模式 2:外部触发输入 ETR

• 内部触发输入 (ITRx)

时基单元

见基本定时器章节

输入捕获

输入捕获可以对输入的信号的上升沿、下降沿或者双边沿进行捕获,常用的有测量输入信号的脉

宽,和测量 PWM 输入信号的频率和占空比这两种。

输入捕获的大概的原理就是,当捕获到信号的跳变沿的时候,把计数器 CNT 的值锁存到捕获寄

存器 CCR 中,把前后两次捕获到的 CCR 寄存器中的值相减,就可以算出脉宽或者频率。如果捕

获的脉宽的时间长度超过你的捕获定时器的周期,就会发生溢出,这个我们需要做额外的处理。

具体用法放在高级定时器章节

输出比较(最常用)

输出比较就是通过定时器的外部引脚对外输出控制信号,有冻结、将通道 X(x=1,2,3,4)设置为

匹配时输出有效电平、将通道 X 设置为匹配时输出无效电平、翻转、强制变为无效电平、强制变

为有效电平、 PWM1 和 PWM2 这八种模式,具体使用哪种模式由寄存器 CCMRx 的位OCxM[2:0]配置。其中 PWM 模式是输出比较中的特例,使用的也最多。

输出比较

输出比较模式总共有 8 种,具体的由寄存器 CCMRx 的位 OCxM[2:0] 配置。

以 PWM1 模式来讲解,以计数器 CNT 计数的方向不同还分为边沿对齐模式和中心对齐模式。 PWM 信号主要都是用来控制电机,一般的电机控制用的都是边沿对齐模式, FOC 电机一般用中心对齐模式。日常开发中最常使用的模式为 PWM1 模式的向上计数模式,因此本文着重介绍该

模式,对于其他模式不做介绍。

在 PWM1 模式 1 向上计数模式中(极性不反转的情况下),当 CNT<CCR 时,输出比较通道对应输出有效电平,即高电平1,当 CNT>=CCR 时,输出比较通道输出无效电平,即低电平0。

PWM

PWM(Pulse Width Modulation)即脉冲宽度调制,在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速、开关电源等领域

PWM 中有三个重要参数:频率、占空比(高电平时长占整个周期信号时长的比例)、分辨率(占空比可调精度)。

频率 Freq: Freq = CK _ PSC /(PSC +1) /(ARR +1)

PWM 占空比: Duty = CCR /(ARR +1)

PWM 分辨率: Reso =1/(ARR +1)

CK_PSC 为技术单元时钟源频率 , PSC 为分频因子 , ARR 为目标计数值 , CCR 为 CCR寄存值

输出比较应用(PWM驱动直流电机)

初始化PWM,设置 PWM频率为100hz,分辨率为0.1%,占空比由TIM_SetComparex()函数配置(x可为1,2,3,4)

#include "pwm.h"

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720-1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 1000-1;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCStructInit(&TIM_OCInitStructure);
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse =0;    //CCR
	TIM_OC3Init(TIM2,&TIM_OCInitStructure);
	TIM_OC4Init(TIM2,&TIM_OCInitStructure);
	
	TIM_Cmd(TIM2,ENABLE);

}

void PWM_SetCompare3(uint16_t Compare)
{
	TIM_SetCompare3(TIM2,Compare);
}

void PWM_SetCompare4(uint16_t Compare)
{
	TIM_SetCompare4(TIM2,Compare);
}

void usart_PWM(uint16_t Compare1,uint16_t Compare2)
{
	TIM_SetCompare3(TIM2,Compare1);
	TIM_SetCompare4(TIM2,Compare2);
}

定义 pwm.h文件

#ifndef _PWM_H_
#define _PWM_H_
#include "stm32f10x.h" 
void PWM_Init(void);
void PWM_SetCompare3(uint16_t Compare);
void PWM_SetCompare4(uint16_t Compare);
void usart_PWM(uint16_t Compare1,uint16_t Compare2);
#endif

初始化串口中断,并重定义printf()和scanf()函数

#include "usart.h"

static void NVIC_Configuration(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority =1 ;
	NVIC_InitStruct.NVIC_IRQChannelCmd =ENABLE ;
	NVIC_Init(&NVIC_InitStruct);
}


void usart_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	
	/*TX*/
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	/*RX*/
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStruct;
	USART_InitStruct.USART_BaudRate = 9600;
	USART_InitStruct.USART_HardwareFlowControl =USART_HardwareFlowControl_None ;
	USART_InitStruct.USART_Mode =USART_Mode_Rx | USART_Mode_Tx ;
	USART_InitStruct.USART_Parity = USART_Parity_No;
	USART_InitStruct.USART_StopBits = USART_StopBits_1;
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART1,&USART_InitStruct);
	NVIC_Configuration();
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	USART_Cmd(USART1,ENABLE);
}
int fputc(int ch, FILE *f)
{
		/* 发送一个字节数据到串口 */
		USART_SendData(USART1, (uint8_t) ch);
		
		/* 等待发送完毕 */
		while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);		
	
		return (ch);
}

int fgetc(FILE *f)
{
		/* 等待串口输入数据 */
		while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

		return (int)USART_ReceiveData(USART1);
}

在接收中断中设置直流电机占空比 ,并通过上位机发送指令

void USART1_IRQHandler(void)
{
	uint8_t ch;
 ch = getchar();
	  printf( "ch=%c\n",ch );
		
		switch(ch)
   {
			case '1': 		usart_PWM(0,200);
				break;
		 
			case '2': 		usart_PWM(0,500);
			  break;
		 
			case '3': 		usart_PWM(0,1000);
			  break;
		 
			default: 		usart_PWM(1000,1000);
		    break;
	 
	}
}
相关推荐
水饺编程3 小时前
【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,1-2
linux·嵌入式硬件·fpga开发
电子科技圈4 小时前
IAR全面支持国科环宇AS32X系列RISC-V车规MCU
人工智能·嵌入式硬件·mcu·编辑器
SZPU领跑4 小时前
第十二届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)(第一套)
stm32·单片机·算法·职场和发展·蓝桥杯
逢生博客4 小时前
Rust 语言开发 ESP32C3 并在 Wokwi 电子模拟器上运行(esp-hal 非标准库、LCD1602、I2C)
开发语言·后端·嵌入式硬件·rust
Tlog嵌入式7 小时前
蓝桥杯【物联网】零基础到国奖之路:十六. 扩展模块之矩阵按键
arm开发·stm32·单片机·mcu·物联网·蓝桥杯·iot
打地基的小白7 小时前
UART通信—基于江科大源码基础进行的改进和解析
单片机·嵌入式硬件·uart通信·代码详解
黄小美3218 小时前
STM32(五)GPIO输入硬件电路及C语言知识复习
stm32·单片机·嵌入式硬件
py.鸽鸽8 小时前
STM32
stm32·单片机·嵌入式硬件
朴人8 小时前
【从零开始实现stm32无刷电机FOC】【实践】【7.1/7 硬件设计】
stm32·单片机·嵌入式硬件
国科安芯9 小时前
IAR全面支持国科环宇AS32X系列RISC-V车规MCU
人工智能·单片机·mcu·risc-v