|
1
简单的说,在REG_WR的上升沿将数据(DataOutput)写入指定寄存器(RegAddress)中,完成写寄存器的操作。在REG_RD为高的时候驱动指定寄存器(RegAddress)中的数据到DataInput完成读寄存器的操作。
PC机的操作用C++/CLI将FTDI的驱动封装成.NET类型UsbDevice,提供基本的操作函数完成读写。同时定义对寄存器的操作序列UsbRegisterOperation用来具体的寄存器操作。
示例:
例如在Cyclone外接一32KB的RAM,在内部定义寄存器:
MemoryAddress_H 存储器地址高8位
MemoryAddress_L 存储器地址低8位
MemoryData_Write 数据写入寄存器
MemoryData_Read 数据读取寄存器
MemoryControl 存储器控制寄存器
其中MemoryControl 存储器控制寄存器有如下位定义:
第6位:Enable,使能片外RAM,相当于拉低RAM的CS引脚。
第4位:Write,RAM写入信号,在Write的上升沿写MemoryData_Write中的数据到地址MemoryAddress中。
第5位:Read,RAM读取信号,在Read为高时,RAM驱动地址MemoryAddress中的数据到MemoryData_Read中。
根据这样的寄存器定义可以写出相应的控制代码。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace Device {
/// <summary>
/// 寄存器操作序列
/// </summary>
public class UsbRegisterOperation : List<byte> {
/// <summary>
/// 写寄存器
/// </summary>
/// <param name="Address"></param>
/// <param name="Data"></param>
public void Write(IConvertible Address, IConvertible Data) {
Add((byte)(0x80 | Address.ToByte(null)));
Add(Data.ToByte(null));
}
/// <summary>
/// 写寄存器
/// </summary>
/// <param name="Address"></param>
/// <param name="Data"></param>
public void Write(IConvertible Address, byte Data) {
Add((byte)(0x80 | Address.ToByte(null)));
Add(Data);
}
/// <summary>
/// 读寄存器
/// </summary>
/// <param name="Address"></param>
public void Read(IConvertible Address) {
Add((byte)(0x7F & Address.ToByte(null)));
}
}
/// <summary>
/// TestDevice 电路板
/// </summary>
public class TestDevice : UsbDevice {
/// <summary>
/// 寄存器定义。
/// </summary>
public enum Regs : byte {
MemoryAddress_H = 17,
MemoryAddress_L = 18,
MemoryData_Write = 21,
MemoryData_Read = 20,
MemoryControl = 19,
}
/// <summary>
/// 寄存器位定义。
/// </summary>
public enum MemoryControl : byte {
Enable = (1 << 6),
Write = (1 << 4),
Read = (1 << 5)
}
/// <summary>
/// 打开设备,如果没有设备连接到计算机将引发异常。
/// </summary>
public void Open() {
foreach(DeviceInfo Info in UsbDevice.GetDeviceList()) {
if(Info.Description == "TestDevice") {
base.Open(Info.Index);
return;
}
}
throw new Exception("NO DEVICE");
}
/// <summary>
/// 写外部RAM。
/// </summary>
/// <param name="Address">起始地址</param>
/// <param name="Data"></param>
public void WriteMEM(ushort Address, byte[] Data) {
UsbRegisterOperation RegOp = new UsbRegisterOperation();
RegOp.Write(Regs.MemoryControl, MemoryControl.Enable);
for(int i = 0; i < Data.Length; i++) {
RegOp.Write(Regs.MemoryAddress_H, (byte)((Address + i) >> 8));
RegOp.Write(Regs.MemoryAddress_L, (byte)(Address + i));
RegOp.Write(Regs.MemoryData_Write, Data);
RegOp.Write(Regs.MemoryControl, MemoryControl.Enable | MemoryControl.Write);
RegOp.Write(Regs.MemoryControl, MemoryControl.Enable);
}
RegOp.Write(Regs.MemoryControl, 0x00);
WriteByte(RegOp.ToArray());
}
/// <summary>
/// 读取外部RAM。
/// </summary>
/// <param name="Address">起始地址</param>
/// <param name="Size">读取的长度</param>
/// <returns></returns>
public byte[] ReadMEM(ushort Address, ushort Size) {
UsbRegisterOperation RegOp = new UsbRegisterOperation();
RegOp.Write(Regs.MemoryControl, MemoryControl.Enable | MemoryControl.Read);
for(int i = 0; i < Size; i++) {
RegOp.Write(Regs.MemoryAddress_H, (byte)((Address + i) >> 8));
RegOp.Write(Regs.MemoryAddress_L, (byte)((Address + i)));
RegOp.Read(Regs.MemoryData_Read);
}
RegOp.Write(Regs.MemoryControl, 0x00);
WriteByte(RegOp.ToArray());
return ReadByte(Size);
}
}
}
这里是状态机的源代码(Verilog):点击此处下载ourdev_237216.rar(文件大小:1K)
这里是状态机的源代码的源代码(Active-HDL状态图描述,Verilog代码由其自动生成):点击此处下载ourdev_237217.rar(文件大小:6K)
这里是状态的PDF文档,方便没Active-HDL的观看:点击此处打开ourdev_237218.pdf(文件大小:57K)
C++/CLI封装的FTDI驱动:点击此处下载ourdev_237219.rar(文件大小:2.37M) |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|