AVR单片机汇编语言机器人控制样例
SL-DIY02-9伺服电机(舵机)机器人专用控制板的应用
摘要:双龙电子为高中《简易机器人制作》课程开设,提供AVR单片机汇编语言机器人控制样例。采用双龙
电子SL-DIY02-9伺服电机(舵机)机器人专用控制板,利用双轴输出伺服电机(舵机)组成各种创意机器人,伺
服电机既是机器人的驱体,又是机器人的活动关节部件,采用AVR单片机ATmega16作为机器人核心控制部件。用AVR汇编语言编写机器人程序, 程序启停采用中断触发方式,可以同时控制4只伺服电机机器人动作,伺服电机运动速度、动作幅度可修改,也可方便扩展到8只伺服电机机器人动作。本程序采用模块式结构,流程图说明,并有详细中文注释,程序在实验中调试通过,本程序可作为机器人创新开发参考。
一、SL-DIY02-9伺服电机(舵机)机器人专用控制板简介
双龙电子的SL-DIY系列积木式单片机开发实验模块板,是单片机教学实验、机器人开发制作、参加各种创新大赛及参加各种机器赛的通用开发实验模板,做到一机多用。SL-DIY系列积木式单片机开发实验模块板,只需一条ISP下载电缆线就可开发所有的AVR单片机。从而为用户节省了购买仿真器、编程器、芯片适配器的大量费用。功能板可以是空芯片,相当于提供一张白纸,可以让你写最好的文章,画最好最美的图画。当然该功能板还提供各种程序例子,有汇编级及高级语言源程序,供使用者学习参考、修改补充,使该功能板符合自己项目工程的需要。另外双龙电子也提供含有监控程序的芯片(含相应操作系统软件),使你可锦上添花,提高你的项目开发水平,加快项目的开发进程,让你早出成果,快出成果。
为了让SL-DIY系列积木式单片机开发实验模块板使用者更好地参加各种创新大赛及机器赛,尽量减小功能板体积及减轻功能板重量,双龙电子特别推出SL-DIY02-9伺服电机(舵机)机器人专用开发板(简称开发板),电原理框图如图1。
图1 电原理框图
SL-DIY02-9开发板体积小(77x53mm),重量轻,是伺服电机机器人专用控制板,可用于有手有脚机
器人、仿生机器人、虚拟机器人、网络机器人等的控制。单片机I/O口也可直接当输入/输出用,适用于AVR单片机机器人制作控制及青少年科技创新活动使用。
SL-DIY02-9开发板,最多可提供32只伺服电机(舵机)接口,可直接接插伺服电机。也可提供8路10位A/D转换接口(PA口);声控启动程序功能,符合世界机器人比赛要求(即机器人进入赛场后不准触摸机器人,必须声控启动);用户程序ISP在线下载编程功能;RS232通讯接口,是供图形软件、流程图软件、工控组态软件通讯、调试、下载程序使用;本机采用大容量高性能ATmega16 AVR单片机,具有JTAG仿真接口,利用JTAG仿真器可以进行在线实时仿真,提高工程项目开发效率。本功能板采用双列直插式DIP器件,便于使用者任意更改功能板的用途或器件的程序内容,在某些比赛场合下尤为重要。
双龙电子也可提供图形软件监控及系统工作软件,只要你会操作电脑,你就会开发设计制作控制调机器人。双龙电子提供的图形软件、流程图软件,最多可输入几百条语句。SL-DIY02-9开发板,双龙电子也可提供组态监控及系统工作软件,可以学习工控组态方法,可以设计开发虚拟机器人与网络机器人。图2为SL-DIY02-9开发板器件位置图,图3为实物图。
图2 器件位置图 图3 实物图 SL-DIY02-9模块板使用说明:
U1(14)出厂时选用ATmega16单片机, ATmega16与ATmega8535/AT90S8535兼容;JPA,JPB,JPC,JPD(15,7,12,10)均可直接插伺服电机(靠芯片一侧为伺服电机信号I/O端口,中间为VCC,外侧为GND),AVR单片机4个I/O口,每组为8个端口(PX0-PX7),为工作方便,请注意:把PD口(PD0-PD7)排在一起了。但JPD0,JPD1端口作串行通讯接口,在通讯连机时不能插伺服电机,通讯下载结束后可插伺服电机;JPD2,JPD3端口也可用作外部中断触发用,当中断触发用时不能插伺服电
机;JPD4可作为声控输入端口,如作声控用时,JMIC(9)插上短路块,不能插伺服电机,如该端口用作伺服电机, JMIC插座上拔出短路块。图4为U1电原理图。
图4 U1电原理图
CZ1(1)为通讯插座,本机配有专用通讯电缆,一头接插CZ1(电话机插头座),另一头接插PC机RS232接口;本通讯接口作为图形软件连机调试用,也是流程图软件、组态工控、虚拟机器人、网络机器人联机通讯工作使用,RS232电原理图见图5。
CZ2(4)为5V电源接线端子,红线为正5伏(VCC标+),黑线为地(GND标-)。本功能板具有防止电源电压线接错及防止误接高电压保护电路TVS器件,当发生以上情况时,仅损坏TVS器件,从而保护单片机。如已损坏TVS器件,一时买不到该器件,可在TVS左侧F处焊上短接线临时解决电源供电,所以千万注意电源线不能接错或错接高电压。
J2为电源开关(新板),ON为接通电源,在OFF为断开电源。
图5 RS232电原理图
CZ3(6)为ISP在线下载插座,本机配有专用ISP下载线,注意下载插座有定位方向,电原理图见图6。 MIC(11)为咪头(话筒),作为声控信号源,也可设计为能听乐曲的跳舞机器人, 电原理图见图7。
图6 ISP电原理图 图7 声控电原理图 RESET(8)为手动复位按键,电原理图见图8。
JAD0(2)短路块插座,当PA0端口作A/D转换时,插上短路块(即PA0接通W1微调电位器,作为外部输入电压测试用), 电原理图见图9。当然JAD1也应拔出短路块(即除去PA口上拉电阻);
JAD1(16)短路块插座,当PA口作A/D转换时, JAD1上的短路块应该拔出;如PA口作伺服电机使用时, JAD1应该插上短路块,即加入上拉电阻。
W1(13)作为A/D转换时,作外部模拟电压输入测试用, 见图9,插上JAD0短路块时,PA0端口即输入模拟电压,可用螺丝刀改变W1的电压值。当要对其它端口测试A/D功能时, 拔出JAD0短路块,可用短接线一头插在JAD0短路插座下端(1),另一头插到PA口的某测试I/O端口插针即可。
图8 复位电路 、模拟电压电路 、 电源指示 LED(5)发光二极管作电源指示用, 电原理图见图10
SL-DIY02-9开发实验器采用8MHZ晶振,也可改为16MHZ晶振,但延时参数必须修正。
SL-DIY02-9开发实验器与SL-JB小键盘连接,可组成互动式虚拟机器人或网络机器人控制用。小键盘接口J7与ATmega16的PC口可用接插线连接工作。虚拟机器人设计可参阅双龙的工控组态开发有关资料。
二、微型伺服电机原理与控制(中鸣) 1、微型伺服电机内部结构
一个微型伺服电机内部包括了一个小型直流电机;一组变速齿轮组;一个反馈可调电位器;及一块电子控制板,如图9。其中,高速转动的直流电机提供了原始动力,带动变速(减速)齿轮组,使之产生高扭力的输出,齿轮组的变速比愈大,伺服电机的输出扭力也愈大,也就是说越能承受更大的重量,但转动的速度也愈低。
图9 微型电机内部结构图
2、微行伺服电机的工作原理
一个微型伺服电机是一个典型闭环反馈系统,其原理可由图10表示如下:
图10 闭环反馈系统原理图
减速齿轮组由电机驱动,其终端(输出端)带动一个线性的比例电位器作位置检测,该电位器把转角坐标转换为一比例电压反馈给控制线路板,控制线路板将其与输入的控制脉冲信号比较,产生纠正脉冲,并驱动电机正向或反向地转动,使齿轮组的输出位置与期望值相符,令纠正脉冲趋于为0,从而达到使伺服电机精确定位的目的。 3、如何控制伺服电机
标准的微型伺服电机有三条控制线,分别为:电源、地及控制信号线。电源线与地线用于提供内部的直流电机及控制线路所需的能源,电压通常介于4V—6V之间,该电源应尽可能与处理系统的电源隔离(因为伺服电机会产生噪音)。甚至小伺服电机在重负载时也会拉低放大器的电压,所以整个系统的电源供应的比例必须合理。
输入一个周期性的正向脉冲信号,这个周期性脉冲信号的高电平时间通常在1ms—2ms之间,而低电平时间应在5ms到20ms之间,并不很严格,表1表示出一个典型的20ms周期性脉冲的正脉冲宽度与微型伺服电机的输出臂位置的关系:在参照上表设计控制脉冲宽度时应注意以下的注意事项。
表1 电机位置与控制脉冲对应表
4、伺服电机的电源引线
控制线
图11 伺服电机引线图
电源引线有三条,如图11中所示。伺服电机三条线中红色(如图最上边一根)的线是控制信号线,接到控制芯片上。中间的是SERVO工作电源线,一般工作电源是5V。 第三条是地线。 5、伺服电机的运动速度
伺服电机的瞬时运动速度是由其内部的直流电机和变速齿轮组的配合决定的,在恒定的电压驱动下,其数值唯一。但其平均运动速度可通过分段停顿的控制方式来改变,例如,我们可把动作幅度为90º的转动细分为128个停顿点,通过控制每个停顿点的时间长短来实现0º—90º变化的平均速度。对于多数伺服电机来说,速度的单位由“度数/秒”来决定。 6、使用伺服电机的注意事项
除非你使用的是数码式的伺服电机,否则以上的伺服电机输出臂位置只是一个不准确的大约数。
普通的模拟微型伺服电机不是一个精确的定位器件,即使是使用同一品牌型号的微型伺服电机产品,他们之间的差别也是非常大的,在同一脉冲驱动时,不同的伺服电机存在±10º的偏差也是正常的。
正因上述的原因,不推荐使用小于1ms及大于2ms的脉冲作为驱动信号,实际上,伺服电机的最初设计表也只是在±45º的范围。而且,超出此范围时,脉冲宽度转动角度之间的线性关系也会变差。
要特别注意,绝不可加载让伺服电机输出位置超过±90º的脉冲信号,否则会损坏伺服电机的输出限位机构或齿轮组等机械部件。
由于伺服电机的输出位置角度与控制信号脉冲宽度没有明显统一的标准,而且其行程的总量对于不同的厂家来说也有很大差别,所以控制软件必须具备有依据不同伺服电机进行单独设置的功 能。
图12舵机控制原理图
三、SL-DIY02-9伺服电机(舵机)机器人专用控制板汇编语言的编程
我们采用SL-DIY02-9伺服电机机器人专用控制板,手动触发(用专用接插线使PD2接一下地)启动,控制四个伺服电机工作。选用AVR单片机ATmega16的PB端口作为伺服电机驱动端口, 手动触发为INT0中断来实现伺服电机的启、停控制。
设定:PB0(0号伺服电机), PB1(1号伺服电机), PB2(2号伺服电机), PB3(4号伺服电机),当然可以扩展到8个伺服电机。有关ATmega16单片机的基础知识: 1.外部中断
图13、MCU控制寄存器
Bit 1, 0 – ISC01, ISC00: 中断0 触发方式控制Bit 1 与Bit 0
外部中断0 由引脚INT0 激发,如果SREG 寄存器的I 标志位和相应的中断屏蔽位置位的 话。触发方式如Table 35 所示。在检测边沿前MCU 首先采样INT0 引脚上的电平。如果 选择了边沿触发方式或电平变化触发方式,那么持续时间大于一个时钟周期的脉冲将触 发中断,过短的脉冲则不能保证触发中断。如果选择低电平触发方式,那么低电平必须保 持到当前指令执行完成。 中断0 触发方式控制
表2、中断触发方式
图14、GICR中断屏蔽寄存器 **口(B口)
每个端口引脚都具有三个寄存器位: DDxn、PORTxn 和PINxn,如P63“I/O 端口寄存器
的说明” 所示。DDxn 位于DDRx 寄存器, PORTxn 位于PORTx 寄存器, PINxn 位于 PINx 寄存器。如图15、16、17。
图15、PORTB寄存器
图16、DDRB寄存器
图16、PINB寄存器
DDxn 用来选择引脚的方向。DDxn 为\"1“ 时, Pxn 配置为输出,否则配置为输入。引脚配置为输入时,若PORTxn 为\"1“,上拉电阻将使能。如果需要关闭这个上拉电阻,可以将PORTxn 清零,或者将这个引脚配置为输出。复位时各引脚为高阻态,即使此时并没有时钟在运行。
当引脚配置为输出时,若PORTxn 为\"1“,引脚输出高电平(\"1“),否则输出低电平(“0“)。在( 高阻态) 三态({DDxn, PORTxn} = 0b00) 输出高电平({DDxn, PORTxn} = 0b11) 两种状态之间进行切换时,上拉电阻使能({DDxn, PORTxn} = 0b01) 或输出低电平({DDxn,PORTxn} = 0b10) 这两种模式必然会有一个发生。通常,上拉电阻使能是完全可以接受的,因为高阻环境不在意是强高电平输出还是上拉输出。如果使用情况不是这样子,可以通过置位SFIOR 寄存器的PUD 来禁止所有端口的上拉电阻。
在上拉输入和输出低电平之间切换也有同样的问题。用户必须选择高阻态({DDxn,PORTxn} = 0b00) 或输出高电平({DDxn, PORTxn} = 0b10) 作为中间步骤。表3 总结了引脚的控制信号。
表3、IO口引脚的控制信号
伺服电机控制主程序流程图如图17
N
程序初始化 N 键入标志=0xff Y 读入数据表格入RAM 定数据首地址及首电机号 N 键入标志=0xff Y 赋motor_comaddr初地址值 ` 调用RUN使电机开始动作 Y 读取电机控制数据 调用_change_data修改数据 电机号加1 是末电机吗? 清电机号为起始电机 程序跳转 图17 伺服电机控制主程序流程图
伺服电机控制程序清单:
;*********************************************** ; SL-DIY02-9 伺服电机(舵机)机器人专用控制板 ; 手动触发,控制四个电机程序。
; ATmega16L的PB端口作为可选驱动端口, ; 具体位地址由数据表格中之控制命令决定. ; 手动触发为INT0中断来实现;
;程序中带下划线的为标号,不带下划线的为寄存器变量 ;************************************************ ;* ATmega16L 8MHz ;* 双龙电子 .cn ;* .cn
;* sam 2004.08.14
;********* XX.cn **************
;******************************************** .include \"m16def.inc\" ;器件配置文件
.def time_h=r20 ;run的脉冲周期公式如下:
.def time_l=r21 ;((time_h-1)*256+time_l)*delay==20ms .def loc_now =r23 ;电机当前位置变量 .def loc_temp=r24 ;电机位置临时变量 .def motor_num=r25 ;电机号变量 .def loc_direct=r18 ;电机运动方向变量 .def loc_amp=r19 ;电机运动增幅变量
.def run_times=r17 ;电机当前运转步数变量 .def **um=r1 ;电机控制命令变量
.def **addr=r2 .def break_flag=r3
;电机控制数据地址变量
;开机信号, 初始化电机启停标志
.org $000 ;程序首址,复位执行地址 rjmp _reset ;跳过器件中断区 .org INT0addr ;INT0中断入口地址 rjmp _int0_fun ;转中断服务程序
.org 0x02a ;主程序地址应大于所有中断入口地址,ATmega16最大中断地址为0x028 _reset: ;程序初始化
ldi r16,low(RAMEND) ;确定ATmega16堆栈指针$045f OUT spl,r16
ldi r16,high(RAMEND) out sph,r16
;*********************************************************************************** ;其中RAMEND为在配置文件”m16vdef.inc”预定义的RAM的容量
: *********************************************************************************** ldi r16,0x40 ;0100 0000B out GICR,r16 ;启动INT0 ldi r16,0x02 ;MCUCR中 ISC01(1) ISC00(0) 0000 0010B out MCUCR,r16 ;设置INT0为下降沿触发(0x02)
ldi r16,0xff ;方向寄存器DDRB规定1为输出,0为输入 out DDRB,r16 ;设置B口为输出口 ldi r16,0x00 ;IO口有推换0(PORTBn=0), 推换1(PORTBn=1)输出, out PORTB,r16 ;B口拘推换0输出
mov break_flag,r16 ;初始化电机启停标志break_flag sei ;置位I,置位SREG(状态寄存器)中的全局中断标志(I) _wait: ;等待键入 Mov r16,break_flag ;电机启停标志,只有r16—r31可进行立即数操作 cpi r16,0xff ;与立即数比较,首次break_flag==0xff为有键入
brne _wait ;不相等转移等待(无键按下),相等顺序执行(有键按下) _run_load_data: ;从FALSH中将数据表读入RAM中 rcall _load_ptod ;调用_load_ptod把数据从Flash装入RAM区 ldi r16,0x61 ;设置数据表首地址 mov **addr,r16 ;借助r16进行立即数操作,保存数据
ldi
motor_num,0x00
;从第一个电机动作起
rjmp _run_on ;开始动作 _run_load_motorX: ;某电机到末位重读入该电机数据表 rcall _load_ptod_motorX ;调用读取一个电机的原始数据 ldi r16,0x61 ;装入第一个数据 mov **addr,r16 ;数据保存
_run_on:
;电机运转程序段
_run_wait: mov r16,break_flag cpi r16,0xff brne _run_wait ldi r16,0x61
mov **addr,r16 rcall _run
;运行过程为进行停止和继续的控制 ;停止和继续的状态
;与立即数比较,首次break_flag==0xff为有键入
;不相等转移等待(无键按下),相等顺序执行(有键按下) ;使**addr指向首地址
; 借助r16进行立即数操作,保存数据 ;电机运转循环
rcall mov lsl lsl add
mov ld
_run ;调用两次,保证运转的精度(亦可在run中修改脉冲数) r16,motor_num ;一个电机有四个数据,当前位置、控制命令、 r16 ;方向、增幅,这里通过电机号来确定每个电机的 r16 ;当前位置数据的偏移地址(motor_num*4) **addr,r16 ;使**addr指向该电机数据块中\"当前位置\"数据
r28,**addr loc_now,Y+
;使Y指针指向\"当前位置\"数据
;读取数据块资料,以便进行修改
inc ld ld mov r28 ;越过控制命令数据
loc_direct,Y+ ;读取方向数据
loc_amp,Y ;读取增量数据 r28,**addr ;重置地址,以进行相应电机控制数据的修改
;修改motor_num使标识电机的数据块
rcall _change_data
inc motor_num cpi motor_num,0x04 brlo _run_on ldi motor_num,0x00
;电机号加1指向下一个电机
;(到末电机否?)(可在此处修改以增加电机数到最多8个)
;清零电机号,保证电机的运转从0号电机开始
rjmp _run_on ;到末电机跳转,重新开始 _reset_end: rjmp _run_load_motorX ;跳转读取原始数据,使电机复原
;*********************************************************************************** ;_run子程序,功能:电机动作了程序 ;注释,电机的控制原理如下图: ;(v) ; ^ 脉冲总宽度为20ms
; |<-------------------------------------------------------------------------->| ; | | ; | | ; |__| 一号电机正电平(其宽度由其位置数据loc_now决定) | ; | | |
; |--|-------------------------------------------------------------------------|---> ; | |___| 二号电机正电平 ; | | |
; |------|-------------------------------------------------------------------------> ; | |____| 三号电机正电平 ; | | |
; |-----------|------.-------------------------------------------------------------> ; | | . ; | . _loop延时形成正电平宽度
; |------------------------>|---|<-------------------------------------------------> ; | |___| N号电机正电平 ; | | |
; |-----------------------------|--------------------------------------------------> ; | |___| N+1号电机正电平 ; | | | (t) ; ---------------------------------------------------------------------------------> ; 20ms=((time_h-1)*256+time_l)*_delay;delay为延时9.88us ; 所以times=20*1000/9.88=2024=0x07e8,
; 所以time_h=0x08,time_l=0xe8 , 实测延时为20ms
;***********************************************************************************
RUN子程序:
设置脉冲个数 读入RAM数据表首地址 设置20ms计时变量高低位 读控制数据入变量 置脉冲高电平并延时 N 到数据表末? Y 延时补足20ms 脉冲数加1 满3次? Y Ret 图18 RUN子程序流程图
_run:
;run子程序
ldi run_times,0x00
_run_next: ;一个脉冲的开始 ldi r28,0x61 ;Y指针指向RAM数据区首地址 _run_settime: ;设置脉冲总计时时间之高低位(参考.def中)
Ldi time_h,0x08 ;20ms计时变量高位赋值0x08 ldi time_l,0xe8 ;20ms计时变量低位赋值0xe8
_run_load: ;读取当前电机数据
ld loc_now,Y+ ;只读取位置参数和控制口命令 ld **um,Y+ ;通过inc跳过下面两句
inc r28
;ld
loc_direct,Y+
_run_start:
Out PORTB,**um
mov loc_temp,loc_now
inc r28
;ld loc_amp,Y+ ;开始输出高电平并延时 ;输出控制命令
;读入位置数据
rcall _loop ;高电平延时,形成一定宽度 ldi r16,0x00 out PORTB,r16 ;置低电平 cpi r28,0x70 ;是否到了数据表的未端(可在此处修改以增加电 brlo _run_load ; 机 数) _run_check: ;继续延时补足20ms rcall _delay ;调用0.01ms延时 dec time_l ;修改20ms延时变量低位 brne _run_check ;若需借位顺执 dec time_h ;借位 breq _run_end ;延时结束否? rjmp _run_check ;未结束返回_run_check,否则顺执 _run_end: inc run_times ;每次输出3个脉冲,不同的脉冲数会对 cpi run_times,0x03 ;电机的速度造成影响,越大速度越慢, brlo _run_next ;因为多余的脉冲只是为了更好的定位 _run_ret: ret
;*********************************************************************************** ;_loop子程序,功能:电机PWM控制信号的正电平宽度延时
;注释: 主要通过loc_temp变量的值来确定正电平的宽度,同时修改time_h和time_l的值 ; 以保证整个脉冲宽度为20ms
;*********************************************************************************** _loop: ;脉冲高电平延时子程序 rcall _delay ;调用延时 dec time_l ;修改总20ms延时变量 brne _loop_check ;判断借位否? dec time_h ;借位 _loop_check: dec loc_temp ;位置数据决定延时时间 brne _loop ret
;*********************************************************************************** ;_load_ptod子程序,功能:把FALSH中的数据表格全部读入RAM区
;*********************************************************************************** _load_ptod: ;把数据从Flash装入RAM区,数据块传送 ldi r31,0x02 ;确定Z指针所指方向Z=0x0120X2=0x0240 ldi r30,0x40 ;由于为字空间,所以Z值是数据表地址的两倍 clr r29 ;Y指针指向RAM数据区 ldi r28,0x61 ;Y=0x061 _load_loop1: ;开始移动数据 lpm ;将Z指针所指向的数据送R0 st Y+,r0 ;先R0内容送Y=(0x061),后Y=(0x062)指针加1 inc r30 ;取数地址Z=(0x0241)加1 cpi r30,0x50 ;Z=0x0250是数据表的边界(可在此处修改以增加电机数)
breq _load_loop2 ;相等转移,子程序返回,不相等顺序执行 rjmp _load_loop1 ;继续传送数据 _load_loop2: ret ;子程序返回
;********************************************************************************* ;_delay子程序,功能:延时近似0.01ms
;注释:理论计算:10us=0.125*80t;h=(80t-5t)/3t=25D=0x19
; 5t包括(ldi+ret)3t包括(dec+brne);实测为9.88us,若修正值为0x1a,则实测值为10.25us ;********************************************************************************* _delay: ;0.01ms定时程序 ldi r16,0x19 ;送延时常数,需1t _delay_loop: dec r16 ;-1,需1t brne _delay_loop ;不为0转移,为0顺执;需1t/2t ret ;子程序返回;需4t
_Change_data子程序: N _Reset_end N
保存修改值
Ret 图19 _Change_data子程序流程图
子程序开始 方向=0? N 方向=1? Y 加增量 过上界? Y _Reset_end 过下界? Y _Reset_end Ret 保存修改值 减增量 N Y
;********************************************************************************* ;_change_data子程序,功能:修改数据区数据.
;注释: 其工作原理,首先对方向进行判定,而后通过加减速增量来修改数据,并判断是否出界 ; 最后把数据返回到RAM 数据区中,等待其他程序的调用.
;********************************************************************************* _change_data: ;修改数据块的数据,只修改loc_now cpi loc_direct,0x00 ;也可通过增加本程序的功能来修改 breq _change_down ;其他三个数据
cpi loc_direct,0x01 breq _change_up rjmp _reset_end
_change_down: sub loc_now,loc_amp cpi loc_now,0x38 brlo _reset_end rjmp _change_end _change_up: adc loc_now,loc_amp cpi loc_now,0xf0 brsh _reset_end _change_end: Mov r28,**addr
St
Y,loc_now
;0x00反方向;0x01正方向 ;非正非反则跳出
;反方向修改数据 ;即减一个增量 ;判断是否出界
;若出界则跳转读取原始数据 ;否则保存数据,等待调用 ;正方向修改数据 ;即加一个增量
;若出界则跳转读取原始数据
;保存参数入RAM,以待调用
ret
;********************************************************************************* ;_load_ptod_motorX子程序,功能:读取一个电机的原始数据. ;注释: 先确定要读取数据和写入数据的首地址
; 接着通过LPM把数据返回到RAM 数据区中,等待其他程序的调用.
;********************************************************************************* _load_ptod_motorX: ldi r31,0x02 ;把数据从程序区装入RAM区,0x02高位地址 mov r16,motor_num ;电机控制命令 lsl r16 ;左移1位,相当于*2 lsl r16 ;左移1位,相当于*2 ldi r30,0x40 ;0x40低位地址 add r30,r16 ;绝对地址:0x0240+motor_num*4 clr r29 ;清0, mov r16,motor_num ;计算该电机数据在RAM区的偏移地址 lsl r16 ;左移1位,相当于*2 lsl r16 ;左移1位,相当于*2 ldi r28,0x61 ;绝对地址:0x61+motor_num*4 add r28,r16 ;加偏移地址成绝对地址 lpm ;本处只读取了Z=r31+r30地址内容送r0, 初始的\"当前位置\" st Y+,r0 ;间接数存在Y=r29+r28地址RAM内,后Y指针加1, ret ;读者可通过一个小循环达到读取所有数据的功效
;*********************************************************************************** ;_int0_fun,功能:INT0中断服务子程序. ;注释: 其通过每次按键进行异或的操作,
; 使相临两次的break_flag值都不同来达到启、停切换的功能
;***********************************************************************************
_int0_fun: ;INT0中断服务子程序, Ldi r16,0xff ;对每次按键进行异或的操作, eor break_flag,r16 ;使相临两次的break_flag值都不同 reti ;达到启、停切换的功能
.org 0x0120
.dw 0x0138,0x1001 ;控制命令(例0x01),当前位置(0x38),增幅(0x10)、方向(0x01) .dw 0x02e0,0x0a00 .dw 0x04e0,0x0500 .dw 0x08e0,0x0600
;*********************************************************************************** ;数据结构:控制命令,当前位置,增幅、方向;前者范围(0x38-0xe0),方向(0/1),增幅
;小于初始结束位置之差。(数据结构:控制命令,当前位置,增幅、方向--如上之从左到右)
;*********************************************************************************** ;1)控制命令是针对是B口而言的,也就是一个口来控制该电机,所以通过口地址的变换可以 ; 非常轻易地扩展到8个电机,如果还要增加,则需要再做些改动。
;2)当前位置,这个数据是决定脉冲的占空比的数据,由于电机是通过PWM来控制,并由反馈电阻来 ; 来定位的,所以不同的占空比脉冲决定不同的电机位置。下面是几个典型值:0x38(-90度)、 ; 0x50(-45度)、0x80(0度)、0xc0(+45度)、0xf0(+90度)。
;3)增幅,也就是修改数据中加减速的量的大小,其决定着电机的转动速度。若值越大,速度越高, ; 精度略有下降;若值很小,速度相应很小,不地精度可以较高,下面是几个节拍的典型值 ; 电机摆动速度,0x10(20度/S)、0x0a(12度/S)、0x05(5度/S)以上几个都是近似值,读者可根 ; 自己的要求对数据进行修改以观察效果。这是在run程序一次调用输出三个脉冲时的速度情况, ; 读者可以根据不同的速度和精度要求,修改输出脉冲数(在run子程序中有标识),脉冲数越大, ; 速度越慢,每一步的精度越高,反之速度越快,大角度转移时精度不高. ;4)方向只有两个,0/1.
;***********************************************************************************
广州市天河双龙电子有限公司 **
**
广州双龙:广州天河路561号新赛格电子城331室(510630) 电话:**、87505012 传真:分机620
北京双龙:北京海淀知春路132号中发大厦616室(100086) 电话:**、62653785 传真:**
上海双龙:上海北京东路668号科技京城东搂12H2室(200001) 电话:** 、53081502 传真:分机213
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- shangjiatang.cn 版权所有 湘ICP备2022005869号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务