完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
一、前言
利用STM32的TIM3的通道1输出PWM信号,驱动MG996R舵机,按键控制。 相关知识:TIM定时器基本原理,TIM输出PWM信号、MG996R舵机驱动原理 二、MG996R舵机简介 MG996R舵机单线驱动,是一款360°舵机,180°舵机与360°舵机的区别就是:180°舵机可以直接控制舵机旋转的角度,但舵机只能够旋转180°;360°舵机无法直接控制其旋转角度,只能控制其转动方向和速度。 舵机的驱动信号由周期为20ms的脉冲来控制:
三、通用定时器TIMx 通用TIMx定时器(TIM2、TIM3、TIM4和TIM5)功能主要包括如下: 16位向上、向下、向上/向下自动装载计数器 16位可编程(可以实时修改)预分频器,分频系数为1~65535 四种独立通道功能: 1.输入捕获 2.输出比较 3.PWM生成 4.单脉冲输出 使用外部信号控制定时器和定时器互连的同步电路 可以由如下事件触发中断或者DMA: 1.更新,即计数器溢出,或者计数器初始化 2.特定的触发事件,比如:计数器启动、停止、初始化等等 3.输入捕获 4.输出比较 支持针对定位的增量(正交)编码器和霍尔传感电路 触发输入作为外部时钟或者按周期的电流管理 可编程通用定时器的主要部分是一个16位计数器和其相关的自动装载寄存器,前面也说了,计数器可以向上、向下、双向计数。既然要计数,那就必须要知道计数的多少和每一次计数的时间。计数器的时钟由预分频器对时钟源分频得到。 时基单元包括: 计数器寄存器(TIMx_CNT) 预分频器寄存器(TIMx_PSC) 自动装载寄存器(TIMx_ARR) 计数器寄存器中存储的是当前计数的值,自动装载寄存器中存储的是目标计数值,当计数器溢出后,会重新装填目标计数值,而预分频器寄存器中的是对时钟的分频系数。 有专门的三个寄存器来控制PWM: 捕获/比较模式寄存器(TIMx_CCMR1/2) 捕获/比较使能寄存器(TIMx_CCER) 捕获/比较寄存器(TIMx_CCR1~4) 四、TIM3输出PWM信号代码详解 输出PWM用到的TIMx初始化结构体有: 1 1.时基初始化结构体TIM_TimeBaseInitTypeDef 2.输出比较初始化结构体TIM_OCInitTypeDef typedef struct { uint16_t TIM_Prescaler; // 预分频器 uint16_t TIM_CounterMode; // 计数模式 uint32_t TIM_Period; // 定时器周期 uint16_t TIM_ClockDivision; // 时钟分频 uint8_t TIM_RepetitionCounter; // 重复计算器 } TIM_TimeBaseInitTypeDef; TIM_Prescaler:预分频器设置,只有经过预分频器后的时钟才是CK_CNT,计数器时钟频率 (fCK_CNT) 等于fCK_PSC / (PSC[15:0] + 1),可实现 1 至 65536 分频。 TIM_CounterMode:定时器计数模式,可设置向上计数、向下计数和中心对齐计数三种模式。 TIM_Period:设置的是自动重装寄存器ARR的值,ARR为要装载到影子寄存器的值,可设置 1 至 65536 。 TIM_ClockDivision:时钟分频,设置定时器时钟 CK_INT 频率与死区发生器以及数字滤波器采样时钟频率分频比。可以选择 1、 2、 4 分频。 TIM_RepetitionCounter:重复计数器,只有八位,只存在与高级定时器。 typedef struct { uint16_t TIM_OCMode; // 比较输出模式 uint16_t TIM_OutputState; // 比较输出使能 uint16_t TIM_OutputNState; // 比较互补输出使能 uint32_t TIM_Pulse; // 脉冲宽度 uint16_t TIM_OCPolarity; // 输出极性 uint16_t TIM_OCNPolarity; // 互补输出极性 uint16_t TIM_OCIdleState; // 空闲状态下比较输出状态 uint16_t TIM_OCNIdleState; // 空闲状态下比较互补输出状态 } TIM_OCInitTypeDef; TIM_OCMode:比较输出模式选择,总共有八种,常用的为 PWM1/PWM2。它设定 CCMRx 寄存器 OCxM[2:0]位的值。 TIM_OutputState:比较输出使能,决定最终的输出比较信号 OCx 是否通过外部引脚输 出。它设定 TIMx_CCER 寄存器 CCxE/CCxNE 位的值。 TIM_OutputNState:比较互补输出使能,决定 OCx 的互补信号 OCxN 是否通过外部引脚 输出。它设定 CCER 寄存器 CCxNE 位的值。 TIM_Pulse:比较输出脉冲宽度,实际设定比较寄存器 CCR 的值,决定脉冲宽度。可 设置范围为 0 至 65535。 TIM_OCPolarity:比较输出极性,可选 OCx 为高电平有效或低电平有效。它决定着定 时器通道有效电平。它设定 CCER 寄存器的 CCxP 位的值。 TIM_OCNPolarity:比较互补输出极性,可选 OCxN 为高电平有效或低电平有效。它 设定 TIMx_CCER 寄存器的 CCxNP 位的值。 TIM_OCIdleState:空闲状态时通道输出电平设置,可选输出 1 或输出 0,即在空闲状 态(BDTR_MOE 位为 0)时,经过死区时间后定时器通道输出高电平或低电平。它设定 CR2 寄存器的 OISx 位的值。 TIM_OCNIdleState:空闲状态时互补通道输出电平设置,可选输出 1 或输出 0,即在 空闲状态(BDTR_MOE 位为 0)时,经过死区时间后定时器互补通道输出高电平或低电 平,设定值必须与 TIM_OCIdleState 相反。它设定是 CR2 寄存器的 OISxN 位的值。 当要输出PWM信号时只需要配置如下成员即可: uint16_t TIM_OCMode; // 比较输出模式 uint16_t TIM_OCPolarity; // 输出极性 uint16_t TIM_OutputState; // 比较输出使能 输出极性决定了有效电平是高电平还是低电平 void GENERAL_TIM_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // TIM_DeInit( TIM3 ); TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_PERIOD; // 驱动CNT计数器的时钟 = Fck_int/(psc+1) TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_PSC; // 时钟分频因子 ,配置死区时间时需要用到 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 计数器计数模式,设置为向上计数 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 初始化定时器 TIM_TimeBaseStructure.TIM_RepetitionCounter=0; TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 输出使能 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 输出通道电平极性配置 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = GENERAL_TIM_CCR3; TIM_OC3Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC3PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); // TIM_ARRPreloadConfig( TIM3, ENABLE ); TIM_Cmd( TIM3, ENABLE ); } `` ```c // 输出PWM的频率为 72M/{ (ARR+1)*(PSC+1) } #define GENERAL_TIM_PERIOD (200-1) #define GENERAL_TIM_PSC (7200-1) #define GENERAL_TIM_CCR3 0 主函数 while(1) { key=KEY_Scan(1); //得到键值 if(key) { switch(key) { case KEY1_PRES: //反向最大转速 TIM_SetCompare3(TIM3,25); break; case KEY0_PRES: //正向最大转速 TIM_SetCompare3(TIM3,5); break; case WE_UP_PRES: TIM_SetCompare3(TIM3,15); //停止 break; } } } TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2); 函数改变ccr,从而改变PWM信号的占空比。 /* 20ms脉冲 5-14 正转,值越小,转的越快 16-25 反转,值越大,转的越快 */ |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1780 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1081 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1679 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
556浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 04:10 , Processed in 0.624646 second(s), Total 46, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号