串口通信控制LED灯

news2025/1/25 8:59:25

做这个东西的目的是锻炼一下自己的编程能力以及系统思维能力

首先,清楚自己要干什么,正点原子大家应该都看过,系统框图是一个比较重要的东西,引导我们去设计和思考。

下面先给出系统框图:

模块划分好后,结构就比较清晰了,可以分成三个文件实现,一个是LED控制模块,一个是串口接收模块,还有一个是顶层模块。

串口接收模块
module uart_recv (
    input clk,
    input rst_n,
    input uart_rx,
    output reg [7:0] rx_data,
    output reg data_valid
);

reg [1:0] signal;
wire falling_edge; 
always @ (posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        signal[0] <= 1'd0;
        signal[1] <= 1'd0;
    end else begin
        signal[0] <= uart_rx;
        signal[1] <= signal[0];
    end
end

assign falling_edge = ~signal[0] & signal[1];    //检测下降沿

reg rx_flag;
always @ (posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        rx_flag <= 1'd0;
    end else if (falling_edge) begin
        rx_flag <= 1'd1;
    end else if (data_cnt == 4'd8) begin
        rx_flag <= 1'd0;
    end else begin
        rx_flag <= rx_flag;
    end
end

//115200bps 8680ns接收一位数据 系统时钟50M 20ns 每计数434次接收一位数据
reg [8:0] cnt;
always @ (posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cnt <= 9'd0;
    end else if (rx_flag && cnt < 9'd434) begin
        cnt <= cnt + 1;
    end else begin
        cnt <= 9'd0;
    end
end

reg [7:0] data;
reg [3:0] data_cnt;
always @ (posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        data <= 8'd0;
        data_cnt <= 4'd0;
    end else if (rx_flag && cnt == 9'd434) begin
        data <= {data[6:0],uart_rx};
        data_cnt <= data_cnt + 1;
    end else if (rx_flag) begin
        data <= data;
        data_cnt <= data_cnt;
    end else
        data <= 8'd0;
        data_cnt <= 4'd0;
    end
end

always @ (posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        rx_data <= 8'd0;
        data_valid <= 1'd0;
    end else if (data_cnt == 4'd8) begin
        rx_data <= data;
        data_valid <= 1'd1;
    end else begin
        rx_data <= 8'd0;
        data_valid <= 1'd0;
    end
end
    

endmodule

对该模块进行仿真测试

`timescale 1ns / 1ps

module uart_recv_tb;

reg clk;
reg rst_n;
reg uart_rx;
wire [7:0] rx_data;
wire data_valid;

// 实例化模块
uart_recv uut (
    .clk(clk),
    .rst_n(rst_n),
    .uart_rx(uart_rx),
    .rx_data(rx_data),
    .data_valid(data_valid)
);

// 时钟生成
initial begin
    clk = 1'b0;
    forever #10 clk = ~clk; // 50 MHz 时钟
end

// 复位信号
initial begin
    rst_n = 1'b0;
    #50 rst_n = 1'b1;
end

// 模拟 UART 数据帧传输(起始位+8数据位+停止位)
initial begin
    uart_rx = 1'b1; // 空闲状态

    // 发送起始位(低电平)
    #8680 uart_rx = 1'b0;

    // 发送数据位 (10101011)
    #8680 uart_rx = 1'b1;
    #8680 uart_rx = 1'b0;
    #8680 uart_rx = 1'b1;
    #8680 uart_rx = 1'b0;
    #8680 uart_rx = 1'b1;
    #8680 uart_rx = 1'b0;
    #8680 uart_rx = 1'b1;
    #8680 uart_rx = 1'b1;

    // 发送停止位(高电平)
    #8680 uart_rx = 1'b1;

    // 等待接收完成
    #50000 $finish;
end

endmodule

测试结果

检测到起始位:

读出数据正确,读有效信号拉高


LED控制模块
module led_control(
	input clk,
	input rst_n,
	input [7:0] data,
	input data_valid,
	output reg led
);

always @ (posedge clk or negedge rst_n) begin
	if (!rst_n) begin
		led <= 1'd0;
	end else if (data_valid && data == 8'h12) begin
		led <= 1'd1;
	end else if (data_valid && data == 8'h23) begin
		led <= 1'd0;
	end else begin
		led <= led;
	end
end

endmodule

顶层模块
module top(
    input clk,
    input rst_n,
    input uart_rx,
    output led
    );

wire [7:0] data;
wire data_valid;

uart_recv u_uart_recv(
    .clk        (clk),
    .rst_n      (rst_n),
    .uart_rx    (uart_rx),
    .rx_data    (data),
    .data_valid (data_valid)
);

led_control u_led_control(
    .clk        (clk),
    .rst_n      (rst_n),
    .data       (data),
    .data_valid (data_valid),
    .led        (led)
);


ila_0 your_instance_name (
	.clk(clk), // input wire clk
	.probe0(led), // input wire [0:0]  probe0  
	.probe1(data_valid), // input wire [0:0]  probe1 
	.probe2(data) // input wire [7:0]  probe2
);

endmodule
综合仿真

仿真结果正确,串口发送12时led点亮,串口发送23时,led熄灭


上板测试结果与仿真一致

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

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

相关文章

WPF+MVVM案例实战与特效(四十五)- 打造优雅交互:ListBox 的高级定制与行为触发(侧边菜单交互面板)

文章目录 1、引言2、案例效果3、案例实现1、依赖安装2、文件创建3、代码实现1、依赖引用与上下文2、个性化视觉效果:自定义 ItemContainerStyle3、页面样式与布局完整代码4、ViewModel 逻辑实现5、子界面代码:3、实现效果4、源代码获取5、总结1、引言 在WPF应用程序开发中,…

分享两个爬虫练习网站+一个python游戏网站

目录 第一个网站第二个Python游戏网站 第一个网站 网站一 第二个 网站二 Python游戏网站 网站三

空天地遥感数据识别与计算--数据分析如何助力农林牧渔、城市发展、地质灾害监测等行业革新

在科技飞速发展的时代&#xff0c;遥感数据的精准分析已经成为推动各行业智能决策的关键工具。从无人机监测农田到卫星数据支持气候研究&#xff0c;空天地遥感数据正以前所未有的方式为科研和商业带来深刻变革。然而&#xff0c;对于许多专业人士而言&#xff0c;如何高效地处…

C++中的进程虚拟内存布局

进程虚拟内存布局 进程虚拟内存布局&#xff1a; .text&#xff08;代码段&#xff09;&#xff1a;存放的是程序源代码编译后的机器指令&#xff0c;是只读的。 .rodata&#xff08;只读数据段&#xff09;&#xff1a;存放的是程序中的只读数据&#xff0c;一般是程序里面的…

鸿蒙开发-ArkTS 创建自定义组件

在 ArkTS 中创建自定义组件是一个相对简单但功能强大的过程。以下是如何在 ArkTS 中创建和使用自定义组件的详细步骤&#xff1a; 一、定义自定义组件 使用Component注解&#xff1a;为了注册一个组件&#xff0c;使其能够在其他文件中被引用&#xff0c;你需要使用Component…

计算机网络B重修班-期末复习

[TOC] (计算机网络B重修班-期末复习&#xff09; 一、单选 &#xff08;20题&#xff0c;1分/题&#xff0c;共20分&#xff09; 二、判断 &#xff08;10题&#xff0c;1分/题&#xff0c;共10分&#xff09; 三、填空 &#xff08;10题&#xff0c;1分/题&#xff0c;共10…

SSH连接成功,但VSCode连接不成功

环境 在实验室PC上连接服务器234 解决方案&#xff1a;在VSCode中重新添加远程主机 删除旧的VSCode Server 在远程主机上&#xff0c;VSCode会安装一个‘vscode-server’服务来支持远程开发&#xff0c;有时旧的‘vscode-server’文件可能会导致问题&#xff0c;删除旧的&am…

揭开 Choerodon UI 拖拽功能的神秘面纱

01 引言 系统的交互方式主要由点击、选择等组成。为了提升 HZERO 系统的用户体验、减少部分操作步骤&#xff0c;组件库集成了卓越的拖拽功能&#xff0c;让用户可以更高效流畅的操作系统。 例如&#xff1a;表格支持多行拖拽排序、跨表数据调整、个性化调整列顺序&#xff1…

面试题整理9----谈谈对k8s的理解1

谈谈对k8s的理解 1. Kubernetes 概念 1.1 Kubernetes是什么 Kubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;方便进行声明式配置和自动化。Kubernetes 拥有一个庞大且快速增长的生态系统&#xff0c;其服务、支持和工具的…

Elasticsearch:什么是信息检索?

信息检索定义 信息检索 (IR) 是一种有助于从大量非结构化或半结构化数据中有效、高效地检索相关信息的过程。信息&#xff08;IR&#xff09;检索系统有助于搜索、定位和呈现与用户的搜索查询或信息需求相匹配的信息。 作为信息访问的主要形式&#xff0c;信息检索是每天使用…

【深度学习】 零基础介绍卷积神经网络(CNN)

CNN学习 零基础介绍写个CNN最简单的代码一. 概述二. 搭建CNN1. 输入层2. 卷积层3. 激活层4. 池化层5. 全连接层6. 网络搭建小结7. 损失函数8. 梯度下降9. 反向传播10. 模型评估与正则化11. 尝试搭建自己的第一个CNN 三. 经典CNN结构四. 猫狗识别项目实践1. Paddle实现版本&…

flutter 使用dio 请求go语言后台数据接口展示瀑布流图片

添加依赖 dependencies:flutter:sdk: flutterdio: ^5.0.0 # 请检查最新版本flutter_staggered_grid_view: ^0.4.0 添加网络权限 <uses-permission android:name"android.permission.INTERNET" /> go后端代码 图片存放目录 // main.go package mainimport (&q…

ZYNQ初识2(zynq_7010)基于vivado,从PL端调用PS端的时钟

由于需要进行一些FPGA的简单开发&#xff0c;但板载PL端没有焊接晶振&#xff0c;所以需要从PS端借用时钟到PL端使用。 首先新建项目&#xff0c;根据自己的板载选择芯片&#xff0c;我的板载芯片是zynq_7010。 一路next&#xff0c;在自己的vivado的工作文档新建文件夹并给自…

Go语言启动独立进程

文章目录 问题解决方案1. **将 npc.exe 启动为独立的进程**2. **修改 exec.Command 函数**示例代码解释为什么这样有效注意 问题 在你当前的代码中&#xff0c;调用 exec.Command("XXX.exe") 启动 XXX.exe 程序时&#xff0c;这个程序是由 Go 程序直接启动的。如果 …

oracle client linux服务器安装教程

p13390677_112040_Linux-x86-64_4of7.zip 安装前&#xff0c;确认/etc/hosts文件已配置正确 cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 10.2…

strongswan构建测试环境

make-testing脚本文件负责构建strongswan的虚拟化测试系统。位于目录strongswan-5.9.14/testing/&#xff0c;需要以管理员身份运行make-testing。生成测试用到的虚拟客户机镜像&#xff0c;KVM虚拟机和虚拟网络的配置文件位于目录:config/kvm。 ~/strongswan-5.9.14/testing$…

页面无滚动条,里面div各自有滚动条

一、双滚动条左右布局 实现效果 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Doc…

踩准智能汽车+机器人两大风口,速腾聚创AI+机器人应用双线爆发

日前&#xff0c;RoboSense速腾聚创交出了一份亮眼的Q3财报。受到多重利好消息影响&#xff0c;其股价也应势连续大涨。截止12月9日发稿前&#xff0c;速腾聚创股价近一个月内累计涨幅已超88%。 财务数据方面&#xff0c;速腾聚创在今年前三季度实现总收入约11.3亿元&#xff0…

省略内容在句子中间

一、使用二分查找法 每次查找时&#xff0c;将查找范围分成两半&#xff0c;并判断目标值位于哪一半&#xff0c;从而逐步缩小查找范围。 循环查找 计算中间位置 mid Math.floor((low high) / 2)。比较目标值 target 和中间位置的元素 arr[mid]&#xff1a; 如果 target ar…

CTF — 压缩包密码爆破

CTF — 压缩包密码爆破 ​ 在CTF比赛中&#xff0c;密码爆破压缩包&#xff08;如ZIP或RAR文件&#xff09;是一个常见的任务。针对ZIP压缩包的密码爆破主要是使用工具ARCHPR完成的。这个工具的功能非常强大&#xff0c;假设你已经在Win系统里安装完这个软件了&#xff0c;打开…