基于NIOS 2 的网络通信(使用cyclone II EP2C35F672C6)【图片不能显示,正在处理中】
本文绝对原创。这是本人实习经过两个星期艰苦探索,艰苦调错摸索出来的。
鸣谢在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
一、 实现功能;
- 实现发包:
- 实现收包,获取包的长度
- LCD屏幕和七段管显示收发包信息
- 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) 构建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)【图片不能显示,正在处理中】相关推荐
- 基于 Nios II 的串口打印和流水灯设计【使用 Quartus 软件】【掌握 SOPC 开发流程】
目录 一.前言 二.实验步骤 第一步:硬件部分设计 1)建立新项目 2)进行 Qsys 系统设计 3)完成 Qsys 设计的后续工作 4)原理图设计 5)编译工程及物理针脚分配. 第二步:软件部分设计 ...
- 基于NIOS II的液晶显示设计——自定义图形库
基于NIOS II的液晶显示设计--自定义图形库 下面是我写的简单图形库 // graphics.h / #ifndef GRAPHICS_H_ #define GRAPHICS_H_ #includ ...
- HDMI系列之一:基于Nios II的HDMI显示图片
一休哥将在本文中介绍一个基于Nios II的HDMI显示图片的工程.我将主要分三个部分来介绍这一工程,从而实现工程效果. 1. Nios II的常规使用套路 2. 自定义HDMI IP核的制作 3. ...
- android 网络通信方式,Android中基于TCP协议的网络通信
一.Android网络简介 Android与服务器的通信方式主要有两种,一种是Http通信,另一种是Socket通信. HTTP通信:Android中内置HttpClient,这样可以发方便的发送Ht ...
- python异步框架twisted_twisted是python实现的基于事件驱动的异步网络通信构架。
网:https://twistedmatrix.com/trac/ http://www.cnblogs.com/wy-wangyan/p/5252271.html What is Twisted? ...
- Cyclone II FPGA系列简介(备忘)
Altera? Cyclone? II 采用全铜层.低K值.1.2伏SRAM工艺设计,裸片尺寸被尽可能最小的优化.采用300毫米晶圆,以TSMC成功的90nm工艺技术为基础,Cyclone II 器件 ...
- 转载]Cyclone II JTAG ASP 配置下载程序
原文:http://blog.sina.com.cn/s/blog_4739958a0100irp7.html 首先,还是那句话,电脑上写好程序.pof文件直接通过JTAG写到FPGA SRAM里,掉 ...
- Java学习系列(十八)Java面向对象之基于UDP协议的网络通信
UDP协议:无需建立虚拟链路,协议是不可靠的. A节点以DatagramSocket发送数据包,数据报携带数据,数据报上还有目的目地地址,大部分情况下,数据报可以抵达:但有些情况下,数据报可能会丢失 ...
- Java学习系列(十六)Java面向对象之基于TCP协议的网络通信
TCP/IP的网络分层模型:应用层(HTTP/FTP/SMTP/POPS...),传输层(TCP协议),网络层(IP协议,负责为网络上节点分配唯一标识),物理层+数据链路层). IP地址用于标识网络中 ...
最新文章
- Web运行控制台输出乱码解决总结
- 【数据结构与算法】之深入解析“买卖股票的最好时机III”的求解思路与算法示例
- 5分钟内Google App Engine上的Vaadin App
- 前端图片canvas,file,blob,DataURL等格式转换
- Sublime Text添加插入带当前时间说明
- java中gradlew 命令_gradle命令学习
- node soket.io + express + vue-soket.io 之间实现通信
- 解决go get下载包失败问题
- java.math.BigInteger cannot be cast to java.lang.Long
- 拼多多运营模式分析 | 如何杀出电商重围?
- selenium之qq邮箱登录-发邮件
- android viewgroup点击变色,Android ViewGroup点击效果(背景色)
- 大佬们抖音带货流水都过亿 普通人有什么抖音变现的好方式
- 系统监控的四个黄金指标
- 字符串逆序输出c语言,5、输入一个字符串,对该字符串进行逆序,输出逆序后的字符串。...
- 内涵TV段子,价值500元的dz内涵笑话商业源码
- 英文版windows10记事本等中文显示乱码
- i7处理器好吗_买电脑一定买i7?i7 比 i5 新?希望你千万不要中奸商的圈套
- 广告竞价策略:GFP,GSP,VCG
- RANSAC 激光雷达地面检测 (1)