找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

利用PWM信号驱动DC马达并精确控制马达位置

[复制链接]
admin 发表于 2012-9-2 06:23:46 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
把自己做的DC马达驱动电路拿出分享下

  利用PWM信号驱动马达,通过调整PWM信号高低电平a和b的时间比来调节速度
  当a>b时,马达正转,当a<b时,反转,a=b时正停止,
  (由于不知道怎么在文件中直接插入图形编辑,发在附件图片中说明)
  由于马达的底端以及转子的周围有传感器感应,所以要求精确定位
  复位时要求马达停在离底端0.3mm的地方,而升出时要求不触及顶端,
  通过计数FG信号脉冲数来确定,经过2天的不断思考和调试,终于可以精确复位了
  有时间把示波器上的调试过程发出来.
  此次只有伸出(TELE)和缩回(WIDE)2个动作,如果要求开关控制的话,
  自己可以加开关控制伸出一半,加速等,
  马达驱动是用的驱动IC,原来想用MOS管搭H桥驱动的,后来发现驱动精度不好控制.
  如果要单纯控制马达驱动,则用来确认马达位置的信号就不用了
  这样程序就简单多了,
  第一次发,也不知道说清楚没,大家原谅啊

下面是程序
    include 16f84.h ;
.osc hs   ;
.wdt off    ;

;__CONFIG _HS_OSC & _PWRTE_ON & _CP_OFF & _WDT_OFF ;
       org  0ch
tim0 ds   1 ;
tim1 ds   1 ;
tim2 ds  1 ;
timx0 ds   1 ;
timx1 ds   1 ;
timx2 ds   1 ;
timy0 ds   1 ;
timy1 ds  1 ;
timy2 ds   1 ;
width ds   1 ;
width0 ds   1 ;
width1 ds   1 ;
counta0 ds   1 ;
counta1 ds   1 ;
countb0 ds   1 ;
countb1 ds   1 ;

        org 0
        goto start ;程序起始地址

org 4H ;中断程序地址
clrb intcon.2 ;toif 复位中断标志位
goto intproc ;去执行中断

start
clrb intcon.7 ;gie 关中断允许
    clr ra ;
        clr rb ;
       mov !ra,#00000b        ;RA全部输出
    mov !rb,#01111111b       ;RA.7输出,其他输入
setb rb.7 ;置高电平
setb status.5 ;bank1 以设置TMR0
movlw 81H ;10000011 分频比1︰4
mov option,w ;
clrb status.5 ;bank0
sw jb rb.4,left1 ;
jb rb.5,right1 ;
goto sw ;
left1
jb rb.1,left ;
goto sw ;
right1
jb rb.1,sw ;
goto right ;
left
movlw 04BH ;定时时间初值
mov tmr0,w ;
clr counta0 ;
clr counta1 ;
clr countb0 ;
clr countb1 ;
setb intcon.5 ;toie 开TMR0定时中断
setb intcon.7 ;gie 开全局中断
setb ra.1 ;马达控制位
setb ra.0 ;
goto iddp1 ;
right movlw 04BH ;
mov tmr0,w ;
setb intcon.5 ;toie
setb intcon.7 ;gie
setb ra.1 ;
clrb ra.0 ;
goto iddp2 ;

iddp1 nop ;循环等待中断
jb rb.2,cn0 ;FG信号
goto iddp1 ;
cn0 inc counta0 ;FG信号计数755后停止
cje counta0,#255,c1 ;
goto cn01 ;
c1 inc counta1 ;
clr counta0 ;
cje counta1,#3,stop ;
goto cn01
cn01 nop
jb rb.3,cn1 ;
goto cn01 ;
cn1 inc countb0 ;
cje countb0,#255,c2 ;
goto cn11 ;
c2 inc countb1 ;
clr countb0 ;
cje countb0,#3,stop ;计数FG信号到达目标值后停止移动,                           ;以免触及顶端
goto cn11 ;
cn11 nop
jnb rb.2,iddp1 ;
goto cn11 ;


iddp2 nop ;循环等待中断
jb rb.1,reset       ;RESET信号
goto iddp2 ;
reset ;开始复位
clrb intcon.5 ;
clrb intcon.7 ;
call wait1 ;重要!等待马达稳定后再判断(重力,                           ;f等惯性影响)
jnb rb.0,ccc ;FG0
jnb rb.1,bbb ;FG1
goto finish ;复位完成

judge
call wait1 ; 重要!等待马达稳定后再判断(重力,                           ;f等惯性影响)
jnb rb.0,aaa ;
jnb rb.1,bbb ;
goto finish ;
aaa ;250个脉冲一组,共5组
clr width0 ;伸出方向移动
clr width1 ;
mov width0,250 ;
mov width1,#5 ;
loop1 call wait1 ;
dec width1 ;
jb rb.0,judge       ;防止在上一个250个脉冲里没复位,下                           ;一个复位成功,则立即停止,如果去                           ;掉这条指令,比如在第3个250
                           ;脉冲组时没有复位ok,第4个后o                           ;k了,则它会继续运行第5个,就过                           ;了,所以加上后缩短复位时间
loop2 dec width0 ;
call tele ;
cje width0,#0,loop1 ;
cje width1,#0,judge ;
goto loop2 ;
bbb
clr width0 ;缩回方向移动
clr width1 ;
mov width0,250 ;
mov width1,#5 ;
loop3 call wait1 ;
dec width1 ;
jb rb.1,judge ;
loop4 dec width0 ;
call wide ;
cje width0,#0,loop3 ;
cje width1,#0,judge ;
goto loop4 ;
ccc ;由于一开始下去速度快,肯定到达底                            ;部,所以先快速的往伸出方向移动一                           ;点,然后再慢点复位,以减短复位时                           ;间
clr width0 ;
clr width1 ;
mov width0,200 ;
mov width1,#5 ;
loop5 dec width1
loop6 dec width0 ;
call tele1 ;区别于tele,快速伸出来一点点,                           ;利用wait4
cje width0,#0,loop5 ;
cje width1,#0,judge ;
goto loop6 ;
tele ;tele方向移动一个脉冲(慢速)
setb ra.1 ;
setb ra.0 ;
call wait2 ;
clrb ra.0 ;
nop
nop
nop
nop
nop
clr ra ;
ret
tele1 ;tele方向移动一个脉冲(快速)
setb ra.1 ;
setb ra.0 ;
call wait4 ;
clrb ra.0 ;
nop
nop
nop
nop
nop
clr ra ;
ret
wide ;wide方向移动一个脉冲(慢速)
setb ra.1 ;
clrb ra.0 ;
call wait3 ;
setb ra.0 ;
nop
nop
nop
nop
nop
clr ra ;
ret
finish
jb rb.4,left ;复位成功
goto finish ;
stop
clrb intcon.5 ;
clrb intcon.7 ;
setb ra.1 ;
setb ra.0 ;
nop
nop
nop
nop
call wait2 ;
clrb ra.0 ;
call wait2 ;
jb rb.5,right ;
goto stop ;
intproc ;中断程序
movlw 04BH ;重新装入初值
mov tmr0,w ;
call rc ;pwm信号高低电平时间比设置以调节马达速度
movlw 01H ;取反ra.0
xor ra,w ;
call wait ;
movlw 01H ; 取反ra.0
xor ra,w ;
retfie ;


rc ;利用电容充放电时间来设定width值
clr width ;
clrb rb.7 ;电容开始放电
lp11 sb rb.6 ;电容放电完了吗?
goto lp12 ;放电完了则跳,取得时间常数width
nop ;
incsz width ;
goto lp11 ;
movlw 0FFH ;
mov width,w ;
lp12 setb rb.7 ;电容充电
return ;




wait
mov tim0,#1 ;如果使用VR10K的电阻,则1变为8,
wa0 mov tim1,width ;
wa1 nop
nop
djnz tim1,wa1
djnz tim0,wa0
ret
wait1
mov tim2,#50
wa2 mov timx1,#250
wa3 djnz timx1,wa3
djnz tim2,wa2
ret

wait2
mov timx0,#13
wax1 djnz timx0,wax1
ret
wait3
mov timy0,#13
way0 djnz timy0,way0
ret
wait4
mov timx2,#23
wax3 djnz timx2,wax3
ret


马达驱动.dcd.pdf (16.95 KB, 下载次数: 0)
5_39472_24135745e976592.jpg
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-11-24 03:44 , Processed in 0.057830 second(s), 14 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表