尼玛啊,很久前我买了6个舵机啊,辉盛的MG995啊。。。。自己想做个机械手玩,六自由度的。
组装完成之后开始写程序,那时候还是用51,然后就改成用MINI STM32,两个通用,产生6路PWM,
舵机频率固定50HZ ,靠占空比控制。。(这么说来STM32F1还可以控制30多路耶。)
还专门买了一个5V10A的电源。
单个舵机都没问题的,上了机架之后就肘关节动不了了,说好的10KG扭力的呢????
这连1斤的重量都不到啊,这么抬不起呢?摩擦也没问题啊。。
后来不知道咋滴,居然冒烟了。。而且有些还滑牙了
我了个去。。
坏得只剩2个好的,3个滑牙,1个冒烟烧了。。
一个舵机4、50块啊。。我这没钱玩下去了,所以就放弃了。
这视频是还算好的情况。。。不过隔天就冒烟了。
就最近,我想那两个好的应该还能用吧。。。
没想到他连摄像头都抬不动。。泪奔。
勉勉强强动下还可以。。。
发帖求安抚。
我待国产如初恋,国产扇我千百遍。
感觉不会再爱了。
顺便开源,让有玩舵机的方便一些。。还有,国产舵机请慎挑。
STM32F10X的:
寄存器版:
void PWM_Init_Tim2(u16 arr,u16 psc)
{
//此部分需手动修改IO口设置
RCC->APB1ENR|=1<<0; //TIM2时钟使能
GPIOA->CRL&=0XFFFFFF00;//PA0/1输出
GPIOA->CRL|=0X000000BB;//复用功能输出
GPIOA->ODR|=3<<0;//PA0/1上拉
GPIOA->CRL&=0XFFFF00FF;//PA2/3输出
GPIOA->CRL|=0X0000BB00;//复用功能输出
GPIOA->ODR|=3<<2;//PA2/3上拉
TIM2->ARR=arr;//设定计数器自动重装值
TIM2->
SC=psc;//预分频器不分频
TIM2->CCMR1|=7<<4;// CH1
TIM2->CCMR1|=1<<3;
TIM2->CCMR1|=7<<12;//
CH2
TIM2->CCMR1|=1<<11;
TIM2->CCMR2|=7<<4;//
CH3
TIM2->CCMR2|=1<<3;
TIM2->CCMR2|=7<<12;//
CH4
TIM2->CCMR2|=1<<11;
TIM2->CCER|=1<<0;//CH1
TIM2->CCER|=1<<4;//CH2
TIM2->CCER|=1<<8;//CH3
TIM2->CCER|=1<<12;//CH4
TIM2->CR1|=1<<7; //ARPE使能
TIM2->CR1|=0x01; //使能定时器3
}
void PWM_Init_Tim3(u16 arr,u16 psc)
{
//此部分需手动修改IO口设置
RCC->APB1ENR|=1<<1; //TIM3时钟使能
GPIOA->CRL&=0X00FFFFFF;//PA6/7输出
GPIOA->CRL|=0XBB000000;//复用功能输出
GPIOA->ODR|=3<<6;//PA6/7上拉
TIM3->ARR=arr;//设定计数器自动重装值
TIM3->
SC=psc;//预分频器不分频
//CH1/2 PWM2模式
//CH1/2预装载使能
TIM3->CCMR1|=7<<4;//CH1
TIM3->CCMR1|=1<<3;//
TIM3->CCMR1|=7<<12;//CH2
TIM3->CCMR1|=1<<11;//
//OC1/2 输出使能
TIM3->CCER|=1<<0;//CH1
TIM3->CCER|=1<<4;//CH2
//
TIM3->EGR|=1;//更新事件
TIM3->CR1|=1<<7; //ARPE使能
多余的一句
TIM3->CR1|=0x01; //使能定时器3
}
库函数版:
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
//使能定时器3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射 TIM3_CH2->
B5
//设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形
GPIOB.5 GPIOB.4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_0; //TIM_CH2|TIM_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
//初始化TIM3
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}
用法:库和寄存器一样 TIM3_PWM_Init (19999,71);
调占空比CCR的值选是19500~17500之间,库用TIM_SetCompare2(TIM3, "CCR" ); 算法是 20000-(500+text*7.8125); text范围是0~256;
F4版本
F4的寄存器版不会。。。= =
库函数:
void PWM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIOC and GPIOB clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* GPIOB Configuration: TIM3 CH3 (PB0) and TIM3 CH4 (PB1) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect TIM3 pins to AF2 */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM3);
/* -----------------------------------------------------------------------
TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles.
In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1),
since APB1 prescaler is different from 1.
TIM3CLK = 2 * PCLK1
PCLK1 = HCLK / 4
=> TIM3CLK = HCLK / 2 = SystemCoreClock /2
To get TIM3 counter clock at 28 MHz, the prescaler is computed as follows:
Prescaler = (TIM3CLK / TIM3 counter clock) - 1
Prescaler = ((SystemCoreClock /2) /28 MHz) - 1
To get TIM3 output clock at 30 KHz, the period (ARR)) is computed as follows:
ARR = (TIM3 counter clock / TIM3 output clock) - 1
= 665
TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
Note:
SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.
Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
function to update SystemCoreClock variable value. Otherwise, any configuration
based on this variable will be incorrect.
----------------------------------------------------------------------- */
PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 1000000) - 1;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 19999;
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/* PWM1 Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0x0000;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel4 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0x0000;
TIM_OC4Init(TIM3, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);
/* TIM3 enable counter */
TIM_Cmd(TIM3, ENABLE);
}
伤心,钱被坑了。
---------------------------------
请问MG995控制方式是怎样的呢?我看资料是0.5ms到2.5ms,基准是1.5ms吗?我不是相关专业的学生,所以我不太清楚哦,为什么你设置TIM2->CCMR1那里111模式呢?那样假如占空比调到百分之10的话,那不就是18ms高电平,2ms低电平了么?
一周热门 更多>