介绍

输入捕获就是IC(input capture),捕获/比较是CC,CCR就是捕获/比较寄存器

PWM

通用定时器的输出比较路线

在控制器输入CNT和CCR数值的大小关系,输出高低电平,之后可以通过主模式映射到TRGO引脚,但主要是另一条路:高低电平经过极性选择,0就是输出电平不取反,1就要经过非门将电平取反,然后输出使能,允许输出。至于通过什么规定来对应大小关系和高低电平,取决于选择的输出比较模式

输出比较模式

通过配置输出比较单元,以及后面的是否取反,就得到最后输出的PWM信号。

参数计算

可以看出PWM频率和定时器频率是一样的,算法一样,因为周期都是CNT从0自增到ARR的时间;在CNT=29的时候还是高电平,CNT=CCR=30的一瞬间就是低电平了,所以高电平的时间是从0到CCR-1的时间,所以占空比=CCR/(ARR+1);分辨率是越小越好,CCR自由调整范围越大越好

相关装置

舵机

占空比固定的时候舵机角度就固定

直流电机

STBY置高是工作状态,置低就是待机,不管输入什么都不会工作,如果不需要待机就直接接VCC;工作状态下,两输入端如果电平相等,没有电压差,电机不会转动;输入端电平不相等即有电压差时,输入的PWM信号置高电平就会转,低电平不转,这样就能根据占空比来调节速度,转动方向由两输入端决定

PWM的输出通道是定时器的CH引脚,一共四个,对应关系如下

默认复用功能下的这些引脚都是复用在对应的IO口,如果有需要,也可以使用重映射,可以将重定义下这些引脚复用在另外对应的IO口。例如:TIM2_CH3和ADC12_IN2都是复用在PA2引脚的,如果需要同时使用这两个,但是他们引脚冲突,此时在重映射下TIM2_CH3还可以复用在PB10引脚。

初始化PWM代码

使用定时器输出比较功能输出PWM信号,先开启RCC时钟,选择内外时钟源,再配置时基单元,然后配置输出比较单元(包括CCR的值,输出比较模式,输出使能和极性选择),接着将用到的GPIO口初始化,最后启动定时器

void PWM_init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	//接下来选择内外时钟源,这里选内部时钟
	TIM_InternalClockConfig(TIM2);
	
	//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//滤波器参数,对内部时钟没用,不分频
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数器模式,向上计数
	TIM_TimeBaseInitStructure.TIM_Period=100-1;//自动重装值ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler=72-1;//分频值PSC
	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;//输出比较模式,PWM1模式
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//极性选择,不取反
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//输出使能
	TIM_OCInitStructure.TIM_Pulse=0;//CCR的值
	TIM_OC1Init(TIM2,&TIM_OCInitStructure);//输出比较有四个引脚选择,这里OC1是使用CH1引脚
	
	//初始化GPIO,因为使用了CH1引脚,根据GPIO口复用关系,对应了PA0引脚
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出,普通的输出模式控制权在寄存器,要让定时器即片上外设来控制GPIO口就需要复用输出
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	//启动定时器
	TIM_Cmd(TIM2,ENABLE);
}

初始化完成之后就会在对应IO口输出参数固定的PWM信号

但有时候需要占空比不固定,可以使用函数单独改变CCR的值

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


 

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐