DE2-115串口通信

news2025/1/19 11:37:27

目录

  • 一、 内容概要
  • 二、 Hello Nios-II
    • 2.1 Nios-II编程
      • 2.1.1 硬件
        • Ⅰ 搭建环境
        • Ⅱ 编写代码
      • 2.1.2 软件
      • 2.1.3 烧录
        • Ⅰ硬件
        • Ⅱ 软件
    • 2.2 verilog编程
  • 三、 心得体会

一、 内容概要

  1. 分别用Verilog和Nios软件编程, 实现DE2-115开发板串口输出“Hello Nios-II”字符到笔记本电脑串口助手。

二、 Hello Nios-II

2.1 Nios-II编程

2.1.1 硬件

Ⅰ 搭建环境

新建工程,选择开发板在这里插入图片描述
在这里插入图片描述
进行模块添加和连接
在这里插入图片描述

分配地址
在这里插入图片描述
Generate

在这里插入图片描述

Ⅱ 编写代码

新建Verilog文件

module uart(
	input clk,
	input reset_n,
	//uart的接收和发送端
	input rxd,//接收
	output txd//发送
);
endmodule

配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
进入qip文件的第一个verilog文件
在这里插入图片描述
根据模块信息,在顶层文件里增加:

hello_nioII u0 (
        .clk_clk       (clk),       //   clk.clk
        .reset_reset_n (reset_n), // reset.reset_n
        .uart_rxd      (rxd),      //  uart.rxd
        .uart_txd      (txd)       //      .txd
    );

完整代码为:

module uart(
	input clk,
	input reset_n,
	//uart的接收和发送端
	input rxd,//接收
	output txd//发送
);

hello_nioII u0 (
        .clk_clk       (clk),       //   clk.clk
        .reset_reset_n (reset_n), // reset.reset_n
        .uart_rxd      (rxd),      //  uart.rxd
        .uart_txd      (txd)       //      .txd
    );

endmodule

编译
配置管脚
在这里插入图片描述

2.1.2 软件

在这里插入图片描述
在这里插入图片描述
修改hello_world.c

#include <stdio.h>
#include "unistd.h"
#include "system.h"
#include "alt_types.h"
#include "altera_avalon_uart_regs.h"
#include "sys\alt_irq.h"

alt_u8 txdata=0;
alt_u8 rxdata=0;

//UART中断服务函数
void IRQ_UART_Interrupts(){
	rxdata = IORD_ALTERA_AVALON_UART_RXDATA(UART_BASE);//将rxdata寄存器中存储的值读入变量rxdata中
	txdata = rxdata;//串口自收发,将变量rxdata的值赋给txdata
	while(!(IORD_ALTERA_AVALON_UART_STATUS(UART_BASE)& ALTERA_AVALON_UART_STATUS_TRDY_MSK));
	//查询发送准备接收信号,如果没有准备好,则等待
	IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE,txdata);//发送准备好,发送txdata
}

//中断初始化函数
void IRQ_init()
{
	//清除状态寄存器
	IOWR_ALTERA_AVALON_UART_STATUS(UART_BASE, 0);
	//使能接收准备中断,给控制寄存器相应位写1
	IORD_ALTERA_AVALON_UART_CONTROL(UART_BASE);

	alt_ic_isr_register(
			UART_IRQ_INTERRUPT_CONTROLLER_ID,//注册ISR
			UART_IRQ,//中断控制器标号,从system.h复制
			IRQ_UART_Interrupts,//UART中断服务函数
			0x0,//指向与设备驱动实例相关的数据结构体
			0x0);//flags,保留未用
}

int main()
{
  /*while(1){
	  IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE, "hello world!\n");
	  int i=0;
	  while(i<5000)
	  {
		  i++;
	  }
  }*/
  IRQ_init();
  while(1);
  return 0;
}

配置

在这里插入图片描述
在这里插入图片描述
报错:
在这里插入图片描述
若遇到类似情况,请按住ctrl然后左键单击#include 里面的system.h,找到UART部分
在这里插入图片描述
发现是URAT_0_BASE,把helloworld.c里面的UART_BASE修改为URAT_0_BASE就行

2.1.3 烧录

Ⅰ硬件

在这里插入图片描述在这里插入图片描述

Ⅱ 软件

在这里插入图片描述

2.2 verilog编程

编译烧录以下代码就行

`timescale  1ns/1ns

module  rs232
(
    input   wire    sys_clk     ,    //系统时钟50MHz
    input   wire    sys_rst_n   ,   //全局复位
    input   wire    rx          ,   //串口接收数据
    
    output  wire    tx              //串口发送数据
);

//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//parameter define
parameter   UART_BPS    =   20'd9600        ,   //比特率
            CLK_FREQ    =   26'd50_000_000  ;   //时钟频率

localparam  BAUD_CNT_MAX    =   CLK_FREQ/UART_BPS   ;
//wire  define
wire            en_h_flag;
wire    [7:0]   po_data;    //接收的数据
wire            po_flag;    //接收完1字节数据标志位,高电平有效
wire            flag;       //识别到接收数据与密码对应标志位
wire            tx_flag;    //发送完1字节数据标志位,高电平有效
reg     [39:0]  datain_reg; //存储接收的数据,5字节
reg     [47:0]  dataout_reg;//存储的要发送的数据,6字节
reg     [1:0]   state;      //状态位
reg     [7:0]   data_tx;    //发送的1字节数据
reg             en_tx;      //发送允许标志位
reg     [2:0]   tx_cnt;     //发送字节计数器,发送6个后置0
reg             en;         //发送控制开关
reg     [12:0]  baud_cnt;   //收到发送成功的tx_flag后延迟1个波特
reg             bit_flag;   //计满1baud有效
reg             work;       //波特计数器baud_cnt有效
//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//
//------------------------ uart_rx_inst ------------------------
uart_rx
#(
    .UART_BPS    (UART_BPS  ),  //串口波特率
    .CLK_FREQ    (CLK_FREQ  )   //时钟频率
)
uart_rx_inst
(
    .sys_clk    (sys_clk    ),  //input             sys_clk
    .sys_rst_n  (sys_rst_n  ),  //input             sys_rst_n
    .rx         (rx         ),  //input             rx
            
    .po_data    (po_data    ),  //output    [7:0]   po_data
    .po_flag    (po_flag    )   //output            po_flag
);
always@(posedge sys_clk or negedge sys_rst_n)
    if(!sys_rst_n)
        en <= 1'b1;
    else if(en_h_flag)
        en <= 1'b1;
    else if(tx_cnt>=3'd5)
        en <= 1'b0;   
//接收数据寄存
always@(posedge sys_clk or negedge sys_rst_n)
    if(!sys_rst_n)
        datain_reg <= 40'd0;
    else if(po_flag)
        datain_reg <= {datain_reg[31:0],po_data[7:0]};
        
//接收到tx_flag后,延迟一个baud时间再发送下一个
always@(posedge sys_clk or negedge sys_rst_n)
    if(!sys_rst_n)
        work <= 1'b0;
    else if(tx_flag)
        work <= 1'b1;
    else if(state != 2'd2)
        work <= 1'b0;

always@(posedge sys_clk or negedge sys_rst_n)
    if(!sys_rst_n)
        baud_cnt <= 13'd0;
    else if((baud_cnt == BAUD_CNT_MAX - 1) || en_tx)
        baud_cnt <= 13'b0;
    else if(work)
        baud_cnt <= baud_cnt + 1'd1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(!sys_rst_n)
        bit_flag <= 1'b0;
    else if(baud_cnt == BAUD_CNT_MAX - 1)
        bit_flag <= 1'b1;
    else if(state != 2'd2) 
        bit_flag <= 1'b0;

                              //hello的ASCII码
assign flag = (datain_reg == 40'h68656c6c6f)? 1'b1:1'b0;

always@(posedge sys_clk or negedge sys_rst_n)
    if(!sys_rst_n)
        begin
            state <= 2'd0;
            dataout_reg <= 48'h6e692c68616f;//ni,hao的ASCII码
            data_tx <= 8'd0;
            en_tx <= 1'b0;
            tx_cnt <= 3'd0;
        end
    else
        case(state)
            2'd0:
                begin
                    if(flag && en)
                        state <= 2'd1;
                    else
                        state <= 2'd0;
                end
            2'd1://发送数据
                begin
                    state <= 2'd2;
                    data_tx <= dataout_reg[47:40];
                    en_tx <= 1'b1;
                    dataout_reg <= dataout_reg << 8;
                end            
            2'd2://等待数据发送完成,并计数+1
                begin
                    if(bit_flag)
                        begin
                            if(tx_cnt>=3'd5)begin
                                state <= 2'd0;
                                tx_cnt <= 3'd0;                         
                            end
                            else begin
                                state <= 2'd1;
                                tx_cnt <= tx_cnt + 1'd1;                            
                            end 
                        end
                    else
                        begin
                            en_tx <= 1'b0;
                            state <= 2'd2;
                        end
                end 
            default : state <= 2'd0;
        endcase            
//------------------------ uart_tx_inst ------------------------
uart_tx
#(
    .UART_BPS    (UART_BPS  ),  //串口波特率
    .CLK_FREQ    (CLK_FREQ  )   //时钟频率
)
uart_tx_inst
(
    .sys_clk    (sys_clk    ),  
    .sys_rst_n  (sys_rst_n  ),  
    .pi_data    (data_tx    ),  
    .pi_flag    (en_tx      ),     
    
    .tx         (tx         ),   
    .tx_flag    (tx_flag    )
);

endmodule


三、 心得体会

通过本次实验,我更深刻地理解了Nios II软件编程和Verilog硬件编程在FPGA设计中的应用和区别。Nios II软核提供了一个通用的处理器环境,可以使用高级语言如C/C++进行编程,易于理解且开发效率较高。而Verilog则是一种硬件描述语言,它允许我直接控制硬件行为,更适合于对性能要求较高的应用。

硬件环境的搭建与配置
在Nios II编程部分,我学会了如何使用Quartus软件和Platform Designer(或Qsys)来搭建硬件环境,包括选择适当的开发板、添加必要的硬件模块(如Nios II处理器、存储器、UART等),并进行模块间的连接和参数配置。这个过程对理解整个系统的硬件架构非常有帮助。

软件编程与硬件的交互
在软件编程部分,我学习了如何在Nios II软核上编写C语言程序,并通过HAL库函数来控制硬件设备,如UART进行串口通信。同时,我也意识到了软件编程中对硬件地址和中断控制器标识符的正确引用的重要性。

遇到的问题及解决
在实验过程中,我遇到了几个问题,包括硬件地址未定义、中断控制器标识符未声明等。通过查阅文档、检查硬件设置和代码,我学会了如何定位并解决这些问题。这些经验对于我未来解决类似的问题非常宝贵。

Verilog编程实践
在Verilog编程部分,我编写了一个简单的UART收发模块,并实现了基本的串口通信功能。这个过程加深了我对UART工作原理和Verilog语言的理解。

总体来说,这次实验不仅增强了我的动手实践能力,也加深了我对FPGA设计、Nios II软核开发以及跨平台串口通信等知识的理解。通过解决实际遇到的问题,我获得了宝贵的学习和成长经验。未来,我希望能将这些知识和技能应用到更复杂的项目中,以进一步提升我的专业技能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1682321.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用宝塔面板搭建nodejs网站(不使用pm2)

利用宝塔面板搭建nodejs网站&#xff08;不使用pm2&#xff09; 1. 准备代码文件2. 将代码上传至云主机3. 云主机配置3.1 绑定域名3.2 利用面板配置node环境3.3 利用面板增加node项目 4. 打开端口 暂时只演示http的。https类似&#xff0c;需要添加证书。 1. 准备代码文件 清单…

SpringBoot环境隔离Profiles

前言 通常我们开发不可能只有一个生产环境&#xff0c;还会有其它的开发&#xff0c;测试&#xff0c;预发布环境等等。为了更好的管理每个环境的配置项&#xff0c;springboot也提供了对应的环境隔离的方法。 直接上干货 知识点 激活环境方法 1&#xff0c;在application…

伪头部校验

本章问题 UDP和TCP的伪首部只用于计算校验和&#xff0c;在UDP和TCP的报文中是不存在的&#xff0c;为什么要引入伪首部呢&#xff1f;为什么伪首部的要有这些字段&#xff1f;这里我们就先看一下TCP和UDP的首部格式。 TCP和UDP首部 源端口目的端口&#xff1a;是0-65535任…

CSP认证刷题笔记(3)最大矩形(13年CSP认证第三题)

文章目录 题目描述基本思路求解代码 题目描述 在横轴上放了n个相邻的矩形&#xff0c;每个矩形的宽度是1&#xff0c;而第i&#xff08;1≤i≤n&#xff09;个矩形的高度是 hi。这n个矩形构成了一个直方图。例如&#xff0c;下图中六个矩形的高度就分别是3,1,6,5,2,3。 请找出…

聚苯并咪唑(PBI)为超高性能工程塑料 未来应用前景较好

聚苯并咪唑&#xff08;PBI&#xff09;为超高性能工程塑料 未来应用前景较好 聚苯并咪唑&#xff08;简称PBI&#xff09;&#xff0c;是一类以苯并咪唑基团作为结构重复单元的杂环聚合物。聚苯并咪唑不溶于水&#xff0c;溶于强极性溶剂&#xff0c;具有耐高温、耐腐蚀、抗辐…

学习C语言的重要性以及如何学好

配套视频&#xff1a;https://www.bilibili.com/video/BV1kw4m1Q7AV/?spm_id_from333.999.0.0 一、C语言在互联网领域重要的开源项目 https://github.com/mysql/mysql-server 数据库开源项目【互联网重型开源项目】 编程语言&#xff1a;C/C/ASM 部分汇编代码 开源项目核心…

Verilog基础语法——条件语句if-else与case

Verilog基础语法——条件语句case、if-else 写在前面一、if-else语句二、case语句2.1 case语句2.2 casez语句2.3 casex语句 写在后面 写在前面 在Verilog语法中&#xff0c;常用的条件语句有if-else语句和case语句&#xff0c;用于判断条件是否为真&#xff0c;并执行判断条件后…

使用docker安装doccano

使用docker安装doccano 1 介绍 数据标注的工具比较多&#xff0c;比较出名的有Doccano、Label Studio等。 Label Studio &#xff1a;图像标注、文本标注、音频标注、视频标注、时间序列标注&#xff0c;功能比较多。 Doccano&#xff1a;主要是针对文本的标注&#xff0c;…

平芯微PW4057H中文规格书

产品概述&#xff08;百度翻译&#xff09; PW4057H 是可以通过外部电阻编程的恒流/恒压充电的充电管理电路。该器件内部包括功率晶体管应用时不需要外部的电流检测电阻和阻流二极管。 PW4057H 只需要极少的外围元器件&#xff0c;并且符合 USB 总线技术规范&#xff0c;非常适…

英睿达硬盘数据恢复方法:从丢失到找回的详细指南

在数字化时代&#xff0c;硬盘作为我们存储重要数据的关键设备&#xff0c;承载着大量的个人、工作甚至商业信息。然而&#xff0c;无论是由于意外删除、格式化、病毒感染还是硬件故障&#xff0c;硬盘数据丢失的情况时有发生。英睿达硬盘作为市场上的知名品牌&#xff0c;其数…

后仿真中的必懂VCS仿真选项之 +ignorempcond

当多个输入同时改变时&#xff0c;VCS支持延迟注释。它忽略条件检查&#xff0c;并从适用的延迟中插入最小的延迟。 当多个输入同时改变时&#xff0c;它们会对特定的输出信号产生影响。 如果没有匹配的条件弧线从输入(切换)延伸到输出&#xff0c;那么VCS不会标注零延迟。 …

ITSM的服务台如何让工作更流畅

在现代企业的信息技术管理框架内&#xff0c;IT服务管理&#xff08;IT Service Management, ITSM&#xff09;体系扮演着至关重要的角色&#xff0c;而其中的服务台则是这一复杂体系的心脏地带。服务台不仅仅是解答技术疑问的一线窗口&#xff0c;更是企业IT运维效率与用户满意…

STM32_IIC通信

IIC通信 • I2C&#xff08;Inter IC Bus&#xff09;是由Philips公司开发的一种通用数据总线 • 两根通信线&#xff1a;SCL&#xff08;串行时钟线&#xff09;、SDA&#xff08;串行数据线&#xff09; • 同步&#xff0c;半双工 • 带数据应答 • 支持总线挂载多…

C++ 程序员常用的VScode的插件

vscode中好用的插件 Better CommentsBookmarksC/C ThemeChinese (Simplified) (简体中文) Language Pack for Visual Studio CodeclangdClang-FormatCodeLLDBCMakeCMake ToolsCode RunnerCode Spell CheckerCodeSnapColor Highlightvscode-mindmapDraw.io IntegrationError Len…

VirtualBox虚拟机串口通信

主机&#xff1a;Win11 VirtualBox: 7.0 两台Guest虚拟机: CentOS 现在希望两台CenOS虚拟机能通过串口通信。 设置前先关闭两台虚拟机。 设置方式就是在VirtualBox的设置里面设置串口&#xff0c;需要注意的是其中一台不勾选“连接至现有通道或套接字”&#xff0c;另外一…

分享我经常用的一个图片下载插件,不会写爬虫代码也能随意下载图片

更多精彩内容在公众号。 ImageAssistant&#xff08;图片助手&#xff09;是一款专为Chrome浏览器设计的扩展程序&#xff0c;它具备强大的网页图片处理功能。以下是关于ImageAssistant的一些主要特点和功能&#xff1a; 批量下载图片&#xff1a;ImageAssistant的核心功能之一…

什么是蜜罐,在当前网络安全形势下,蜜罐能提供哪些帮助

在当前的互联网时代&#xff0c;网络安全威胁日益严峻&#xff0c;攻击手段层出不穷。为了应对这些威胁&#xff0c;网络安全专家们不断探索新的防御手段&#xff0c;在过去的几年里&#xff0c;一种更加积极主动的网络安全方法正在兴起。蜜罐技术便是这样一种备受瞩目的主动防…

GPT大模型不再遥不可及:本地化部署让每个人都能拥有

本地化部署是GPT发展的一个趋势。 本地化部署指的是将大模型部署在用户自己的设备上&#xff0c;而不是依赖于云服务商提供的接口。本地化部署有以下几个优势&#xff1a; 数据完全私有化&#xff0c;降低数据丢失和泄露风险&#xff0c;对数据安全性和私密性有保障。 降低使…

uniapp微信小程序使用vscode代替HBuilderX开发uniapp微信小程序并且vscode改动代码微信开发者工具能实时更新

前言 最近公司开发新的小程序项目&#xff0c;经调研综合所有人员考虑&#xff0c;用uni-app Vue3tsvite技术栈开发&#xff1b;而官方推荐使用HBuilderX开发&#xff0c;而考虑到目前公司所有前端人员对VsCode更熟悉&#xff0c;故此总结了一下uniapp项目使用vscode代替HBuild…

【Python探索之旅】字典

字典的基本特性 创建字典 修改字典 添加键值对 删除键值对 字典方法 遍历字典 完结撒花​ 前言 字典是 Python 中内建的一种具有弹性储存能力的数据结构&#xff0c;可存储任意类型对象&#xff0c;与序列使用整数索引不同&#xff0c;它使用键(key)进行索引。 通常任何不…