赞
踩
在基本定时器功能的基础上新增功能:
通用定时器有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(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寄存值
IC(Input Capture)输入捕获
输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
每个高级定时器和通用定时器都拥有4个输入捕获通道 可配置为PWMI模式,同时测量频率和占空比
可配合主从触发模式,实现硬件全自动测量
测量脉宽和频率还有一个更简便的方法就是使用 PWM 输入模式,该模式是输入捕获的特例,只
能使用通道 1 和通道 2,通道 3 和通道 4 使用不了。与上面那种只使用一个捕获寄存器测量脉宽
和频率的方法相比, PWM 输入模式需要占用两个捕获寄存器
当使用 PWM 输入模式的时候,因为一个输入通道 (TIx) 会占用两个捕获通道 (ICx),所以一个定
时器在使用 PWM 输入的时候最多只能使用两个输入通道 (TIx)。
PWM 信号由输入通道 TI1 进入,因为是 PWM 输入模式的缘故,信号会被分为两路,一路是
TI1FP1,另外一路是 TI1FP2。其中一路是周期,另一路是占空比,具体哪一路信号对应周期还
是占空比,得从程序上设置哪一路信号作为触发输入,作为触发输入的哪一路信号对应的就是
周期,另一路就是对应占空比。
- #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);
- }
- #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
- #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;
-
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。