本文绝对原创。这是本人实习经过两个星期艰苦探索,艰苦调错摸索出来的。

鸣谢在Baidu上或多或少提供帮助的网友。

特别感谢一下连接的作者。http://www.cnblogs.com/sunev/archive/2012/03/12/2392510.html#2478302

虽然里面的例子不是很稳定,但是通过调整这个例子,再自己研究硬件驱动,我完成我的实习。

使用软件:

在测试的时候可以使用科来数据包生成器来从电脑发包:方便大家使用,我在网盘里给你们个连接

http://pan.baidu.com/share/link?shareid=2267413508&uk=3372569806

在嗅探的时候如果会使用sniffer最好,不会的话我也给个小软件,叫IpTool。基本够用。

http://pan.baidu.com/share/link?shareid=2291917654&uk=3372569806

还有就是7个可能用到的驱动程序。这是我的板子上有的,驱动来源是官方例子。

SRAM_16Bit_512K.rar         http://pan.baidu.com/share/link?shareid=2298119953&uk=3372569806

这是个16Bit 512k的ram。但是由于我的板子上还有个8M的DRAM,我没用这个

Audio_DAC_FIFO.rar           http://pan.baidu.com/share/link?shareid=2302455541&uk=3372569806

这是个音频的模块(有个Audio嘛)

Binary_VGA_Controller.rar   http://pan.baidu.com/share/link?shareid=2303528870&uk=3372569806

这是个视频的模块(VGA)

DM9000A.rar                       http://pan.baidu.com/share/link?shareid=2306257136&uk=3372569806

这是个比较强大的网络模块芯片。我的这个实习主要就是这个芯片

ISP1362.rar                         http://pan.baidu.com/share/link?shareid=2309925263&uk=3372569806

这是个串口芯片。貌似是用来连接USB的

SEG7_LUT_8.rar                 http://pan.baidu.com/share/link?shareid=2313948234&uk=3372569806

这是七段管。玩过电路的肯定不陌生

由于实习没有结束,所以 我就不把工程给你们了。以后再传。而且在测试的时候发现,如果仅仅使用Import的话,一般是不能运行的

本下面的代码设计运行在Quartus II 9.0上和配套的Nios II 9.0 IDE

一、 实现功能;

  1. 实现发包:
  2. 实现收包,获取包的长度
  3. LCD屏幕和七段管显示收发包信息
  4. LCD屏幕显示开发相关说明

二、 DM9000A的相关说明

图表 1DM9000A的功能模块分布

下面DM9000的通用初始化函数

我尽最大的可能解释了一下。但是后面还是有些没看懂,保留原始的注释

unsigned int DM9000_init (void)

{

unsigned int  i;        //这是后面需要用的循环次数控制。用来设置网卡MAC地址

iow(0x1E, 0x01);        //0x1E寄存器为1表示允许输出

iow(0x1F, 0x00);        //0x1F寄存器为0表示激活芯片功能

msleep(5);               //等待2毫秒以上让物理器件上电成功

iow(NCR,  0x03);        //NCR为3是调用软件的变量复位

usleep(20);             //等待10微秒以上以完成软件的变量复位

iow(NCR, 0x00);         //下面一小段代码就是重复执行软件复位。

iow(NCR, 0x03);        //这是为了尽可能的保证复位操作成功

usleep(20);

iow(NCR, 0x00);

iow(0x1F, 0x01);        //0x1F为1表示暂停芯片功能。

iow(0x1F, 0x00);       //这里两行代码是为了重新启动芯片

msleep(10);              //等待上电成功

phy_write(0,PHY_reset);    //初始化芯片状态

usleep(50);                   //等待芯片初始化结束

phy_write(16, 0x404);      //关闭节能模式

phy_write(4, PHY_txab);   /* set PHY TX advertised ability: ALL + Flow_control */

phy_write(0, 0x1200);      //开启自动协调,自动嗅探监测功能

msleep(5);                    //等待功能开启成功

for (i = 0; i < 6; i++)   //将预设的MAC地址输入板卡

iow(16 + i, ether_addr[i]);

iow(ISR, 0x3F);             //ISR一共有3个寄存器,存储中断信息。全部清空

iow(NSR, 0x2C);             //清除阻塞信息

iow(NCR,  NCR_set);        //启用芯片功能,关闭MAC自环路模式

iow(0x08, BPTR_set);  /* BPTR  REG.08  (if necessary) RX Back Pressure Threshold in Half duplex moe only: High Water 3KB, 600 us */

iow(0x09, FCTR_set);  /* FCTR  REG.09  (if necessary) Flow Control Threshold setting High/ Low Water Overflow 5KB/ 10KB */

iow(0x0A, RTFCR_set); /* RTFCR REG.0AH (if necessary) RX/TX Flow Control Register enable TXPEN, BKPM (TX_Half), FLCE (RX) */

iow(0x0F, 0x00);      /* Clear the all Event */

iow(0x2D, 0x80);           //切换LED模式

/* set other registers depending on applications */

iow(ETXCSR, ETXCSR_set); /* Early Transmit 75% */

/* enable interrupts to activate DM9000 ~on */

iow(IMR, INTR_set);   /* IMR REG. FFH PAR=1 only, or + PTM=1& PRM=1 enable RxTx interrupts */

/* enable RX (Broadcast/ ALL_MULTICAST) ~go */

iow(RCR , RCR_set | RX_ENABLE | PASS_MULTICAST);  /* RCR REG. 05 RXEN Bit [0] = 1 to enable the RX machine/ filter */

/* RETURN "DEVICE_SUCCESS" back to upper layer */

return  (ior(0x2D)==0x80) ? DMFE_SUCCESS : DMFE_FAIL;

}

三、 整体实现

1. 硬件部分

CPU采用了NIOS II的标准类型。采用4M的Flash 和8M的SDRAM

采用DM9000A作为网络控制芯片。

使用18个拨动开关和4个按钮作为控制输入。,LCD_16207,七段管 和26个LED灯作为输出。

2. 软件部分

调用了DM9000A和LCD_16207的相关驱动函数,组成了软件驱动部分。

三、 具体实现:

  1. 硬件部分:

(1) 构建CPU模块

用鼠标点击左侧边框的红圈处Nios II Processor,如下图示

图表 1打开SoPC Builder

点击finish,添加cpu_0:

图表 2

再依次次添加三态桥、Ram、Flash、Pio等模块,这都是系统自带的,本实验还需要添加DM9000芯片、七段管、液晶显示屏的驱动,这一模块需要手动添加,将编写好的这几个驱动添加到工程文件夹下,之后在System Contents则能找到该模块,就可以添加进去了。

图表 3 添加IP核

其中需要注意的是,有的模块需要配置参数,例如:

图表 4 配置IP核参数

因为实验板的flash是4M的,所以需要将Address Width(bits)设置成18位的,这都是需要根据具体使用的实验板的型号不同配置不同的参数。

同理, SRAM使用16Bit的

(2) 绑定管脚

回到QuartusII中,新建一个.bdf文件,点击左侧的Symbol Tool的图标,将配置好的cpu拖进来,连接好电路后,根据DE2_pin_assignments.csv修改管脚名称,使每个管脚的名称都要与DE2_pin_assignments.csv文件中左侧的名称相对应。如图.注意:这里添加了一个用来稳频和倍频的锁相环。

图表 5 管脚绑定完成图

双击管脚,即可修改管脚名称,如图:

图表 6  修改管脚名称

管脚绑定完成后,硬件配置部分就完成了。打开NiosII IDE软件,进行软核部分代码的编写。

2. 软件部分

为了实现相关功能,除了要引入相关的驱动程序外,还需要编写一下几个文件

//GetState.h

#ifndef GETSTATE_H_

#define GETSTATE_H_

#endif /*GETSTATE_H_*/

int GetSWState(int i);

//HexToDec.h

#ifndef HEX2DEC_H_

#define HEX2DEC_H_

#endif /*HEX2DEC_H_*/

int Hex2Dec(int hex);

char* int2char(int i);

char* int2str(int i);

以及相关实现文件

//GetState.c

#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <io.h>

#include "system.h"

#include "LCD.h"

//---------------

int GetSWState(int r)

{

int x = IORD(SW_BASE, 0);           //获取SW寄存器的值

int i;

for(i = 0; i < r; i ++)             //获取第r个开关的值

{

x /= 2;

}

return x % 2;

}

//HexToDec.c

#include <stdio.h>

#include "HexToDec.h"

int Hex2Dec(int hex)                   //将10进制的数显示在16进制的屏幕上

{

int g, s, b, q, w, sw, bw, qw, y;

int temp = hex;

int result;

g = temp % 10;  temp /= 10;

s = temp % 10;  temp /= 10;

b = temp % 10;  temp /= 10;

q = temp % 10;  temp /= 10;

w = temp % 10;  temp /= 10;

sw = temp % 10;  temp /= 10;

bw = temp % 10;  temp /= 10;

qw = temp % 10;  temp /= 10;

y = temp /=10;

result = g + 0x10 * s + 0x100 * b + 0x1000 * q + 0x10000 * w + 0x100000 * sw + 0x1000000 * bw + 0x10000000 * qw + 0x100000000 * y;

return result;

}

//----------------------------------------------

char* int2char(int i)              //利用C语言的格式函数将int变成char*

{

char num[10] = {0};

sprintf(num, "%d", i);

return num;

}

//-----------------------------------------------

char* int2str(int i)     //利用C语言的格式函数将int变成char*。但是有结束标志

{

char num[10] = {0};

sprintf(num, "%d\0", i);

return num;

}

//-----------------------------------------------

本程序从某种意义上说也算是一个小系统。Main函数由一下及部分组成:

void ethernet_interrupts()  //负责完成数据包的接收功能

void ShowDescription()      //负责完成开发说明的LCD屏显示

在main函数中除了开始的一些变量初始化,芯片初始化,欢迎界面,然后就是一个while(1)的循环。整体构架如下

数据包接受模块

开发说明显示模块

Main()

{

//DM9000A的初始化判断

//欢迎界面的显示功能

While(1)

{

//亮灯模块

//初始化模块

//开发说明显示模块

//发包模块

//收包模块

//刷新速度控制模块

}

}

//亮灯模块

/*

*   亮灯的实际实现是通过对LED灯的寄存器写入一定的值来实现。

*   具体的函数是使用altera_avalon_pio_regs.h

*   头文件里的IOWR_ALTERA_AVALON_PIO_DATA(BASE,  Value)

*   这个函数的参数分别为寄存器的基地址(BASE), 赋值变量(Value)

*/

for(t = 0; t < 8; t ++)

{

IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE,1<<t);

LCD_Init();

}

//初始化模块

if(GetSWState(0))                      //如果SW[0]为1成立

{

seg7_show(SEG7_LUT_8_0_BASE, 0);   //七段管显示清零

rec_package = 0;                   //收包个数清零

send_package = 0;                  //发包个数清零

rx_len = 0;                        //获取的收包长度清零

last_rx_len = 0;                   //获取的上一个包的长度清零

}

//显示说明模块

if(GetSWState(1))                      //如果SW[1]为1成立

{

ShowDescription();                  //显示说明信息

}

//收包模块

if(GetSWState(17))                      //如果SW[17]为1成立

{

LCD_Line1();                        //LCD写入第一行

tran = TransmitPacket(TXT,0x40);    //发送TXT数组的64个数据

msleep(250);                        //为方式发送失败,暂停250ms

send_package++;                    //发包个数统计

//初始化在LCD屏幕显示的字符

s[0] = 's';   s[1] = 'e';   s[2] = 'n';   s[3] = 'd';

s[4] = ':';   s[5] = '\0';  s[6] = '\0';  s[7] = '\0';

s[8] = '\0';  s[9] = '\0';  s[10] = '\0'; s[11] = '\0';

s[12] = '\0'; s[13] = '\0'; s[14] = '\0'; s[15] = '\0';

/*

*   将发送的数据包个数拼接在S(一个Char[16]的字符数组)后.

*   同时使用了int2str自定义函数。可以把整型变成char*类型

*/

strcat(s, int2str(send_package));

LCD_Show_Text(s);                   //LCD屏幕显示”send:[发包个数]”

}

else                                   //如如果SW[17]为0成立

{

LCD_Line1();                       //切换为第一行显示

/*

*   动态显示

*   PushSW17ToSend

*   PushSW17ToSend |

*   PushSW17ToSend /

*   PushSW17ToSend -

*/

if(t%4 == 0)

LCD_Show_Text("PushSW17ToSend -");

if(t%4 == 1)

LCD_Show_Text("PushSW17ToSend ");

if(t%4 == 2)

LCD_Show_Text("PushSW17ToSend |");

if(t%4 == 3)

LCD_Show_Text("PushSW17ToSend /");

}

//收包模块

if(GetSWState(16))                     //如如果SW[16]为1成立

{

ethernet_interrupts();             //调用收包模块

/*

*   这是对LCD输出字符的初始化

*/

r[0] = 'r';   r[1] = 'e';   r[2] = 'c';   r[3] = 'e';

r[4] = ':';   r[5] = '\0';  r[6] = '\0';  r[7] = '\0';

r[8] = '\0';  r[9] = '\0';  r[10] = '\0'; r[11] = '\0';

r[12] = '\0'; r[13] = '\0'; r[14] = '\0'; r[15] = '\0';

LCD_Line2();                        //切换到第二行显示

strcat(r, int2str(rec_package));    //将收到的包数拼接到输出字符数组上

LCD_Show_Text(r);                   //在LCD屏幕显示

}

else                                   //如果SW[16]为0成立.功能同发包模块

{

LCD_Line2();

if(t%4 == 0)

LCD_Show_Text("PushSW16ToRece -");

if(t%4 == 1)

LCD_Show_Text("PushSW16ToRece ");

if(t%4 == 2)

LCD_Show_Text("PushSW16ToRece |");

if(t%4 == 3)

LCD_Show_Text("PushSW16ToRece /");

}

//调速模块

/*

*SW[2]-SW[15]开关,如果有一个为1,则等待时间缩短20ms,为0增加20ms.

*/

if(GetSWState(2))    {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(3))    {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(4))    {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(5))    {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(6))    {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(7))    {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(8))    {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(9))    {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(10))   {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(11))   {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(12))   {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(13))   {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(14))   {msleep(delay_short);}

else                 {msleep(delay_long);}

if(GetSWState(15))   {msleep(delay_short);}

else                 {msleep(delay_long);}

//七段管显示模块

/*

*   将8位的七段管按照 发包个数(2位) 收包个数(2位) 收包长度(4位)显示.

*   同时有10*  转成16进制的显示函数

*/

seg7_show(SEG7_LUT_8_0_BASE, Hex2Dec(last_rx_len + rec_package % 100 * 10000 + send_package % 100 * 1000000));

//收包模块

void ethernet_interrupts()

{

/*

*      ReceivePacket函数是DM9000A驱动自带函数。

*      如果收包成功,返回0.同时rx_len值为收到包的长度,包的信息放入RXT中

*/

aaa=ReceivePacket (RXT,&rx_len);

if(rx_len != 0) last_rx_len = rx_len;

printf("receive = %d(0) ", aaa);

if(!aaa)

{

rec_package++;

printf("\n\nReceive Packet Length = %d ",rx_len);

}

seg7_show(SEG7_LUT_8_0_BASE, Hex2Dec(last_rx_len + rec_package % 100 * 10000 + send_package % 100 * 1000000));

}

基于NIOS 2 的网络通信(使用cyclone II EP2C35F672C6)【图片不能显示,正在处理中】相关推荐

  1. 基于 Nios II 的串口打印和流水灯设计【使用 Quartus 软件】【掌握 SOPC 开发流程】

    目录 一.前言 二.实验步骤 第一步:硬件部分设计 1)建立新项目 2)进行 Qsys 系统设计 3)完成 Qsys 设计的后续工作 4)原理图设计 5)编译工程及物理针脚分配. 第二步:软件部分设计 ...

  2. 基于NIOS II的液晶显示设计——自定义图形库

    基于NIOS II的液晶显示设计--自定义图形库 下面是我写的简单图形库 // graphics.h / #ifndef GRAPHICS_H_ #define GRAPHICS_H_ #includ ...

  3. HDMI系列之一:基于Nios II的HDMI显示图片

    一休哥将在本文中介绍一个基于Nios II的HDMI显示图片的工程.我将主要分三个部分来介绍这一工程,从而实现工程效果. 1. Nios II的常规使用套路 2. 自定义HDMI IP核的制作 3. ...

  4. android 网络通信方式,Android中基于TCP协议的网络通信

    一.Android网络简介 Android与服务器的通信方式主要有两种,一种是Http通信,另一种是Socket通信. HTTP通信:Android中内置HttpClient,这样可以发方便的发送Ht ...

  5. python异步框架twisted_twisted是python实现的基于事件驱动的异步网络通信构架。

    网:https://twistedmatrix.com/trac/ http://www.cnblogs.com/wy-wangyan/p/5252271.html What is Twisted? ...

  6. Cyclone II FPGA系列简介(备忘)

    Altera? Cyclone? II 采用全铜层.低K值.1.2伏SRAM工艺设计,裸片尺寸被尽可能最小的优化.采用300毫米晶圆,以TSMC成功的90nm工艺技术为基础,Cyclone II 器件 ...

  7. 转载]Cyclone II JTAG ASP 配置下载程序

    原文:http://blog.sina.com.cn/s/blog_4739958a0100irp7.html 首先,还是那句话,电脑上写好程序.pof文件直接通过JTAG写到FPGA SRAM里,掉 ...

  8. Java学习系列(十八)Java面向对象之基于UDP协议的网络通信

    UDP协议:无需建立虚拟链路,协议是不可靠的. A节点以DatagramSocket发送数据包,数据报携带数据,数据报上还有目的目地地址,大部分情况下,数据报可以抵达:但有些情况下,数据报可能会丢失 ...

  9. Java学习系列(十六)Java面向对象之基于TCP协议的网络通信

    TCP/IP的网络分层模型:应用层(HTTP/FTP/SMTP/POPS...),传输层(TCP协议),网络层(IP协议,负责为网络上节点分配唯一标识),物理层+数据链路层). IP地址用于标识网络中 ...

最新文章

  1. Web运行控制台输出乱码解决总结
  2. 【数据结构与算法】之深入解析“买卖股票的最好时机III”的求解思路与算法示例
  3. 5分钟内Google App Engine上的Vaadin App
  4. 前端图片canvas,file,blob,DataURL等格式转换
  5. Sublime Text添加插入带当前时间说明
  6. java中gradlew 命令_gradle命令学习
  7. node soket.io + express + vue-soket.io 之间实现通信
  8. 解决go get下载包失败问题
  9. java.math.BigInteger cannot be cast to java.lang.Long
  10. 拼多多运营模式分析 | 如何杀出电商重围?
  11. selenium之qq邮箱登录-发邮件
  12. android viewgroup点击变色,Android ViewGroup点击效果(背景色)
  13. 大佬们抖音带货流水都过亿 普通人有什么抖音变现的好方式
  14. 系统监控的四个黄金指标
  15. 字符串逆序输出c语言,5、输入一个字符串,对该字符串进行逆序,输出逆序后的字符串。...
  16. 内涵TV段子,价值500元的dz内涵笑话商业源码
  17. 英文版windows10记事本等中文显示乱码
  18. i7处理器好吗_买电脑一定买i7?i7 比 i5 新?希望你千万不要中奸商的圈套
  19. 广告竞价策略:GFP,GSP,VCG
  20. RANSAC 激光雷达地面检测 (1)

热门文章

  1. python怎么爬取电影海报_豆瓣top250海报原图爬取
  2. SitePoint Podcast#142:2011年最后一个小组
  3. AWS亚马逊实战-(移动端直传S3)服务器端调用AWS STS生成用户临时凭证上传至S3
  4. stm32驱动ov7670 数据转BMP格式再转JPEG存储
  5. 一个简易网络嗅探器的实现
  6. 系统启动U盘制作全过程详解
  7. 功能测试和兼容性测试
  8. ubuntu18.04 openni2和nite2配置KinectV1(XBOX360)
  9. SSPU-BBS中的邮箱认证
  10. 故障隔离率lru_利用电网阻尼率的精确测量实现配网线路绝缘状态实时监控