高性能CAN适配器的设计与实现
2008-04-11
作者:姜海鹏1,周玉杰2
摘 要: 一种快速、高效的CAN适配" title="适配">适配器设计方案。把双端口" title="双端口">双端口RAM分为两个独立的区域,实现了双缓冲" title="双缓冲">双缓冲,并从软硬件上保证了PC机和片载单片机对双端口RAM的不冲突访问。
关键词: CAN总线 CAN适配器 双端口RAM 单片机
Stewart平台机器人又称六自由度并联机器人,它具有刚度大、承载能力强、误差小、精度高、自重负荷比小、动力性能好、控制容易等一系列优点。本文基于CAN适配器实现了Stewart平台机器人的远程监控。由于在应用Stewart平台进行实验性研究时,外部的控制量无法预知,并有可能超出Stewart平台机器人的承受范围。因此,外部的控制命令需要经过一个保护、控制系统,经过此系统上位机的解析后再送给Stewart平台。同时,上位机也负责实时采集Stewart平台的运动数据并发送。远程控制计算机通过接收到的状态信息产生下一时刻的控制命令。整个系统结构如图1所示。
远程监控的实现要求机器人把并联机器人六根杆的长度传送给远程控制端,再把控制量传回机器人。实际应用中要传输的杆长为1000~2000mm,一根杆长可以用10位二进制表示,6根杆长共用60位,加上4位校验码共8个字节。控制量是下一次机器人的6根杆长,所以也为8个字节。为了保证机器人的运行安全,要求控制周期最大为20ms,由于监控端还要进行机器人位置姿态解算,因此必须选择实时、高效的通信方式。为了保证实时,选用了基于实时DOS的机器人控制系统。如果选用以太网卡通信,其在DOS下的驱动比较麻烦,况且如果使用TCP/IP协议实现局域网通信,略显复杂。
1 CAN适配器的研究现状
控制器局域网CAN-bus(Controller Area Network)是目前国际上应用最广泛的现场总线之一。它是一种架构开放、广播式的新一代网络通信协议,成本低,实时处理能力强,可以在强电磁干扰环境下可靠工作。因此CAN总线被广泛应用于离散控制领域中的过程检测和控制,特别是工业自动化的底层监控,以解决控制与测试之间可靠和实时的数据交换。
CAN总线具有协议简单、有效载荷高等特点,可以实现点对点和多点间的通信,其最高通信速率达1Mbps/40m,用于局域网通信时可保证较高的实时性。假设实际通信中CAN总线的效率为80%,则传送22字节(有效数据8+8字节,控制信令3+3字节)的时间仅为0.22ms,完全可以满足本项目需要。本文根据控制要求设计实现了适合控制系统数据传输的CAN控制器,具有速率高、实时性好、PC机运行负担小等特点。
本文在众多CAN适配器的研究和开发的基础上做了进一步改进,把双缓冲的概念引入双端口RAM,实现了PC机读写和板载单片机接收的并行工作,并用两个锁存" title="锁存">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器" title="锁存器">锁存器避免PC机与单片机的访问冲突。实践表明,该方法可以大大提高通信效率。
2 双缓冲的实现
2.1 硬件基础
适配卡主要由双端口RAM、微处理器、发送/接收数据缓冲区、CAN控制器及其收发电路组成,如图2所示。其中CAN控制器采用Philips公司的SJA1000及与其对应的PCA82C250 CAN总线收发器;板载单片机采用AT89C52,负责SJA1000的初始化,向PC端接收/发送数据以及通过控制SJA1000实现数据的接收和发送等通信任务;发送和接收缓冲区各由一个62256存储器构成,各容量为8KB,采用先进先出的方式存放数据。
本文采用双缓冲区模式实现高效通信。该模式在工程上称为“乒乓”缓冲区模式,与常用的单缓冲区模式相比,其优点是:可以使用容量较小的内存,不间断地对无限量的数据缓冲(输入与输出端需协同工作)。这种缓冲区模式的工作原理是: 在内存中开辟两块容量相等的缓冲区(以下称1# 缓冲区和2# 缓冲区)。在通信时,PC机获取某缓冲区(如1# 缓冲区),把数据写入;然后获取另一块缓冲区的写控制权,在PC机给2#缓冲区写的同时,单片机把1#缓冲区的数据传送给CAN控制器,从而实现PC机写入双端口RAM与单片机发送的并行工作,大大提高通信效率。为了实现此功能,使用双端口RAM作为PC机和单片机之间的交换区,并协调缓冲区的控制权,避免读写冲突。
双端口RAM采用CYPRESS公司的7C132,容量为2KB。其中1000字节作为PC机向微处理器发送数据的缓冲区,1000字节作为PC机从微处理器接收数据的缓冲区。其他区域用于存放PC机对板卡的初始化信息,包括帧长、通信模式、目标节点ID等。双端口RAM拥有两个完全独立的端口,并允许两个端口独立、异步地对存储器中的任何存储单元进行存取操作。当两个端口同时对存储器中的同一单元进行存取操作时会发生竞争现象,造成数据的丢失或误读。为此,双端口RAM利用内部的仲裁逻辑电路决定两边的优先权,并对外提供2个信号,以表示对该端口的操作是否有效。未获得许可的端口信号被拉成低电平,此间,对该端口的读操作均无效。解决双端口RAM的竞争问题有两种方法:软件查询法和硬件判优法。
硬件判优法需要CPU具有等待时序的功能。本文所讨论的CAN适配卡中微处理器采用的AT89C52不具备READY引脚的功能,因此硬件判优法在本适配卡中无法实现。
软件查询法是将信号接到微处理器的一个I/O引脚上,通过查询此I/O引脚的状态确定当前是否能对双端口RAM进行读写操作。软件查询法会增加微处理的负担,仅适用于竞争现象不经常发生的情况。本文所讨论的CAN适配卡通过两片74LS374实现PC机和单片机的状态锁存,巧妙地实现单片机和PC机的协调通信。
具体电路如图3所示。
PC机的状态字锁存信号由ISA总线的和139A的Y1经过一个或非门决定。平时CLK引脚为低电平,当PC向139A的Y1所对应的I/O地址(即A2~A9为跳线开关选定地址,A1、A0为01)写状态字时,和Y1同时为低,CLK引脚变为高电平,出现一个上升沿,从而将ISA数据总线的状态字锁存在374中,等待C52的读取。当C52从PC状态字对应地址(F700H)读取状态字时,139B的Y3、C52的P2.3和同时出现低电平,从而使得374的引脚信号有效,将374锁存内容送到C52的P0口,C52完成对PC状态字的读取。
C52的、P2.4和139B的输出Y3经过逻辑或非决定C52状态字的锁存信号CLK是否有效。当C52向其状态字对应地址(EF00H)写入状态字时,、P2.4和Y3会同时出现一个低电平信号,经过或非门后变为高电平,由于CLK引脚平时是低电平,这时会出现一个上升沿,从而把C52送到P0口的状态字锁存在74LS374中,等待PC的读取。当PC从C52状态字地址(A2~A9为跳线开关选定地址,A1、A0为10)读取状态字时,ISA总线的和139A的Y2会同时出现低电平信号,使得374的引脚信号有效,将其锁存内容送到ISA的数据总线上,从而完成对C52状态字的读取。
2.2 状态控制
双缓冲机制非常有效,但是用双端口RAM实现双缓冲时,必须解决访问冲突问题。为了减小CPU查询此状态的负担,PC端和单片机端均通过自己的状态变量和读取对方锁存器来判别缓冲区的使用权,以避免访问冲突。下面介绍实现方法。
记连接ISA/IOW的锁存器为PC_STATUS,该锁存器反映PC机的状态变量PC_FLAG,为PC写,单片机只读;记连接C52/WR的锁存器为MCU_STATUS,该锁存器反映单片机的状态变量MCU_FLAG,为单片机写,PC只读。
锁存器低4位中,第0位反映1# 缓冲区的占有权。规定两个锁存器的低2位中,若第0位相同,则PC端对1# 缓冲区有控制权,否则该缓冲区的控制权在单片机端;锁存器第1位反映2# 缓冲区的状态,不再赘述。控制权示意图如图4。如果任意一方把自己锁存器的对应位求反后,则表示放弃控制权。如PC_STATUS=01H,MCU_STATUS=00H,表示PC机拥有2#缓冲区,单片机拥有1#缓冲区。MCU_STATUS保持不变,当PC_STATUS=03H时,表示PC放弃2#缓冲区,即单片机同时得到两个缓冲区。
锁存器中第3、4位为1,分别表示1#、2#缓冲区有数据,PC读到此状态便知单片机已写好数据等待PC机读取;单片机读到此状态便知该缓冲区中有数据要发送。
3 软件设计
CAN适配器与PC机的关系如图5所示。最上面一层是应用层,主要功能是实现用户与CAN适配卡之间的接口程序,完成数据的发送和接收。其余层构成CAN适配器。其中控制层由微处理器AT89C52完成,主要负责检测PC端和CAN总线的状态,并进行相应的数据转移,即把PC端要发送的数据从双端口RAM中取出并通过CAN总线发往指定的节点,或者接收来自CAN总线上的数据并将其放入接收缓冲区等待PC端用户的读取。数据层主要由CAN控制器SJA1000完成报文的验收和滤波以及数据的接收/发送。最底层是物理层,CAN收发器PCA82C250完成协议控制器和物理传输线路之间的接口,将总线电缆上的差动电压转换为逻辑电平信号或者进行相反的操作。
为了实现通信,本文完成了PC机程序和板载单片机程序的设计。单片机程序描述如下:
(1)等待PC机初始化,得到帧长、目标ID等信息;
(2)查询CAN总线是否有数据,如果没有则转到(5);
(3)得到可以接收的缓冲区编号;
(4)接收数据。修改状态,放弃当前缓冲区控制权,置有数据位为1,并锁存该状态;
(5)判断PC机方有无数据要发送,如果没有则转到(2);
(6)得到待发送的缓冲区编号;
(7)发送数据。修改状态,放弃当前缓冲区控制权,置有数据位为0,并锁存该状态;
(8)转到(2)。
(3)中得到可接收缓冲区编号的条件是:MCU_FLAG和PC_STATUS的低2位中有一位不同,并且该位表示缓冲区中没有数据(对应的第3或4位为0);(6)得到待发送缓冲区编号的条件是:MCU_FLAG和PC_STATUS的低2位中有一位不同,并且该位表示的缓冲区中有数据。上述程序中的读是从CAN总线读,写是向CAN控制器发送数据;而PC机的写是向单片机写,读是从单片机读。因此二者的程序非常类似,不再重复。
为了提高通信效率,本文做了三方面的工作。首先将板载单片机AT89C52作为适配卡的主控制器,负责数据管理工作,提高了数据传输的速度、稳定性和可靠性,减轻了PC机的处理负担;其次利用双端口RAM作为PC机数据发送和接收的缓冲区,并将双端口RAM映射为PC机内存的一部分,减少了PC发送和接收数据的时间;最后根据双缓冲的思想,把整个缓冲区一分为二,使PC机写数据和CAN适配卡发送数据异步进行,并用锁存器实现互斥访问,进一步提高通信速度和效率。
本文中远程控制器的操作系统为Win98,这是因为Win2000或者XP的实时性并不比Win98好,而且Win98可以对I/O端口直接读写,开发工作量小。
参考文献
1 邬宽明.CAN总线原理与应用系统设计[M].北京:北京航空航天大学出版社,1996
2 吕杜鹃.CAN智能适配卡的设计方案[J].工业控制计算机,2001;(8)
3 杨朝龙.基于双接收缓冲队列的CAN驱动模型设计[J].微计算机信息,2006;(2)
4 傅民仓.基于CAN总线的数据采集系统实现与应用[J].现代电子技术,2006;(2)
5 陈杨杨.CAN总线和DeviceNet通信协议在单片机系统中的应用[J].仪器仪表学报,2005;(2)