求:单片机采集20路编码器的思路
测量20路电机转速,利用机器现有的编码器进行编码器输出脉冲频率最大400hz 最低60hz
一共是20路 需要实时采集频率送给上位机进行处理
中断/STM32单片机也就16路 是一个问题
坛友 有没有其他好的思路望赐教 好的建议lz请吃汤圆{:tongue:} {:loveliness:} 用两片单片机 是总共20路编码器的AB信号还是 20个编码器? 第一种情况 简单,相当于只用采集10路信号就行,方向信号用硬件+普通IO口判断。 第二中情况。能不能这样做。 比如 1-16 路接在PA0-PA15上,17-20 接在PB12-PB15上。然后在中断里面判断具体引脚。 这个我没试验过,也不知道。 采用外部计数器芯片吧 CD4051单端8通道多路开关,
C、B、A 用来选择通道号输出到单片机中断io口
分时进行中断采集
如: 50ms给每一路采集时间
多次采集进行滤波处理之后 即可
这是其他项目采用方案用起来效果还可以不占用太多中断资源 普通STC单片机也可以胜任 編碼器端加小板子把數據轉 485 再傳送到 MCU 你这个频率比较低,STM32 所有有IO都能当外部中断输入。用一个定时器做一个 比如10uS的时基。然后再定义20个变量。两次外部中断上升沿(或者下降沿)之间 让对应的变量计数。根据计数值就能算出频率。时基越小精度越高。20路 400Hz 我估计没问题。以前 我用这种方式 在C8051上 做过PWM输出(相当于IO口模拟PWM)。2路频率2K都没问题。 BOERLBH 发表于 2021-9-27 20:48
你这个频率比较低,STM32 所有有IO都能当外部中断输入。用一个定时器做一个 比如10uS的时基。然后再定义20 ...
你这太费劲了。最简单最便宜的,stc8调到4khz中断,然后去读io,之后用软件去解码。仅仅是计算个频率而已,最大400hz,中断读数据,正常状态处理数据,轻轻松松而已。 谢谢各位参与汤圆请笑纳{:handshake:}{:hug:}{:hug:} 0.5ms的定时中断扫描IO足矣
如果用CD4051单端8通道多路开关,50ms转换一次端口20个刚好是1s
然后,根据一个io口-----50ms采集到的脉冲数量*50 就是时间1s单路的脉冲总数
分时复用
这样方案大家看看如何 lb0857 发表于 2021-9-27 23:01
如果用CD4051单端8通道多路开关,50ms转换一次端口20个刚好是1s
然后,根据一个io口-----50ms采集到的脉 ...
(引用自11楼)
最后采用什么方案了? 参考之前看到的一个旋转编码器的驱动, 挺有意思
用两个普通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; // 保存状态供下次使用
} 如果真的不认同分时复用的方案,可以将一半通道采用频压转换,一半10个采用AD引脚采集,一半10个接10个定时器
页:
[1]