lb0857 发表于 2021-9-27 18:05:33

求:单片机采集20路编码器的思路

测量20路电机转速,利用机器现有的编码器进行
编码器输出脉冲频率最大400hz   最低60hz   

一共是20路   需要实时采集频率送给上位机进行处理   
中断/STM32单片机也就16路   是一个问题

坛友 有没有其他好的思路望赐教   好的建议lz请吃汤圆{:tongue:} {:loveliness:}

令狐冲 发表于 2021-9-27 18:07:37

用两片单片机

BOERLBH 发表于 2021-9-27 18:27:07

是总共20路编码器的AB信号还是 20个编码器? 第一种情况 简单,相当于只用采集10路信号就行,方向信号用硬件+普通IO口判断。 第二中情况。能不能这样做。 比如 1-16 路接在PA0-PA15上,17-20 接在PB12-PB15上。然后在中断里面判断具体引脚。 这个我没试验过,也不知道。

wycox 发表于 2021-9-27 18:40:26

采用外部计数器芯片吧

lb0857 发表于 2021-9-27 20:41:55

CD4051单端8通道多路开关,
C、B、A 用来选择通道号输出到单片机中断io口
分时进行中断采集
如: 50ms给每一路采集时间   
多次采集进行滤波处理之后 即可
这是其他项目采用方案用起来效果还可以不占用太多中断资源   普通STC单片机也可以胜任

dukelec 发表于 2021-9-27 20:42:03

編碼器端加小板子把數據轉 485 再傳送到 MCU

BOERLBH 发表于 2021-9-27 20:48:47

你这个频率比较低,STM32 所有有IO都能当外部中断输入。用一个定时器做一个 比如10uS的时基。然后再定义20个变量。两次外部中断上升沿(或者下降沿)之间 让对应的变量计数。根据计数值就能算出频率。时基越小精度越高。20路 400Hz 我估计没问题。以前 我用这种方式 在C8051上 做过PWM输出(相当于IO口模拟PWM)。2路频率2K都没问题。

wye11083 发表于 2021-9-27 21:00:12

BOERLBH 发表于 2021-9-27 20:48
你这个频率比较低,STM32 所有有IO都能当外部中断输入。用一个定时器做一个 比如10uS的时基。然后再定义20 ...

你这太费劲了。最简单最便宜的,stc8调到4khz中断,然后去读io,之后用软件去解码。仅仅是计算个频率而已,最大400hz,中断读数据,正常状态处理数据,轻轻松松而已。

lb0857 发表于 2021-9-27 21:33:01

谢谢各位参与汤圆请笑纳{:handshake:}{:hug:}{:hug:}

modbus 发表于 2021-9-27 21:39:09

0.5ms的定时中断扫描IO足矣

lb0857 发表于 2021-9-27 23:01:07


如果用CD4051单端8通道多路开关,50ms转换一次端口20个刚好是1s
然后,根据一个io口-----50ms采集到的脉冲数量*50   就是时间1s单路的脉冲总数
分时复用   
这样方案大家看看如何

bad_fpga 发表于 2023-9-15 22:36:21

lb0857 发表于 2021-9-27 23:01
如果用CD4051单端8通道多路开关,50ms转换一次端口20个刚好是1s
然后,根据一个io口-----50ms采集到的脉 ...
(引用自11楼)

最后采用什么方案了?

tomzbj 发表于 2023-9-15 23:33:17

参考之前看到的一个旋转编码器的驱动, 挺有意思
用两个普通GPIO, 每次读2bit, 把上次的2bit左移两位, 拼成4bit
那么如果转了, 只能是0001, 0111, 1110, 1000, 或者是0010, 1011, 1101, 0100这8种情况.
如果是0000, 0101, 1010, 1111, 说明没转, 如果是0011, 1100, 0110, 1001, 说明读取间隔太慢, 漏读了一次.

然后把读编码器的函数做成回调, 下面的g.read_f, 这样用哪些GPIO读取可以任意搭配, 方便连线.
判断正转或反转的操作也做成回调, 下面的g.action_f.
old_state数组是各个编码器的旧状态.

只要读得过来, 想读几个都行.

    for(int i = 0; i < ZRE_NUM; i++) {
      unsigned char state = ((g.old_state << 2) | g.read_f(i)) & 0xf;            // 只需要4bit
      switch(state) {
            case 0x1:
            case 0x7:
            case 0xe:
            case 0x8:
                g.action_f(i, ZRE_CW);             // 顺时针
                break;
            case 0x2:
            case 0xb:
            case 0xd:
            case 0x4:
                g.action_f(i, ZRE_CCW);         // 逆时针
                break;
      }
      g.old_state = state;               // 保存状态供下次使用
    }

老徐 发表于 2023-9-16 00:39:49

如果真的不认同分时复用的方案,可以将一半通道采用频压转换,一半10个采用AD引脚采集,一半10个接10个定时器
页: [1]
查看完整版本: 求:单片机采集20路编码器的思路