老规矩,先上代码 https://github.com/Tuya-Community/tuya-iotos-embeded-mcu-demo-wifi-ble-steering-engine

舵机原理


舵机简单的说就是集成了直流电机,电机控制器和减速器等,并封装在一个便于安装的外壳里的伺服单元。它是一个能够利用简单的输入信号,比较精确地转动给定角度的电机系统。舵机安装了一个电位器(或其他角度传感器)检测输出轴转动角度,控制板根据电位器的信息能够比较准确的控制和保持输出轴的角度,形成闭环控制,所以舵机更准确的说是伺服马达。

舵机信号

舵机一般采用PWM信号控制,周期一般为20ms,高电平持续时间最少为0.5mS,一般在0.5ms~2.5ms之间。具体如下图:

例程分析


弄明白了舵机的控制信号之后,接下来就是要如何产生这样的信号。小编以STM32G071为例(stm32各个系列,产生方法均类似),带大家一步步讲解。
初始化程序如下,采用TIM16 CH1通道产生PWM波形
void ConfigureTIM16_CH1_AsPWM_EdgeAligned(void)
{
RCC->APBENR2 |= 1<<17;
RCC->IOPENR |= 1<<3;
GPIOD->MODER &=~(3<<0);
GPIOD->MODER |= 2<<0;
GPIOD->AFR[0]&=0XFFFFFFF0;
GPIOD->AFR[0] |= 0x02 << 0;

TIM16->PSC = 159;
TIM16->ARR = 1999;
TIM16->CCR1 = 150;
TIM16->CCMR1 |=6<<4|1<<3;
TIM16->CCER |= 1<<0;
TIM16->CR1 |= 1<<0;
TIM16->EGR |= 1<<0;
TIM16->BDTR |=1<<14;
}
下面是分析
因为我们用定时器TIM16产生PWM,所以要先使能TIM16时钟
RCC->APBENR2 |= 1<<17;

通过数据手册可以得知,PD0具有TIM16的CH1通道PWM功能,
因此还要初始化PD0。

先使能GPIOD;
RCC->IOPENR |= 1<<3;

再将PD0配置成复用功能模式。
GPIOD->MODER &=~(3<<0);
GPIOD->MODER |= 2<<0;

那复用功能那么多,哪个才是TIM16_CH1呢?

通过手册可以发现是AF2,于是,可以如下配置。
GPIOD->AFR[0]&=0XFFFFFFF0;
GPIOD->AFR[0] |= 0x02 << 0;

好了,PD0基本配置好了,接下来就是配置TIM16了
先设置预分频器

TIM16->PSC = 159;
这句话将16M系统时钟的1/(159+1)用于TIM16时钟,那么可以计算出TIM16时钟频率为100KHz,即每计一个数,需要10us。

根据上面舵机原理,周期要20ms,因此一个周期,需计(1999+1)个数
所以自动重载值配置如下
TIM16->ARR = 1999;

接下来配置高电平时间,可以通过比较寄存器配置,具体如下
TIM16->CCR1 = 150;
CCR1*10us就是高电平时间,以0.5ms到2.5ms为例,那么CCR1取值范围为50~250.

TIM16->CCMR1 |=6<<4|1<<3;
这句功能为将TIM16配置成PWM模式1,并且使能与 TIM16_CCR1 相关的预装载寄存器

TIM16->CCER |= 1<<0;
这句话将输出极性设置为高电平有效。
后面就可以使能TIM16计数器,边沿对齐,递增方式
TIM16->CR1 |= 1<<0;

更新中断
TIM16->EGR |= 1<<0;

自动输出使能
TIM16->BDTR |=1<<14;

好了,至此,TIM16_CH1的PWM模式已配置好了,可以用示波器去看看波形是不是大家想要的。
另外,需要调整占空比,之需要修改CCR1的值就行,比如现在是1ms,修改成2ms,只要执行一下TIM16->CCR1 = 200;即可

好啦,小编就不啰嗦啦,祝大家玩的愉快,程序有疑问,可以在底下留言,我会一一为大家解答。
 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐