集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 2084|回复: 3

通过USB控制FPGA

[复制链接]
老怪甲 该用户已被删除
老怪甲 发表于 2010-5-13 10:22:38 | 显示全部楼层 |阅读模式
简单的说,在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);
                }
        }
}
front 发表于 2013-2-17 21:11:29 | 显示全部楼层
感谢版主无私分享
fpga_feixiang 发表于 2022-5-23 21:14:15 | 显示全部楼层
6666666666666
dameihuaxia 发表于 2022-5-24 14:11:23 | 显示全部楼层
串口通信基本知识
http://www.fpgaw.com/forum.php?m ... 0&fromuid=58166
(出处: fpga论坛|fpga设计论坛)
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2025-6-12 17:42 , Processed in 0.067388 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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