本帖最后由 小燕子神飞 于 2012-6-20 20:06 编辑
这是我的毕业设计,一个带有机械轮子和电机的小地鼠车身,上面有一块控制电路板,可以接收不远处的无线电控制指令,然后前进转弯等;
笔记本的USB接口还有一块转接电路板,把USB数据转换成无线电指令和机器鼠通信。
目前这套装置的功能是:运行电脑上的一个上位机程序,然后通过电脑键盘向不远处的电动小地鼠发送控制指令,一共有6种,
其中 W S A D 这4个键控制小地鼠前进后退左右转,K和L 这两个键控制小地鼠摇脑袋,按 K 小脑袋向左摇,按 L 小脑袋向右摇。
这个设计和通常的系统不同的地方是,全部程序(3个)写在一个记事本文件中(超萌小地鼠.txt)。用我的编译器打开这个记事本文件,
点击编译按钮,生成3个我们最终需要的目标文件。其中一个是小地鼠从机的hex文件,下载到从机上的MEGA32中,另一个是USB转接板的hex文件,
这个下载到USB转接板的控制芯片上(是一个AT89S52),最后有个上位机的编译目标文件,不过不是exe文件,而是生成一个V扩展名的文件:超萌小地鼠控制器.V 。
这个类似于java的字节码文件,需要在一个虚拟机中运行。点击编译器的“打开文件”按钮打开这个V文件,打开后编译器会自动调用虚拟机运行它。
运行结果就是出现一个窗体,这个窗体可以接受电脑键盘按键事件,并控制远程小地鼠相应运动。
也就是说这个设计在一个记事本中包含了一个上位机程序(编译生成V文件),一个AT89S52单片机程序和一个MEGA32程序。点击编译之后生成对应的3个目标文件,
另外这个开发环境还包含了一个ISP下载器,编译完就可以点击下载按钮把hex文件下载到89S52和MEGA32里。
程序的语法部分我是参考C语言的,然后我改了一些地方,比如支持中文编程,呵呵。
如果您感兴趣可以到我的博客看看更详细的介绍:
blog.sina.com.cn/freerobot
这有个视频:
http://blog.sina.com.cn/s/blog_694e0ad701012gbp.html
attachimg]26551[/attachimg]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
源程序 小地鼠.txt
//*******************************************************
//上位机控制程序
ACI cpu = ACI cputype VM 小地鼠控制器,
ACI 启动 -> 启动,
user32 windows -> windows,
导入 组件库 windows windows,
导入 组件库 windows user32,
导入 组件库 windows kernel32,
导入 组件库 userdll ch375,
导入 组件库 AVM AVM,
link 虚拟类型 AC {} -> ACI Cloud code,
//=======================================
引擎(公开)
启动
{
HDC = AVM ACI_ShowAVM[ 300, 300 ],
t1(T) = ch375 CH375SetTimeout[ 0, 5000, 5000 ],
r(Z32) = ch375 CH375OpenDevice[ 0 ],
如果 r == -1,
user32 MessageBox[ 0, "Open CH375 Error!", "Warning:", 0 ],
kernel32 ExitProcess[ 0 ].
buffer 0 = 0,
buffer 1 = 0,
buffer 2 = 0,
buffer 3 = 0,
buffer 4 = 0,
buffer 5 = 0,
length(N32) = 6,
AVM ACI_SetInterrupt[ AVM 中断类型 KeyDown, true ],
AVM ACI_SetInterrupt[ AVM 中断类型 KeyUp, true ],
按下结束键 = false,
反复执行
length = 6,
ta(T) = ch375 CH375WriteData[ 0, buffer, length ],
ta = ch375 CH375ReadData[ 0, buffer, length ],
kernel32 Sleep[ 50 ],
如果 按下结束键, 中断.
...
ch375 CH375CloseDevice[ 0 ],
kernel32 ExitProcess[ 0 ],
}
buffer([N8*8]),
HDC(N32),
按下结束键(T),
引擎(interrupt[AVM 中断类型 KeyDown])
KeyValue(N32),
KeyDown
{
如果 KeyValue,
== 'W' 时, buffer 0 = 1,
== 'S' 时, buffer 1 = 1,
== 'A' 时, buffer 2 = 1,
== 'D' 时, buffer 3 = 1,
== 'K' 时, buffer 4 = 1,
== 'L' 时, buffer 5 = 1,
== 'T' 时, 按下结束键 = true,
否则 ...
}
引擎(interrupt[AVM 中断类型 KeyUp])
KeyValue(N32),
KeyUp
{
如果 KeyValue,
== 'W' 时, buffer 0 = 0,
== 'S' 时, buffer 1 = 0,
== 'A' 时, buffer 2 = 0,
== 'D' 时, buffer 3 = 0,
== 'K' 时, buffer 4 = 0,
== 'L' 时, buffer 5 = 0,
否则 ...
}
//*******************************************************
//USB转换器程序
ACI cpu = ACI cputype mcs51 USB控制器,
ACI 启动 -> 控制器 启动,
导入 组件库 mcs c51 chip,
导入 组件库 software time mcs_24mhz time,
指示灯 定时器 -> 定时器,
导入 组件库 hardware start mcs51 led,
无线收发器 芯片 -> chip,
无线收发器 组件
{
公开 link 接口 组件 {} -> nrf2401,
公开 link 芯片 组件 {}
nrf2401 CE_port -> CE_port,
nrf2401 IRQ_pin -> IRQ_pin,
nrf2401 CSN_port -> CSN_port,
nrf2401 spi SCK_port -> SCK_port,
nrf2401 spi MISO_pin -> MISO_pin,
nrf2401 spi MOSI_port -> MOSI_port,
link CE_port(N1) = 芯片 P1 3,
link IRQ_pin(N1) = 芯片 P1 2,
link CSN_port(N1) = 芯片 P3 0,
link SCK_port(N1) = 芯片 P1 0,
link MISO_pin(N1) = 芯片 P3 1,
link MOSI_port(N1) = 芯片 P1 1,
导入 组件库 hardware nrf2401 mcs nrf2401,
}
CH372 定时器 -> 定时器,
CH372 芯片 -> chip,
CH372 组件
{
公开 link 接口 组件 {} -> CH372,
公开 link 定时器 组件 {}
公开 link 芯片 组件 {}
CH372 DATA_port -> DATA_port,
CH372 INT_port -> INT_port,
CH372 WR_port -> WR_port,
CH372 RD_port -> RD_port,
CH372 A0_port -> A0_port,
link DATA_port(N8) = 芯片 P0,
link INT_port(N1) = 芯片 P2 7,
link WR_port(N1) = 芯片 P2 6,
link RD_port(N1) = 芯片 P2 5,
link A0_port(N1) = 芯片 P2 4,
CH372 定时器 -> 定时器,
导入 组件库 hardware ch372 mcs ch372,
}
控制器 指示灯 -> 指示灯,
控制器 定时器 -> 定时器,
控制器 USB控制器 -> CH372 接口,
控制器 无线收发器 -> 无线收发器 接口,
控制器 组件
{
公开 link 指示灯 组件 {}
公开 link 定时器 组件 {}
公开 link USB控制器 组件 {}
公开 link 无线收发器 组件 {}
引擎(公开)
启动
{
指示灯 初始化[],
指示灯 闪烁[ 3 ],
USB控制器 初始化[],
如果 !USB控制器 设置工作模式成功[ 2 ], 指示灯 闪烁[ 100 ].
USB控制器 设置超时时间[ 200 ],
无线收发器 初始化[],
如果 !无线收发器 工作正常[], 指示灯 闪烁[ 100 ].
无线收发器 设置超时时间[ 200 ],
无线收发器 本机地址 0 = 0,
无线收发器 本机地址 1 = 0x43,
无线收发器 本机地址 2 = 0x10,
无线收发器 本机地址 3 = 0x10,
无线收发器 本机地址 4 = 0x01,
对方地址 0 = 27,
对方地址 1 = 0x43,
对方地址 2 = 0x10,
对方地址 3 = 0x10,
对方地址 4 = 0x01,
长度(N8) = 0,
反复执行
反复执行 直到 USB控制器 接收到数据[ 数据区, 长度, true ], ...
USB控制器 发送数据[ 数据区, 长度 ],
如果 长度 != 6, 指示灯 闪烁[ 100 ].
无线收发器 设置为发射模式[],
指示灯 打开[],
无线收发器 发射数据[ 数据区, 6, 对方地址 ],
指示灯 关闭[],
...
}
对方地址([N8*5]),
数据区([N8*32]),
}
//*******************************************************
//遥控小地鼠从机程序
//晶振: 6MHz
ACI cpu = ACI cputype mega32 小地鼠,
ACI 启动 -> 从机 控制器 启动,
从机 组件
{
导入 组件库 avr mega32 chip,
指示灯 OUT_PORT -> 指示灯_配置 OUT_PORT,
指示灯 OUT_DDR -> 指示灯_配置 OUT_DDR,
指示灯_配置 组件
{
公开 link OUT_PORT(N1) = ACI Wind 从机 chip PORTB 4,
公开 link OUT_DDR(N1) = ACI Wind 从机 chip DDRB 4,
}
指示灯 定时器 -> 定时器,
导入 组件库 hardware start avr led,
导入 组件库 software time avr_6mhz time,
无线收发器 芯片 -> chip,
无线收发器 组件
{
公开 link 接口 组件 {} -> nrf2401,
公开 link 芯片 组件 {}
nrf2401 CE_ddr -> CE_ddr,
nrf2401 CE_port -> CE_port,
nrf2401 IRQ_ddr -> IRQ_ddr,
nrf2401 IRQ_pin -> IRQ_pin,
nrf2401 CSN_ddr -> CSN_ddr,
nrf2401 CSN_port -> CSN_port,
nrf2401 spi SCK_ddr -> SCK_ddr,
nrf2401 spi SCK_port -> SCK_port,
nrf2401 spi MISO_ddr -> MISO_ddr,
nrf2401 spi MISO_pin -> MISO_pin,
nrf2401 spi MOSI_ddr -> MOSI_ddr,
nrf2401 spi MOSI_port -> MOSI_port,
link CE_ddr(N1) = 芯片 DDRD 7,
link CE_port(N1) = 芯片 PORTD 7,
link IRQ_ddr(N1) = 芯片 DDRD 1,
link IRQ_pin(N1) = 芯片 PIND 1,
link CSN_ddr(N1) = 芯片 DDRD 4,
link CSN_port(N1) = 芯片 PORTD 4,
link SCK_ddr(N1) = 芯片 DDRD 6,
link SCK_port(N1) = 芯片 PORTD 6,
link MISO_ddr(N1) = 芯片 DDRD 5,
link MISO_pin(N1) = 芯片 PIND 5,
link MOSI_ddr(N1) = 芯片 DDRD 3,
link MOSI_port(N1) = 芯片 PORTD 3,
导入 组件库 hardware nrf2401 avr nrf2401,
}
控制器 指示灯 -> 指示灯,
控制器 定时器 -> 定时器,
控制器 舵机 -> 舵机,
控制器 直流电机 -> 直流电机,
控制器 无线收发器 -> 无线收发器 接口,
控制器 组件
{
公开 link 指示灯 组件 {}
公开 link 定时器 组件 {}
公开 link 舵机 组件 {}
公开 link 直流电机 组件 {}
公开 link 超声波探测器 组件 {}
公开 link 无线收发器 组件 {}
引擎(公开)
启动
{
指示灯 初始化[],
舵机 初始化[],
直流电机 初始化[],
无线收发器 初始化[],
如果 !无线收发器 工作正常[], 指示灯 闪烁[ 100 ].
无线收发器 设置为接收模式[],
无线收发器 设置超时时间[ 200 ],
无线收发器 本机地址 0 = 27,
无线收发器 本机地址 1 = 0x43,
无线收发器 本机地址 2 = 0x10,
无线收发器 本机地址 3 = 0x10,
无线收发器 本机地址 4 = 0x01,
对方地址 0 = 0,
对方地址 1 = 0x43,
对方地址 2 = 0x10,
对方地址 3 = 0x10,
对方地址 4 = 0x01,
指示灯 闪烁[ 3 ],
舵机 角度 = 55,
#asm "sei"
反复执行
反复执行 直到 无线收发器 接收到数据[ 数据区, 6, true ], ...
如果 数据区 4 == 1,
如果 舵机 角度 < 85, 舵机 角度 + 5.
...
如果 数据区 5 == 1,
如果 舵机 角度 > 35, 舵机 角度 - 5.
...
左轮速度(Z8) = 0,
右轮速度(Z8) = 0,
方向(Z8) = 0,
如果 数据区 0 == 1, 方向 = 1.
如果 数据区 1 == 1, 方向 = -1.
如果 方向 == 0,
如果 数据区 3 == 1, 左轮速度 = 20, 右轮速度 = -20.
如果 数据区 2 == 1, 左轮速度 = -20, 右轮速度 = 20.
否则
左轮速度 = 20 * 方向,
右轮速度 = 20 * 方向.
直流电机 左轮速度 = 左轮速度,
直流电机 右轮速度 = 右轮速度,
...
}
数据区([N8*32]),
对方地址([N8*5]),
}
//********************************************
舵机 chip -> chip,
舵机 直流电机 -> 直流电机,
舵机 组件
{
公开 link chip 组件 {}
公开 link 直流电机 组件 {}
//======================================
引擎(公开)
初始化
{
//初始角度
角度 = 30,
chip TCCR1A = 0,
// chip TCCR1B=_BV(WGM12)|_BV(CS10)|_BV(CS11),
chip TCCR1B = 0b0000_1001,
//12MHz
//chip OCR1AH = 0x01,
//chip OCR1AL = 0x2c,
//6MHz
chip OCR1AH = 0x00,
chip OCR1AL = 0x96,
chip TIMSK | 0b0001_0000,
角度增量 = 0,
out_put = 0b0000_0001,
SERVO_OUT_ddr = 1,
SERVO_OUT = 0,
}
//======================================
//中断服务函数
引擎(interrupt [0x000e])
timer1_compA
{
角度增量 + 1,
如果 角度增量 < 100,
如果 角度增量 == 角度, SERVO_OUT = 0.
返回.
角度增量 = 0,
out_put << 1,
如果 out_put == 0, out_put = 0b0000_0001.
SERVO_OUT = out_put 0(N1),
//直流电机进程
直流电机 run[],
}
//======================================
公开 角度(N8),
out_put(N8),
角度增量(N8),
link SERVO_OUT(N1) = chip PORTC 0,
link SERVO_OUT_ddr(N1) = chip DDRC 0,
}
//********************************************
直流电机 chip -> chip,
直流电机 组件
{
公开 link chip 组件 {}
//======================================
引擎(公开)
初始化
{
//端口初始化
motor1_A_ddr = 1,
motor1_A = 0,
motor1_B_ddr = 1,
motor1_B = 0,
motor2_A_ddr = 1,
motor2_A = 0,
motor2_B_ddr = 1,
motor2_B = 0,
//控制变量初始化
左轮速度 = 0,
左轮速度增量 = 0,
右轮速度 = 0,
右轮速度增量 = 0,
}
//======================================
//直流电机转速控制
引擎(公开)
run
{
//电机1控制
左轮速度增量 + 1,
如果 左轮速度增量 >= 20, 左轮速度增量 = 0.
如果 左轮速度增量 < +左轮速度,
如果 左轮速度 > 0,
motor1_A = 1,
否则
motor1_B = 1.
否则
motor1_A = 0,
motor1_B = 0.
//电机2控制
右轮速度增量 + 1,
如果 右轮速度增量 >= 20, 右轮速度增量 = 0.
如果 右轮速度增量 < +右轮速度,
如果 右轮速度 > 0,
motor2_A = 1,
否则
motor2_B = 1.
否则
motor2_A = 0,
motor2_B = 0.
}
//======================================
//直流电机
公开 左轮速度(Z8),
公开 右轮速度(Z8),
公开 左轮速度增量(Z8),
公开 右轮速度增量(Z8),
link motor1_A(N1) = chip PORTC 2,
link motor1_A_ddr(N1) = chip DDRC 2,
link motor1_B(N1) = chip PORTC 3,
link motor1_B_ddr(N1) = chip DDRC 3,
link motor2_A(N1) = chip PORTC 6,
link motor2_A_ddr(N1) = chip DDRC 6,
link motor2_B(N1) = chip PORTC 7,
link motor2_B_ddr(N1) = chip DDRC 7,
}
}
|