1.最终效果 一个函数,我调用它直接能达到我要的目的 例: 基本功能 1.设置舵机速度和加速度 输入:速度和加速度 2.让舵机转到指定位置 输入:指定位置 函数中需要实现2:外部输入一个目标 写入寄存器 1.控制单个舵机方法 输入哪个舵机,干什么 2.控制多个舵机方法 输入哪几个舵机 (单次写入的数据只有1字节或2字节) 1.在指令(无论读写)发送时需要输入数据长度, 所有在运行指令命令时需要判断数据长度 而在飞特舵机寄存器里只有1个字节和2个字节的情况 所以就对写入寄存器进行判断,即可判断要写入字节长度 问题1. 但是如果只是简单的判断,由于舵机寄存器地址不连贯,中间有空缺,就导致在判断时变得繁琐 所以,先利用数组表格将寄存器变得连贯,连贯之后进行判断就变得轻松 问题1.(补充) 将寄存器变得连贯后 我在输入时就不能只输入寄存器的实际地址,寄存器的地址已经映射到数组表格里了,我在使用寄存器时得运用映射地址而不是实际地址 问题2 同步指令在参数段需要写入多段数据\ // 在往上抽象一层 -----> 输入想要干的事 ---> 就执行相应功能 // 需要输入 1.想干什么 2.想干事的值 3.让哪个目标干这个活 // 寄存器:解决 // 参数数据:解决 // 参数数据长度:解决 // 指令: // // 写指令有3种情况, 同步(一次性写入),异步(分步单次写入),单纯写(只写一次) // 同步和单纯写是只写一次 9.20 上面全部省略 新的思路 一.控制舵机 1、控制单个舵机 输入: 舵机对象 (舵机对象里包含了 舵机id 舵机寄存器 传入的数据 命令 通过传入舵机对象即可完成对舵机的修改) 实现功能(传入寄存器地址) 数据(写入的东西) 写操作 核心在于指令包的发送 写操作有3个指令 同步写 异步写 单纯写 而同步写可以一次写入多个数据 以此区分指令类型 我分为同步和非同步 (1)、非同步 (传输的数据是1字节或2字节) (1).如何判断传入的数据是1字节还是2字节? 根据寄存器判断传入的数据是1个字节还是2个字节 在飞特的舵机内存表中,只需要知道哪个寄存器就能知道传入几个字节。 所以可以通过传入的实现功能参数来判断传入字节长度 判断字节长度 通过遍历的方式得到字节长 问题1:舵机内存表寄存器地址不连续 导致遍历过程变得繁琐 解决:让寄存器的地址变得连续即可 对原寄存器的地址进行映射 列出一张映射表,该映射表的连续的,且与实际地址一一对应 通过映射表来历遍所有寄存器,这就把原有的地址分离了,在我们进行操作的时候,都使用这张映射表 在想舵机发送数据的时候,在把映射表对应的地址分配即可; 问题2:内存表中有一些寄存器,需要传入负值 对于计算机来说:正负的区分在于最高位的0或1,重二进制层面来说没有负数的概念, 1000和-1000 用二进制存储在计算机中是不同的值,所有只需要判断哪些寄存器需要负值就行了 飞特舵机内存表寄存器中,只有一些2个字节的寄存器需要负值,所以只需要对2个字节的数据就行判断 补充:飞特舵机有几个特殊的寄存器需要特殊处理 运行时间 bit11为和 位置校准 bit10位 来区分正负 9.21 问题3 发送和接收指令包的处理 发送包缺乏校验和数据可能是导致现在驱动不了舵机的原因 接收指令包利用DMA接收,涉及到一个dma中断的处理, 网上的大部分是利用串口空闲中断处理,这样DMA中断在接收数据处理方面就没多大作用; 所以采用DMA的半中断的方式(不采用全中断是害怕溢出),控制DMA接收缓存区的大小来达到接收完从机应答包后就产生DMA中断 问题4 由于同步和非同步的不确定导致指令包参数数据长度不定,而原先的方法是只能用与参数长度为1个字节或者2个字节, 所以需要改变我原先的方法,让参数定长改为参数可变。 对于我原来的方法, 在判断寄存器传入字节长度的时候判断了一次寄存器, 在判断特殊寄存器的位控制时有又判断了一次寄存器 9.23 发先所有的操作都有统一的基础形式,所以对数据包进行统一 2、控制多个舵机