STM32 PWM OC IC

OC(Output Compare) 输出比较

输出比较可以通过比较CNT(计数器)与CCR捕获/比较寄存器值的关系,来对输出电平进行置1,置0或翻转的操作,用于输出一定频率和占空比的PWM波形

每个高级定时器和通用定时器都拥有4个输出比较通道

高级定时器的前3个通道额外拥有死区生成和互补输出的功能STM32 PWM OC IC_第1张图片

 STM32 PWM OC IC_第2张图片

当CNT>CCR,

STM32 PWM OC IC_第3张图片

STM32 PWM OC IC_第4张图片

STM32 PWM OC IC_第5张图片

 电平翻转,占空比始终为50%

STM32 PWM OC IC_第6张图片

 STM32 PWM OC IC_第7张图片

重要函数:

初始化输出比较模块

void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

输出比较结构体赋默认值

void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);

STM32 PWM OC IC_第8张图片

 #include "PWM.h"   
//第一步,RCC开启时钟,把TIM外设和GPIO外设打开
//第二步,配置时基单元(PSC,ARR,CNT)
//第三步,配置输出比较单元,里面包括(CCR,输出比较模式,极性选择,输出使能)
//第四步,PWM对应GPIO,初始化配置对复用推挽输出
//第五步,运行控制

void PWM_Init()
{
	//第一步,RCC开启时钟,把TIM外设和GPIO外设打开
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	//第二步,配置时基单元(PSC,ARR,CNT)
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period=100-1;
	TIM_TimeBaseInitStruct.TIM_Prescaler=720-1;
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
//第三步,配置输出比较单元,里面包括(CCR,输出比较模式,极性选择,输出使能)
	TIM_OCInitTypeDef TIM_OCInitStruct;
	//初始化
	TIM_OCStructInit(&TIM_OCInitStruct);
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse=50;
	TIM_OC3Init(TIM2,&TIM_OCInitStruct);
	//第四步,PWM对应GPIO,初始化配置对复用推挽输出
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStruct);
	//第五步,运行控制
	TIM_Cmd(TIM2, ENABLE);
	
	
}
void PWM_SetComparel(uint16_t Compare)
{
	TIM_SetCompare3(TIM2,Compare);
}


void PWM_SetPrescaler(uint16_t Prescaler)
{
	TIM_PrescalerConfig(TIM2,Prescaler,TIM_PSCReloadMode_Immediate);
}



 

 输入捕获简介

IC (Input Capture)输入捕获

输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT输入捕获模式下,当通道输入引脚出现指定电平跳变下,当前CNT的值将被所存到CCR种中,可用于测量PWM波形的频率,占空比,脉冲间隔,电平持续时间等参数

每个高级定时器和通用定时器都有4个输入捕获通道

可配置为PWMI模式,同时测量频率和占空比

可配置主从触发模式,实现硬件全自动测量

STM32 PWM OC IC_第9张图片

STM32 PWM OC IC_第10张图片

测周法:测量时间的方法,实际上是用一个定时器计次,使用一个已知标准频率fc的计次时钟来驱动计数器,从一个上升沿开始计数,一直计到下一个上升沿,记一个数的时间是1/fc,N个数是N/fc

取个倒数为频率fc/N

 STM32 PWM OC IC_第11张图片

STM32 PWM OC IC_第12张图片

PWMI模式:第一个捕获通道,使用上升沿触发,用来捕获周期        

第二个通道,使用下降沿触发,用来捕获占空比

一个通道灵活切换两个引脚,和两个通道同时捕获一个引脚

STM32 PWM OC IC_第13张图片

 STM32 PWM OC IC_第14张图片

 只有T1FP1,T2FP2,没有TI3,TI4,如果想使用从模式自动清0,只能用通道1,通道2

STM32 PWM OC IC_第15张图片

 两通道测频率和占空比

STM32 PWM OC IC_第16张图片

 

 #include "IC.h"   
//第一步 RCC开启时钟,把GPIO和TIM时钟打开
//第二步 GPIO初始化,把GPIO设置成输入模式(上拉,浮空)
//第三步,配置时基单元,让CNT计数器在内部时钟自增运行
//第四步,配置输入捕获单元
//第五步,选择从模式触发源
//第六步,选择从模式 Reset操作
//第七步,调用TIM_Cmd函数,开启定时器


void IC_Init()
{
	//第一步 RCC开启时钟,把GPIO和TIM时钟打开
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	//第三步,配置时基单元,让CNT计数器在内部时钟自增运行
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period=65536-1; //ARR
	TIM_TimeBaseInitStruct.TIM_Prescaler=72-1; //PSC
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
	//第二步 GPIO初始化,把GPIO设置成输入模式(上拉,浮空)
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStruct);
	//第四步,配置输入捕获单元
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;
	TIM_ICInitStruct.TIM_ICFilter=0xf;
	TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;
	TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1	;
	TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;
	TIM_ICInit(TIM3, & TIM_ICInitStruct); 
	//第五步,选择从模式触发源
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);
	//第六步,选择从模式 Reset操作
	TIM_SelectSlaveMode( TIM3, TIM_SlaveMode_Reset);//CNT自动清0	
	
	TIM_Cmd(TIM3,ENABLE);
}


uint32_t IC_GetFreg()
{
	return 1000000/ TIM_GetCapture1(TIM3);

}


 

测频率占空比

 #include "IC.h"   
//第一步 RCC开启时钟,把GPIO和TIM时钟打开
//第二步 GPIO初始化,把GPIO设置成输入模式(上拉,浮空)
//第三步,配置时基单元,让CNT计数器在内部时钟自增运行
//第四步,配置输入捕获单元
//第五步,选择从模式触发源
//第六步,选择从模式 Reset操作
//第七步,调用TIM_Cmd函数,开启定时器


void IC_Init()
{
    //第一步 RCC开启时钟,把GPIO和TIM时钟打开
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    //第三步,配置时基单元,让CNT计数器在内部时钟自增运行
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInitStruct.TIM_Period=65536-1; //ARR
    TIM_TimeBaseInitStruct.TIM_Prescaler=72-1; //PSC
    TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
    //第二步 GPIO初始化,把GPIO设置成输入模式(上拉,浮空)
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init( GPIOA, &GPIO_InitStruct);
    //第四步,配置输入捕获单元
    TIM_ICInitTypeDef TIM_ICInitStruct;
    TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;
    TIM_ICInitStruct.TIM_ICFilter=0xf;
    TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;
    TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1    ;
    TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;
    TIM_ICInit(TIM3, & TIM_ICInitStruct); 
    //第二通道(方法一)
//    TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;
//    TIM_ICInitStruct.TIM_ICFilter=0xf;
//    TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Falling;
//    TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1    ;
//    TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_IndirectTI;
    第二通道(方法二)
    TIM_PWMIConfig(TIM3, &TIM_ICInitStruct);
    
    TIM_ICInit(TIM3, & TIM_ICInitStruct); 
    //第五步,选择从模式触发源
    TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);
    //第六步,选择从模式 Reset操作
    TIM_SelectSlaveMode( TIM3, TIM_SlaveMode_Reset);//CNT自动清0    
    
    TIM_Cmd(TIM3,ENABLE);
}


uint32_t IC_GetFreg()
{
    return 1000000/ TIM_GetCapture1(TIM3);

}

uint32_t    IC_getDuty()
{
    return     (TIM_GetCapture2(TIM3)+1)*100/ TIM_GetCapture1(TIM3);
}


 

你可能感兴趣的:(stm32,嵌入式硬件,单片机)