伺服电机脉冲控制的多种方式(AB相脉冲,方向脉冲,CW/CCW脉冲)

脉冲信号可以分为AB相脉冲,脉冲+方向,CW/CCW脉冲。

这三种信号格式,在十几年前或者还有明显的相对优缺点和适用场合,现在就已经无所谓了,即使在使用上还是有所区分,也基本上是由于历史习惯。

1、A/B信号:

  位置传感器最喜欢的格式。因为,早期的编码器直接就是用两个传感器输出两路信号的。靠传感器安装的相对位置确保两个信号的相对相位关系。在传感器后面直接加上两个电压比较器,就直接得到了A/B的方波信号输出。如果要让编码器输出两位两种信号,都还需要特定的信号转换。

现在,高分辨率的编码器/光栅尺/磁栅尺……,虽然内部传感器上产生的还是相位差1/4周期的两路信号,但在输出时都要经过细分处理,而细分以后输出什么形式的脉冲信号,其实在技术上没有什么区别。还采用A/B信号的形式,基本上是由于传统。因为这样可以匹配各种现成的接收器。

对于A/B信号的所谓“四倍频”,是对信号的解读方式,所以不存在“输出本身就被4倍频”这种概念。所谓四倍频,是指接受信号的计数器,不是每个脉冲周期计数一次,而是A/B的每个上升沿/下降沿都各计数一次,一个完整的信号周期会计数四次。

对于编码器类的产品本身标称的分辨率是只一个完整信号周期对应的长度/角度,还是1/4信号周期对应的长度/角度,在习惯上各有不同。一般来说,旋转编码器说XXX线/转的时候,是指完整的信号周期。直线的光栅磁栅在说分辨率的时候,是指1/4周期。但是也不敢保证所有产品都是这样标称,具体产品,还是问清楚厂家或商家比较有谱。不过,国内有些商家,由于行业竞争激烈,养不起技术服务人员,甚至有些厂家也养不起做服务的技术人员。客户能接触到的人,也不一定真的清楚细节吧。

比如下面这个周期

A 1 0 0 1

B 1 1 0 0

假设静止在 A0B1这个位置,A被干扰多了1个高电平脉冲,变成A1B1了,当干扰过去之后,就会恢复A0B1。而其它2种,多一个脉冲就真的多一个脉冲了。并且在高速运动中,因为必然是向一个方向走,比如上面这个例子,所有数字量逻辑都必须符合从左到右这个规律。任何反方向的移动都可以认为是干扰排除。还是在A0B1这个位置,下一个位置必须是A0B0,如果是A1B1,就认为A被干扰了。

脉冲+方向,CW/CCW脉冲这2种,相对而言我认为CW/CCW相对好一点,因为脉冲+方向必须是方向正确后的脉冲才有正确的方向。如果切方向切在脉冲输入后,那么切方向前的脉冲就反了。

2、脉冲/方向信号

  控制器最喜欢的信号格式,因为只要一个高速脉冲输出口就可以实现一个电机的控制。现在,对于各种控制核心(MCU、FPGA、DSP等等)来说,高速脉冲输出口已经不算是什么宝贵资源了。而且不同形式的脉冲格式转换也很简单,但是这个传统依然还在。而且一些完整的控制产品,比如PLC上,高速脉冲输出口也还是一种有限的资源。

3、CW/CCW脉冲

  驱动器最喜欢的格式,因为这种格式解读起来最简单。A/B格式,要识别每个上升沿和下降沿,CW和CCW只要识别各自的一个边沿就可以了。脉冲/方向信号虽然也很简单,但是存在一个匹配的问题,当匹配不好的时候,在特定情况下会出现解读错误,造成可累计的误差。

综上所述,

A/B脉冲:有一点绝对值的味道,可以纠错。

CW/CCW脉冲:对电磁干扰无法免疫,但是2个输出独立。

脉冲+方向:对电磁干扰无法免疫,2个输出相互影响必须同时作用。

  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MSP430可以使用定时器模块来控制步进电机的旋转角度。下面是一个控制步进电机旋转角度的示例代码: ```c #include <msp430.h> #define STEP1 BIT0 // 步进电机引脚1 #define STEP2 BIT1 // 步进电机引脚2 #define STEP3 BIT2 // 步进电机引脚3 #define STEP4 BIT3 // 步进电机引脚4 #define CW 1 // 设置步进电机方向,1为顺时针,-1为逆时针 #define CCW -1 unsigned char stepper_table[] = {0x01, 0x02, 0x04, 0x08}; // 步进电机状态表 volatile unsigned int step_count = 0; // 步进电机旋转的角度 volatile unsigned char step_pos = 0; // 步进电机当前的位置 void delay(unsigned int n) { // 延时函数 volatile unsigned int i, j; for (i = 0; i < n; i++) for (j = 0; j < 100; j++); } void stepper_step(int dir) { // 步进电机单步操作函数 step_pos += dir; // 更新步进电机的位置 if (step_pos > 3) step_pos = 0; if (step_pos < 0) step_pos = 3; P1OUT &= ~(STEP1 | STEP2 | STEP3 | STEP4); // 输出步进电机控制信号 P1OUT |= stepper_table[step_pos]; } void main(void) { WDTCTL = WDTPW + WDTHOLD; // 停用看门狗定时器 P1DIR |= STEP1 | STEP2 | STEP3 | STEP4; // 步进电机引脚设置为输出模式 P1OUT &= ~(STEP1 | STEP2 | STEP3 | STEP4); TA0CCR0 = 1000; // 定时器计数值 TA0CTL = TASSEL_2 + MC_1; // 设置定时器来源和计数模式 TA0CCTL0 = CCIE; // 定时器计数中断使能 __enable_interrupt(); // 开启中断 while (1) { int i; for (i = 0; i < 200; i++) { // 控制步进电机旋转的角度 delay(2000); } step_count = 0; } } #pragma vector = TIMER0_A0_VECTOR // 定时器中断处理函数 __interrupt void Timer_A0_ISR(void) { if (step_count < 200) { // 控制步进电机旋转的角度 stepper_step(CW); // 控制步进电机旋转方向 step_count++; } else { TA0CTL = MC_0; // 停止定时器 TA0CCTL0 &= ~CCIE; // 关闭定时器计数中断 } } ``` 该示例代码使用 MSP430 控制一个两步进电机,通过定时器中断来控制步进电机的旋转角度。在 `stepper_step()` 函数中,通过更新 `step_pos` 变量来更新步进电机的位置,并使用 `stepper_table` 数组来输出步进电机控制信号。在 `main()` 函数中,设置定时器计数值和计数模式,并开启定时器中断。在定时器中断处理函数中,控制步进电机旋转的角度,并在旋转到指定角度时停止定时器计数和中断。需要注意的是,实际控制步进电机旋转角度的代码需要根据具体的步进电机型号和控制要求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值