[原创] 基于CAN控制电机转速——只用两个按键就可以实现电机的正反转

fxw451   2010-12-16 20:40 楼主

经过一段时间的学习,终于把CAN基本的东西给搞定,还有许多东西还要去学,在此先发一部分这段时间的学习内容,希望高手拍砖,让讨论抵御这大冷的冬天!!

在刚开始申请板子的时候是想采用232通信来完成电机的控制,但是拿到板子后发现该板子有好多资源,比如CAN,以太网啊,这些好东西。

本程序主要是参照TI公司的CAN例程,在里面修改;从这段时间的学习,我发现CAN功能很强,要比232要好,并且也方便,可以更好的利用好两个板子,所以就考虑用CAN来做电机控制。以前也没做过CAN方面的东西,所以这次很重视CAN的学习,论坛上也有好多高手写CAN方面的资料,下面还是有写罗嗦,望大家见谅。

不过这次例程是在前面的例程的基础上(通过按键实现直流电机的正反转和加减速!https://bbs.eeworld.com.cn/viewthread.php?tid=219790&highlight=%2Bfxw451)做了修改,直接用两个按键实现了电机的正反转,并且还考虑到在正反切换时很容易烧毁电机,在此做了一些改进,大家看看程序就明白了,很简单的。

控制直流电机转动的两个引脚为PWM0PWM2,按键为Device板的UPDOWN键。

下面主要介绍下CAN模块的实现:多罗嗦几句,也是必须罗嗦的部分。

应用流程:

 

aa.jpg

 

 

一、对CAN的接受和发送设置理解
首先来谈一下对 历程中的CAN报文结构的理解
以下是我对一个报文结构的理解不知道对不对,初次接触CAN有错误的地方还望大家指点 一下
typedef struct
 {
 /*(1)*/    unsigned long ulMsgID;      //  11或29位的CAN报文标识符 用于总线仲裁

/*(2)*/    unsigned long ulMsgIDMask;    //  报文滤波器使能后的标识符掩码 用于多个.节点的杂通信 若个不使能报文滤波的话 这块可以不用管

 /*(3)*/    unsigned long ulFlags;         //  由tCANObjFlags列举的配置参数    此值保存多个 状态标志和 tCANObjFlags 所指定的设置 例如使能CAN接受中断以及报文滤波
可设 ulFlags=MSG_OBJ_RX_INT_ENABLE|MSG_OBJ_USE_ID_FILTER
      多个状态设置或上就行

/*(4)*/  unsigned long ulMsgLen;       //  报文数据域长度 指定报文数据场中数据的个.    数 最大8位 若是设置一个接受的报文对象缓冲区 这表示期望的数据宽度

 /*(5)*/   unsigned char *pucMsgData;   //  指向配置报文对象数据域数据的指针 即数据场中的数据地址
}tCANMsgObject;
 
对于CAN的启动
1.。在使用CAN前 先启动CAN 即置位INIT位 使用 CANInit(CAN0_BASE);
2.启动后设置位速CANBitRateSet(CAN0_BASE, 8000000, CAN_BITRATE);
3 使能CAN中断

4 为了接收一个特定的数据帧,要执行下列步骤:
(1)  把tMsgObjType 设置为MSG_OBJ_TYPE_RX。
(2)  把ulMsgID设为完整报文 ID,或使用部分 ID匹配的部分屏蔽。
(3)  设置ulMsgIDMask 位,用于在对比过程中的屏蔽。
(4)  按如下设置 ulFlags:
 ♦  设置 MSG_OBJ_TX_INT_ENABLE 标志,以便在接收数据帧时被中断;
 ♦  设置 MSG_OBJ_USE_ID_FILTER 标志,以便使能基于过滤的标识符。
ulFlags=MSG_OBJ_TX_INT_ENABLE|MSG_OBJ_USE_ID_FILTER
(5)  把ulMsgLen 设置为期望数据帧的字节数。
(6)  此次调用并不使用 pucMsgData 所指向的缓冲区。
(6 ) 调用CANMessageSet(unsigned long ulBase,
unsigned long ulObjID,
tCANMsgObject *pMsgObject,
tMsgObjType eMsgType) ,并把 ulObjID设置为 32 个对象缓冲区中的其中一个缓冲区。
如果您指定的报文对象缓冲区已包含有一个报文标识符,那么它将会被覆写。

5为了直接把一个数据帧或远程帧发送出去,要执行下列步骤:
(1)  把tMsgObjType 设置为MSG_OBJ_TYPE_TX。
(2) 把ulMsgID设为报文 ID。
(3)  设置ulFlags,设置 MSG_OBJ_TX_INT_ENABLE,以便在发送报文时获取一个中断。
为了禁止基于报文标识符的过滤,一定不要设置 MSG_OBJ_USE_ID_FILTER。
(4)  把ulMsgLen 设置为数据帧的字节数。
(5)  把pucMsgData 设置为指向一个包含报文字节的数组(如果是一个数据帧,不适用此
操作;如果是一个远程帧,把这设置为指向一个有效缓冲区则是一个好方法)。
(6)  调用CANMessageSet(unsigned long ulBase,
unsigned long ulObjID,
tCANMsgObject *pMsgObject,
tMsgObjType eMsgType) ,并把 ulObjID设置为 32 个对象缓冲区中的其中一个缓冲区。

 

回复评论 (19)

回复 楼主 fxw451 的帖子

加油!在电子行业默默贡献自己的力量!:)
点赞  2010-12-17 08:30

二、通过系统时钟中断扫描键盘

 

在用can来控制开发版的PWM波时用到了按键在这里没有用GPIO中断来做用的是系统时中断。感觉历程中给的扫描程序写的相当的好 在这里我分享一下对断程序的理解

以前写键盘扫描程序的往往分两步1、用一个延时程序来 消斗 2、有一个while(1)来等待按键抬起。与历程给的相比这样做的话效率不高

 

 历程中的程序用ulLastStatus g_ulDebounceCounter 共同消斗 只有当ulDebounceCounter 等于4的时候才为可靠按下 如果出先按键状态和前一次不一样则清零ulDebounceCounter

 

用以下的两个if()语句判断按键 是刚被按下 还是以前起就一直被按下 g_ucButtonStatus为前一次扫描的按键状态  ulStatus 为本次扫描的按键状态

ucTemp = g_ucButtonStatus ^ ulStatus; 如果前一次状态为按下异或后ucTemp 对应位为0

if(ucTemp & GPIO_PIN_0)  判断 ucTemp 对应位的值

if(GPIO_PIN_0 & ulStatus)  判断按键是否是被按下

 

三、CAN中断的处理

1、进入CAN中断响应后用CANIntStatus(unsigned long ulBase, tCANIntStsReg eIntStsReg) 来读取CAN控制器当前中断状态 如果是一个报文中断则返回的是中中断报文的编号(132)利用返回的编号可以判断是接受数据中断 还是发送中断。

2、如果一个接收到的报文情况下使用CANMessageGet()读取报文 并清除报文对象中断。

3、如果是一个发送中断则用CANIntClear()来清除中断

4、如果两者都不是则使用 CANStatusGet()函数读取状态寄存器并清除状态中断

值得注意的事 对于中断的清除应在 处理程序的最后  以避免在真正清除中断源之前从中断处理程序中返回。 如果操作失败可会能导致立即再次进入中断处理程序。 (因为NVIC仍会把中断源看作是有效的)。

 

                             有错误之处还请高手指教,欢迎高手拍砖!!

——fxw451   

  

2010.12.17    

 

笔记内容:

基于CAN控制电机.pdf (104.66 KB)
(下载次数: 164, 2010-12-17 09:25 上传)
           程序部分:
can driver motor.rar (640.34 KB)
(下载次数: 148, 2010-12-17 09:25 上传)

 

 

CAN驱动资料:

群星系列CAN接口应用.pdf (802.74 KB)
(下载次数: 134, 2010-12-17 09:25 上传)
              
基于LM3S2000系列CAN控制器的驱动库应用笔记_周立功_lm3s2110_multican.pdf (449.41 KB)
(下载次数: 133, 2010-12-17 09:25 上传)

点赞  2010-12-17 09:25

题目应该是实现电机正反转和加减速!!

昨晚整理的不够仔细,补上,下次注意!!

点赞  2010-12-17 09:32
很不错,顶了~!嘿嘿~!
我爱电子!
点赞  2010-12-18 17:27

回复 5楼 jjkwz 的帖子

谢谢支持,这方面还是不能够吸引大家的眼球!!以后写点大家感兴趣的,现在时间还是比较紧,学期末了,事情多。以后有机会要和大家多多分享!!
点赞  2010-12-18 20:01
写的比较详细,支持楼主,历程里有好多改进,值得我们这些初学者学习,谢谢!!
追求卓越,成功就会在不经意间追上你
点赞  2010-12-21 22:00

回复 6楼 fxw451 的帖子

希望楼主在用PWM控制直流电机的问题上再详细一点点。
点赞  2010-12-23 08:56

回复 8楼 academic 的帖子

      控制直流电机转动的两个引脚为PWM0和PWM2,直流电机其实只有两个引线接可以了,在这里我用的是PWM0和PWM2。具体怎么实现他们的正反转和加减速的就是把一个引脚置低,另一个引脚设置占空比,就可以调速了,比如:我先把PWM0置0,调PWM2来实现电机的正转,通过调节PWM2的占空比来现在转速的调节,相反,我就可以实现电机的反转和加减速。

      这个基于CAN的电机控制只是用到了两个按键,转速的调节和正反转是通过按键来实现的,如何实现的??其实很简单,我就是通过按键来显示一个数组的加减进而控制电机的正反转,有两个数组分别给PWM0和PWM2,

P0[]=[0.99,0.80,0.7,0.6,0.5,0.4,0.3,0.2,0.1,0,0,0,0,0,0,0,0,0,0,0],

P2[]=[0,0,0,0,0,0,0,0,0,0,0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.99]

21个数就可以实现了,比如我按下UP键,读取的是P0[0]和P2[0],分别给PWM0和PWM2,在按下UP键就是P0[1]和P2[1],以此类推,DOWN键其实就是减了,在这里我设置了P0[10]和P2[10]均为0,为了是怕电机在突然现在正反转的瞬间PWM0和PWM2都有电压,怕烧坏电机,加了个算是缓冲吧!!

 

        非常感谢你提出了这么一个比较好的问题,在文档中没能说清楚,还请见谅!!

[ 本帖最后由 fxw451 于 2010-12-23 10:46 编辑 ]
点赞  2010-12-23 10:45

回复 8楼 academic 的帖子

你可以通过这个《通过按键实现直流电机的正反转和加减速》 https://bbs.eeworld.com.cn/viewth ... highlight=%2Bfxw451
这个使用三个键来实现电机的正反转和加减速的

这两个是完全不同的电机控制,你可以比较了。

可能是我写作上面功夫不是很好,没能把最吸引人的地方写出来。下次注意多跟大家学习下!!
点赞  2010-12-23 10:51
谢谢楼主分享资料!!!!!!
点赞  2010-12-24 11:23

不错,顶起

http://shop34182318.taobao.com/ https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
点赞  2010-12-25 19:58

回复 12楼 ddllxxrr 的帖子

还请版主提出几个修改的意见!!
点赞  2010-12-26 20:01
记得以前在proteus里看到了一个PWM控制直流电机的例子,采用的是达林顿桥来驱动电机,比较地简单,供大家参考一下。
1.jpg
点赞  2010-12-27 08:43

回复 14楼 academic 的帖子

恩,不错,我刚开始是用了几个三极管编织成H桥,要是遇到大电压电流的恐怕要用达林顿桥,这个很强大!!
点赞  2010-12-27 10:05
楼主用的是LM3S8962的板子 带的CAN小板子吗?

通过排线连接CAN小板和主板 然后将程序烧写进CAN小板的吗?等过一段有时间也好好研究一下LZ的帖子 自己也做做练练手!~
QQ:1625345502
点赞  2010-12-27 10:20

回复 16楼 wanghongyang 的帖子

恩是的。这个有个硬件配置,你只要选择lm3s2110就可以烧到小板子上了,烧大板子的时候需要把连接小板的大排线拔掉。才能烧到大板上。
点赞  2010-12-27 11:18
谢谢楼主,非常感谢
点赞  2011-6-26 11:18
楼主,能不能在CAN里实现定时正反转那
点赞  2011-11-1 10:21
很好,学习了
点赞  2011-11-1 11:08
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复