Verilog新手必看:如何用Vivado 2018.3实现串口控制LED闪烁(附完整代码)

FPGA ise项目 实现点亮led灯,串口收发 文章目录前言一、FPGA开发板使用1.D1闪烁 间隔1s2.D2闪烁,间隔1s,按下key1,key2,实现D2的闪烁时间加长/减少二、串口通信key3作为串口驱动信号,向mcu发送数据,反复发送,key4按下,mcu发送信号给FPGA,FPGA发送反馈数据给mcu总结 前言 FPGA verilog项目学习 一、FPGA开发板使用 1.D1闪烁 间隔1s 代码如下: module D1 #( parameter CNT_MAX = 26'd49_999_999 ) ( input wire sys_ 阅读详情

从零构建FPGA串口交互系统:Vivado实战与Verilog设计精要

很多刚接触FPGA的朋友,在点亮第一个LED之后,往往会陷入一个迷茫期:下一步该做什么?那些复杂的通信协议、状态机、数据解析,听起来就让人头大。我刚开始学的时候,也是对着开发板上的串口接口发愣,不知道如何让电脑和这块小小的芯片“说上话”。直到后来,我意识到一个道理:最好的学习路径,是从一个具体、完整、能跑起来的项目入手。今天,我们就来一起动手,用Vivado 2018.3和Verilog,打造一个可以通过电脑串口助手自由控制的LED闪烁系统。这不仅仅是点亮一个灯,而是构建一个完整的“命令-响应”交互框架,这个框架能延伸到更复杂的应用,比如电机控制、传感器数据采集,甚至是自定义的通信协议栈。

这个项目特别适合已经掌握Verilog基础语法,但还没做过完整数据流项目的朋友。你会接触到串口字节接收的状态机设计、自定义应用层协议的制定与解析、多模块的协同与接口定义,以及如何在Vivado中进行完整的仿真与调试。我不会只给你一堆代码让你照抄,而是会拆解每个设计决策背后的思考过程,告诉你为什么这里要用寄存器打拍,那里要设计特定的握手信号。当你完成这个项目,你收获的将不仅仅是一个闪烁的LED,而是一套可复用的FPGA与上位机通信的“脚手架”。

1. 项目环境搭建与Vivado工程创建

在开始写第一行代码之前,确保你的“战场”已经准备就绪。我推荐使用Vivado 2018.3这个版本,它在稳定性和对教育版开发板的支持上做得不错,网上相关的教程和问题解答也最丰富。当然,如果你用的是更新的版本,大部分操作也是兼容的。硬件方面,任何一款带有UART转USB芯片(如CH340、CP2102)和用户LED的FPGA开发板都可以,比如Xilinx的Basys 3、Nexys 4 DDR,或者国产的很多高性价比型号。

1.1 创建与管理Vivado工程

打开Vivado,点击“Create Project”,跟着向导一步步走。有几个关键点需要注意:

  • 项目类型:选择“RTL Project”,并勾选“Do not specify sources at this time”。这样我们可以先搭好框架,再慢慢添加文件。
  • 目标器件:这里必须和你手头的开发板完全匹配。通常可以在板子的官网或手册上找到芯片型号。例如,Basys 3使用的是Xilinx Artix-7 XC7A35T-1CPG236C。选错型号会导致后续的管脚约束和生成比特流失败。
  • 添加设计源文件:创建完工程后,在“Sources”窗口的“Design Sources”上右键,选择“Add Sources”。我个人的习惯是为每个功能模块创建独立的.v文件,例如 uart_rx.v, cmd_parser.v, led_controller.v,最后用一个top.v把它们连接起来。这种模块化的管理方式,在项目变复杂时会让你省心很多。

提示:建议在项目根目录下创建一个src文件夹,专门存放所有的Verilog源文件。再创建一个constrs文件夹,存放管脚约束文件(.xdc)。这样工程结构清晰,也方便版本管理工具(如Git)进行管理。

1.2 理解串口通信的基础参数

我们的目标是让FPGA通过串口接收来自电脑的命令。在动手设计硬件逻辑之前,必须和电脑端的串口助手软件“对好暗号”。串口通信有几个核心参数,它们必须两端一致:

参数典型值说明
波特率 (Baud Rate)115200每秒传输的符号数。这是最重要的参数,收发双方必须严格一致。115200是常见的高速选择。
数据位 (Data Bits)8每个字节由8位数据构成。这也是最常用的设置。
停止位 (Stop Bits)1用于标识一个字节传输结束。通常为1位。
校验位 (Parity)None用于简单的错误检测。为简化设计,我们选择“无校验”。

在Vivado中设计我们的接收模块时,波特率需要通过系统时钟频率来计算分频系数。例如,系统时钟Clk是100MHz(即100,000,000 Hz),目标波特率是115200,那么每个比特的周期是 1 / 115200 ≈ 8.68 us。为了更精确地采样,我们通常使用16倍过采样,即产生一个频率为 115200 * 16 = 1.8432 MHz 的时钟来检测数据。分频系数就是 100,000,000 / 1,843,200 ≈ 54。这个计算过程我们会用Verilog的参数和函数来实现,使其易于配置。

2. 串口字节接收引擎的设计与实现

串口接收是本次项目的核心,也是很多新手觉得抽象的地方。它的本质是一个状态机,持续监听一根信号线(uart_rx)上的电平变化,从起始位开始,按顺序采集8个数据位,最后确认停止位,完成一个字节的接收。

2.1 接收状态机与边沿检测

串口线在空闲时为高电平。当检测到一个比特时间长度的低电平时,标志着起始位的开始。为了稳定地检测到这个下降沿,我们需要对输入信号进行同步化处理,并做边沿检测,以消除亚稳态和毛刺的影响。

// 同步寄存器链,用于消除亚稳态
reg [1:0] uart_rx_sync;
always @(posedge Clk) begin
    uart_rx_sync[0] <= uart_rx;      // 第一级同步
    uart_rx_sync[1] <= uart_rx_sync[0]; // 第二级同步
end

// 下降沿检测:检测到从1变为0
wire rx_falling_edge;
assign rx_falling_edge = (uart_rx_sync == 2'b10);

当rx_falling_edge信号拉高时,我们就认为检测到了起始位,可以启动接收过程。此时,需要使能一个波特率生成器,产生前面提到的16倍波特率时钟(bps_clk_16x),用于在数据位的中间位置进行采样,这是采样最稳定的时刻。

2.2 比特采样与数据组装

在使能接收(RX_EN信号为高)后,我们用计数器bps_cnt在bps_clk_16x的驱动下从0计数到159(对应10个比特 * 16次采样)。采样点通常选择在每个比特周期的中间,例如对于第0个数据位,在第7到第8个采样点(即bps_cnt为24附近)进行多次采样,然后取多数值作为最终比特值,这种方法称为多数判决,能有效提高抗干扰能力。

// 示例:对第一个数据位(bit 0)进行采样
reg [2:0] sample_reg [7:0]; // 为每个数据位分配一个3位寄存器用于多数判决
always @(posedge Clk) begin
    if (RX_EN && bps_clk_16x) begin
        case (bps_cnt)
            21,22,23,24,25,26,27: // 在bit0的稳定区间内采样
                sample_reg[0] <= sample_reg[0] + uart_rx_sync[1]; // 累加采样值
            ... // 其他数据位的采样区间
        endcase
    end
end

// 一个字节接收完成后,进行多数判决并输出
always @(posedge Clk) begin
    if (byte_receive_done) begin
        rx_data[0] <= (sample_reg[0] >= 4) ? 1'b1 : 1'b0; // 如果7次采样中高电平>=4次,则判为1
        // ... 处理其他7个数据位
    end
end

当bps_cnt计数到159(停止位采样结束)时,产生一个rx_done脉冲信号,标志着一个字节数据rx_data已经有效,可以供上层模块读取。这个rx_done信号是整个数据流中的关键握手信号。

3. 自定义应用层协议与命令解析器设计

如果只能接收单个字节,那功能就太有限了。我们想要的是发送一条包含“闪烁模式”和“时间参数”的完整命令。这就需要定义一套应用层协议,并设计一个命令解析器(Parser)。这是将原始字节流转化为有意义控制信息的关键步骤。

3.1 设计一个简单高效的帧协议

一个好的协议应该具备帧头识别、数据承载和帧尾校验的基本结构,同时兼顾简单和高效。这里我们设计一个8字节的固定长度帧:

| 帧头 (2字节) | 数据区 (5字节) | 帧尾 (1字节) |
|--------------|----------------|--------------|
| 0x55 0xA5    | T3 T2 T1 T0 C  | 0xF0         |
  • 帧头 (0x55, 0xA5):用于在连续的字节流中定位一帧的开始。选择两个特定的字节组合,可以极大地降低误触发概率。
  • 数据区:
    • T3, T2, T1, T0:这是一个32位(4字节)的时间参数,用于控制LED闪烁的周期或占空比。注意字节顺序,这里我们约定T0是最低字节(LSB),T3是最高字节(MSB),即小端模式。
    • C:这是一个8位的控制字。我们可以定义它的每一个比特控制一种LED模式。例如:
      • C[0] = 1: LED常亮
      • C[1] = 1: LED以1Hz频率闪烁
      • C[2] = 1: LED以时间参数T设定的周期闪烁
      • C[3] = 1: LED呼吸灯模式
      • ... 其他比特可自定义
  • 帧尾 (0xF0):用于验证帧的完整性。当解析器识别到正确的帧头和帧尾,且长度符合时,才认为收到了一帧有效数据。

3.2 实现滑动窗口式协议解析器

解析器需要持续监视串口接收模块送来的rx_data和rx_done。一种高效的方法是使用一个移位寄存器数组作为滑动窗口。

module cmd_parser (
    input wire Clk,
    input wire Reset_n,
    input wire [7:0] rx_data,
    input wire rx_done,
    output reg [7:0] ctrl_reg,
    output reg [31:0] time_reg,
    output reg cmd_valid
);
    // 8字节的移位寄存器,构成一个滑动窗口
    reg [7:0] frame_buffer [7:0];
    integer i;
    always @(posedge Clk) begin
        if (rx_done) begin
            // 将新字节移入缓冲区,最旧的字节被移出
            for (i = 0; i < 7; i = i + 1) begin
                frame_buffer[i] <= frame_buffer[i+1];
            end
            frame_buffer[7] <= rx_data;
        end
    end

    // 延迟一拍rx_done,确保缓冲区在移位完成后才被检查
    reg rx_done_dly;
    always @(posedge Clk) rx_done_dly <= rx_done;

    // 协议检查与数据提取
    always @(posedge Clk or negedge Reset_n) begin
        if (!Reset_n) begin
            ctrl_reg <= 8'h00;
            time_reg <= 32'h0000_0000;
            cmd_valid <= 1'b0;
        end else if (rx_done_dly) begin
            // 检查帧头、帧尾和长度(通过rx_done_dly间接判断)
            if ((frame_buffer[0] == 8'h55) &&
                (frame_buffer[1] == 8'hA5) &&
                (frame_buffer[7] == 8'hF0)) begin
                // 提取时间参数和控制字
                time_reg[7:0]   <= frame_buffer[2]; // T0
                time_reg[15:8]  <= frame_buffer[3]; // T1
                time_reg[23:16] <= frame_buffer[4]; // T2
                time_reg[31:24] <= frame_buffer[5]; // T3
                ctrl_reg <= frame_buffer[6]; // C
                cmd_valid <= 1'b1; // 产生一个时钟周期的有效脉冲
            end else begin
                cmd_valid <= 1'b0;
            end
        end else begin
            cmd_valid <= 1'b0;
        end
    end
endmodule

这个解析器的工作流程非常清晰:每当收到一个新字节,就将其推入8字节的缓冲区,并检查此时缓冲区的内容是否符合我们定义的协议格式。如果匹配,则提取出time_reg和ctrl_reg,并产生一个cmd_valid脉冲信号,通知下游的LED控制器:“新命令已就绪,请执行”。

4. 可配置的LED控制器模块

命令解析出来了,接下来就需要一个执行器来驱动LED。这个LED控制器应该能根据ctrl_reg的不同模式,结合time_reg的参数,产生丰富的视觉效果。

4.1 多模式状态机设计

我们可以把LED控制器设计成一个多路选择器+计数器的结构。核心是一个32位的大计数器,其计数上限由time_reg决定。

module led_controller (
    input wire Clk,
    input wire Reset_n,
    input wire [7:0] ctrl,
    input wire [31:0] time_set,
    input wire cmd_valid, // 来自解析器的新命令有效信号
    output reg Led
);
    reg [31:0] period_counter;
    reg [2:0]  pattern_index; // 用于某些模式下的子状态

    // 更新参数:仅在收到新命令时更新
    reg [31:0] period_reg;
    reg [7:0]  ctrl_reg;
    always @(posedge Clk or negedge Reset_n) begin
        if (!Reset_n) begin
            period_reg <= 32'd12_500_000; // 默认0.5秒周期(假设100MHz时钟)
            ctrl_reg <= 8'b0000_0001; // 默认模式
        end else if (cmd_valid) begin
            period_reg <= time_set;
            ctrl_reg <= ctrl;
        end
    end

    // 周期计数器
    always @(posedge Clk or negedge Reset_n) begin
        if (!Reset_n) begin
            period_counter <= 32'd0;
        end else begin
            if (period_counter >= period_reg - 1) begin
                period_counter <= 32'd0;
            end else begin
                period_counter <= period_counter + 1;
            end
        end
    end

    // LED输出逻辑 - 一个简单的多模式选择器
    always @(posedge Clk or negedge Reset_n) begin
        if (!Reset_n) begin
            Led <= 1'b0;
            pattern_index <= 3'd0;
        end else begin
            case (ctrl_reg)
                8'b0000_0001: // 模式1:常亮
                    Led <= 1'b1;
                8'b0000_0010: // 模式2:1Hz闪烁 (period_reg控制)
                    Led <= (period_counter < (period_reg >> 1)) ? 1'b1 : 1'b0; // 50%占空比
                8'b0000_0100: // 模式3:根据ctrl_reg的比特位循环点亮
                    begin
                        if (period_counter == period_reg - 1) begin
                            pattern_index <= (pattern_index == 3'd7) ? 3'd0 : pattern_index + 1;
                        end
                        Led <= ctrl_reg[pattern_index];
                    end
                // ... 可以在这里扩展更多模式,如呼吸灯(PWM)
                default:
                    Led <= 1'b0;
            endcase
        end
    end
endmodule

这里有一个关键细节:period_counter >= period_reg - 1这个判断条件。为什么是“大于等于”而不是“等于”?这是为了代码的健壮性。考虑一种情况:当period_reg的值通过串口命令更新时,period_counter可能已经是一个很大的值,远超新的period_reg。如果使用“等于”判断,计数器可能永远无法匹配到新的、更小的period_reg值,导致计数器溢出(从32‘hFFFF_FFFF回到0)后才能清零,这会产生一个非常长的错误周期。使用“大于等于”可以确保在新的period_reg生效后,计数器能在下一个周期就正确归零,行为更符合直觉。

5. 系统集成、仿真与上板调试

各个模块都准备好了,现在需要把它们像拼图一样组合起来,并进行验证。

5.1 顶层模块设计与管脚约束

顶层模块(top.v)的任务非常明确:实例化所有子模块,并连接它们的端口。它也是与外部物理管脚对接的桥梁。

module top (
    input  wire Clk,      // 系统时钟,连接至板载晶振
    input  wire Reset_n,  // 低电平有效的复位按键
    input  wire uart_rx,  // 串口接收线,连接至USB-UART芯片的TX端
    output wire Led       // LED输出
);
    // 内部连线声明
    wire [7:0] rx_data;
    wire       rx_done;
    wire [7:0] ctrl;
    wire [31:0] time_set;
    wire       cmd_valid;

    // 模块实例化
    uart_byte_rx u_uart_rx (
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Baud_Set(3'd4), // 对应115200波特率,根据你的时钟频率调整
        .uart_rx(uart_rx),
        .Data(rx_data),
        .Rx_Done(rx_done)
    );

    cmd_parser u_cmd_parser (
        .Clk(Clk),
        .Reset_n(Reset_n),
        .rx_data(rx_data),
        .rx_done(rx_done),
        .ctrl_reg(ctrl),
        .time_reg(time_set),
        .cmd_valid(cmd_valid)
    );

    led_controller u_led_ctrl (
        .Clk(Clk),
        .Reset_n(Reset_n),
        .ctrl(ctrl),
        .time_set(time_set),
        .cmd_valid(cmd_valid),
        .Led(Led)
    );
endmodule

接下来是管脚约束(XDC文件)。这是将逻辑信号映射到物理芯片引脚的关键一步。你需要查阅开发板原理图,找到时钟、复位键、串口RX和LED对应的FPGA引脚号。

# 示例:Basys 3开发板的约束(部分)
set_property PACKAGE_PIN W5 [get_ports Clk]     # 100MHz系统时钟
set_property IOSTANDARD LVCMOS33 [get_ports Clk]

set_property PACKAGE_PIN U18 [get_ports Reset_n] # 中央按钮,低电平有效
set_property IOSTANDARD LVCMOS33 [get_ports Reset_n]

set_property PACKAGE_PIN B18 [get_ports uart_rx] # USB-UART的TX端(对应FPGA的RX)
set_property IOSTANDARD LVCMOS33 [get_ports uart_rx]

set_property PACKAGE_PIN U16 [get_ports Led]     # LD0
set_property IOSTANDARD LVCMOS33 [get_ports Led]

5.2 编写Testbench进行仿真

在烧录到板子之前,必须用仿真来验证逻辑的正确性。Vivado自带的仿真工具(XSim)足够完成这个任务。一个好的Testbench应该模拟真实的上位机行为,发送符合协议的完整数据帧。

`timescale 1ns / 1ps
module tb_top();
    reg Clk;
    reg Reset_n;
    reg uart_rx;
    wire Led;

    // 实例化被测设计
    top u_top (.*); // 使用 .* 进行自动连接,要求端口名一致

    // 生成100MHz时钟
    always #5 Clk = ~Clk; // 周期10ns -> 100MHz

    // 任务:模拟UART发送一个字节
    task uart_send_byte;
        input [7:0] data;
        integer i;
        begin
            uart_rx = 1'b0; // 起始位
            #8680;          // 1个比特时间 @115200 baud (约8.68us)
            for (i=0; i<8; i=i+1) begin
                uart_rx = data[i];
                #8680;
            end
            uart_rx = 1'b1; // 停止位
            #8680;
        end
    endtask

    initial begin
        // 初始化
        Clk = 0;
        Reset_n = 0;
        uart_rx = 1'b1; // 空闲状态为高电平
        #100;
        Reset_n = 1;
        #1000;

        // 发送一帧测试数据:0x55, 0xA5, 0x78, 0x56, 0x34, 0x12, 0x01, 0xF0
        // 含义:时间参数 0x12345678,控制字 0x01(模式1:常亮)
        uart_send_byte(8'h55);
        uart_send_byte(8'hA5);
        uart_send_byte(8'h78); // Time LSB
        uart_send_byte(8'h56);
        uart_send_byte(8'h34);
        uart_send_byte(8'h12); // Time MSB
        uart_send_byte(8'h01); // Ctrl
        uart_send_byte(8'hF0);

        // 观察一段时间LED输出
        #1000000; // 1ms
        $finish;
    end
endmodule

在仿真波形中,你需要重点观察:

  1. uart_rx线上模拟的字节波形是否正确。
  2. rx_done信号是否在每个字节接收完成后产生一个脉冲。
  3. cmd_valid信号是否在收到完整且正确的8字节帧后产生一个脉冲。
  4. ctrl和time_set信号是否被正确解析为0x01和0x12345678。
  5. Led输出是否根据控制字做出了预期的变化(例如,在收到0x01后变为常亮)。

5.3 上板验证与调试技巧

通过仿真后,就可以生成比特流文件并下载到开发板了。打开电脑上的串口助手(如Putty、SecureCRT或Xshell),进行如下设置:

  • 端口:选择你的开发板对应的COM口(在设备管理器中查看)。
  • 波特率:115200
  • 数据位:8
  • 停止位:1
  • 校验位:None

发送数据时,注意选择十六进制(Hex)发送模式。按照我们的协议,发送:55 A5 78 56 34 12 01 F0。如果一切正常,你应该能看到板载的LED被点亮。

如果LED没有反应,可以按以下步骤排查:

  1. 检查硬件连接:确认USB线已连接,开发板已上电。
  2. 检查串口设置:确认串口助手的所有参数与FPGA设计完全一致,特别是波特率。
  3. 检查约束文件:确认.xdc文件中的管脚编号与原理图完全一致。这是最容易出错的地方。
  4. 使用内部逻辑分析仪(ILA):Vivado的ILA是强大的片上调试工具。你可以在设计中插入ILA核,抓取uart_rx、rx_done、cmd_valid、ctrl等内部信号的实时波形,就像在板子上运行一个示波器一样。这能最直观地看到数据是否被正确接收和解析。
  5. 简化测试:先发送单个字节(如0x55),在ILA中观察rx_data是否正确。再逐步发送完整帧。

当你看到LED随着你从电脑发送的不同命令而变换各种闪烁模式时,那种成就感是无与伦比的。这个项目虽然不大,但它串联起了FPGA开发中从底层驱动到应用协议,再到系统集成与调试的完整链条。你可以在此基础上轻松地扩展更多命令,控制更多外设,或者将串口接收改为发送,让FPGA把传感器数据传回电脑。这套由物理层驱动、协议解析层、应用控制层构成的架构,是许多更复杂嵌入式系统的缩影。

通过向FPGA发送指令控制led灯闪烁(Quartus+verilog) 适用于需要周期性控制某些开关的场合(由led灯闪烁显示开闭) 阅读详情

相关推荐

FPGA贪吃蛇项目实战:从状态机到VGA驱动的数字逻辑设计

状态机是数字系统设计的核心,它通过定义有限的状态和状态间的转换规则,来控制系统的行为逻辑。其原理基于当前状态和输入信号,决定下一个状态和输出,是实现复杂控制流的基石。在FPGA开发中,状态机技术价值显著,它能高效、可靠地管理如游戏逻辑、通信协议等时序过程。应用场景广泛,从简单的流水灯到复杂的图像处理引擎都离不开它。本文以经典的贪吃蛇游戏为例,具体展示了如何运用状态机设计游戏核心逻辑,并结合VGA驱动时序、Block RAM存储管理等关键技术,完成一个完整的FPGA数字系统。项目实践涵盖了碰撞检测、按键消抖、

weixin_34323858的博客 129

重温FPGA开发17

使用串口来控制LED工作状态

qq_30093417的博客 1141

使用Uart串口控制LED灯闪烁

通过串口调试助手,使用串口发送电脑指令到fpga开发板,来控制led灯的工作状态。通过三个模块来实现 串口控制led闪烁:1.uart的数据接收模块:将用户数据通过串口调试助手发到fpga2.串口命令模块:将uart接受模块的数据通过该模块,通过一个自定义协议来发送led灯所需的控制信号3.led工作状态的控制模块:闪烁时间和闪烁状态由用户指定(Time,Ctrl[on/off])自定义协议如下:类似于起始位和停止位的判定,通过数据的移位和比较。

mvpkuku的博客 1982

FPGA入门学习笔记(十二)Vivado实现UART接收控制LED任务

FPGA入门学习笔记(十二)Vivado实现UART接收控制LED任务

weixin_45463952的博客 2338

串口控制FPGA Led亮灭

http://blog.csdn.net/mybelief321/article/details/42532247 自己用C#写的通过串口控制FPGA的LED灯亮灭,数码管显示LED亮的个数,FPGA的程序也是自己看书编写修改的,分享出来吧,但愿对你有用

FPGA实现控制led

FPGA简单入门,介绍了如何建立工程,编译文件,如何用FPGA点亮一个led

7天零基础FPGA入门:从Verilog到上板验证的完整实践指南

数字电路设计是硬件开发的核心基础,其原理在于通过逻辑门组合实现特定功能,并利用寄存器在时钟同步下完成状态存储与转移。这种硬件描述方法相比传统软件编程,能实现真正的并行处理,在性能与能效上具有显著优势,广泛应用于通信、图像处理、嵌入式控制等领域。FPGA(现场可编程门阵列)作为一种可编程逻辑器件,允许工程师通过硬件描述语言(如Verilog)灵活定义数字电路,是实现快速原型验证和定制化硬件加速的关键技术。本文以Verilog语法和Vivado工具链为核心,通过流水灯等经典案例,系统讲解从环境搭建、代码编写、功

张 作强 BLOG 409

FPGA控制led

FPGA控制ledVerilog

串口通信实现-串口发送(vivado&verilog版)

此文介绍uart串口协议(串口发送)的verilog实现和testbench的编写,仿真环境为vivado 2018.3。

小王在努力...的博客 5516

SurfaceControlViewHost使用介绍

可以看到,主要用途:是把一个进程的View显示到另外一个进程里面。

chadm.xiang 1289

告别环境配置噩梦:VSCode + MinGW 下 OpenGL (glad/glm/glfw) 一站式配置指南(含常见错误排查)

本文提供了一份详细的VSCode与MinGW下OpenGL开发环境配置指南,涵盖glad、glm和glfw三大核心库的安装与调试。通过逐步指导解决常见错误,帮助开发者快速搭建高效的OpenGL开发环境,特别适合初学者避免环境配置中的常见陷阱。

weixin_42557803的博客 491

数字电路设计和仿真

数字电路是处理离散信号的电子电路,与模拟电路不同,它只处理两种状态:高电平(通常用 1 表示)和低电平(通常用 0 表示)。这种二进制的特性使得数字电路在现代电子系统中占据着核心地位。我在做 STM32 开发的时候,几乎每天都在和数字电路打交道,比如 GPIO 的高低电平控制、SPI 通信的时序设计等等。数字电路的基本组成单元包括逻辑门(与门、或门、非门等)、触发器、计数器、寄存器等。这些基本单元可以组合成更复杂的功能模块,比如加法器、译码器、多路选择器等。

码到成功 426

FOC控制必看:单/双/三电阻电流采样方案全对比(附NXP实战避坑指南)

本文深入对比了FOC控制中单电阻、双电阻和三电阻电流采样方案的优劣与适用场景,重点剖析了采样时序、窗口与ADC转换的工程挑战。针对NXP平台,提供了解决采样窗口过窄的实战方案与配置指南,帮助工程师根据成本与性能需求做出最优选择,并规避常见设计陷阱。

n2o3p4的博客 416

FPGA玩家进阶:从高频搜索词看信号链路实现与工程化

FPGA(现场可编程门阵列)以其并行处理和硬件可重构特性,成为数字系统设计的关键器件。从基础外设控制到复杂信号链路,FPGA开发涉及接口协议、算法加速和工程可靠性等多层次技术。当前社区高频搜索词如UART_RX接收仿真、QSPI Flash读写、MIPI摄像头配置、eMMC控制器、乒乓缓存、DDS与Costas环等,反映了开发者正从“点亮器件”迈向“打通链路”。文章逐一拆解这些关键词背后的技术原理、实现要点与工程陷阱,涵盖接口调试、信号处理算法以及时序约束、Multiboot升级等产品化议题,为FPGA进阶

weixin_34195142的博客 438

解密CANoe数据回放:从BLF到ASC的格式转换与优化策略

本文深入解析CANoe数据回放中BLF与ASC格式的转换与优化策略,帮助工程师高效处理汽车电子测试数据。详细介绍了两种格式的特性、转换方法及性能优化技巧,包括CANoe内置功能、命令行自动化和第三方工具应用,提升故障诊断和系统验证效率。

weixin_28331555的博客 538

RV1106G3的fastboot调试

本文详细描述了在幸狐的Luckfox Pico Ultra硬件平台上,使用官方SDK进行系统优化和YOLOv5s模型部署的过程。首先,硬件板卡使用幸狐的SDK进行EMMC非Fastboot配置时功能正常,但Fastboot配置编译失败,通过修改设备树中的ramdisk大小解决了编译问题,但运行时仍报错。幸狐提供的Fastboot烧录文件可正常运行,表明硬件支持Fastboot。随后,使用官方SDK版本rv1106_rv1103_240813进行编译和调试,发现EMMC Fastboot启动失败,通过修改U-

fzktongyong的博客 2363

秋招电控岗没回音?推荐10个开源项目补齐工程实践经历

嵌入式开发岗位的招聘筛选,往往不只关注理论成绩,更看重候选人在真实硬件上解决闭环问题的能力。理解单片机、控制算法与通信协议是基础,但只有将原理落到可运行的系统中,才能形成可被量化、可被追问的工程经历。本文从电控岗位的常见技术栈出发,梳理了涵盖电机控制、实时操作系统、工业总线、嵌入式Linux与边缘计算等方向的10个高质量开源项目,帮助求职者在有限时间内补齐简历短板,提升面试通过率。

weixin_34216614的博客 224

风控域——决策引擎系统设计

本文详细介绍了风控决策引擎系统的设计与应用。决策引擎系统是一种智能化工具,可自动化、数据驱动地辅助或替代人工决策,广泛应用于金融、医疗、营销、风控等领域。文章阐述了决策引擎的核心功能,包括自动化决策、动态规则管理、实时处理和模型集成,以及系统组成,涵盖数据输入层、规则引擎和模型服务层。此外,还探讨了决策引擎的典型应用场景、技术架构、组件设计,以及风控决策引擎系统的技术方案、设计难点和重点。

庄小焱 3321

【小月电子】安路国产FPGA开发板系统学习教程-LESSON7串口通信

国产FPGA安路系统学习教程-串口通信

Moon_3181961725的博客 3000

黏菌优化算法(SMA)详解:从生物智能到优化引擎

黏菌优化算法(SMA)是一种新型生物启发式优化算法,模拟多头绒泡菌的智能觅食行为。该算法包含接近食物、包围食物和抓取食物三个阶段,通过数学模型将生物行为转化为优化过程。SMA采用权重自适应机制和参数振荡模型实现探索与开发的平衡,具有参数简单、收敛性好等优势。算法可通过MATLAB/Python实现,并应用于函数优化、工程设计和神经网络训练等领域。研究表明SMA在求解复杂优化问题时表现优异,未来可通过混沌增强、混合策略等方式进一步提升性能。

qq_42212808的博客 661

Sigrity Power DC Single-BoardPackage IR Drop Analysis模式进行单板压降仿真分析操作指导

如果需要单独对某个via设置参数,右侧选择Setup by padstack,下方下拉选择某个via,单独设置参数即可。举例:板厚1.6mm,内层1OZ(1.2mil,即0.03mm),铜皮宽度1mm,20度温升,允许通流I为2.5A。目的是模拟实际情况,via的孔壁电镀1mil,中间是空心的,让via不完全被填充金属成为实心via。Upper/lower Tolerance:上下公差,设置为5%,也就是压降允许的范围。电流密度计算公式:J=I/A(J为电流密度,I为电流,A为横截面积)

weixin_54787054的博客 699

FPGA 20个例程篇:4.串行DAC输出模拟电压控制LED亮度

二、常用通信协议,摸索探究: 4.串行DAC输出模拟电压控制LED亮度 首先在此表示抱歉,笔者因为最近杂七杂八的事情比较多,搞得整个人莫名其妙地忙起来,所以博客更新的相对缓慢些,期间也有朋友私信我催更,表示在等着新例程学习呢,打开优快云 APP看到这些留言心里有一丝欣慰。 之前的承诺20个FPGA例程精讲精析,笔者会尽最大可能保持每周一个的速度持续更新,因为编写和整理代码会消耗不少的时间,后续例程的代码也会慢慢复杂起来,下班回来要做饭和陪女友,另外还要持续地学习工作方面.........

wandou0511的博客 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Xilinx FPGA:vivado用串口控制数码管

要求输入从千位到个位数字给4位数码管,要求分别输入的数字都能显示。这里注释掉了组合逻辑的写法,因为根据仿真,组合逻辑引发了时序问题。

loveyousosad的博客 809

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Xilinx FPGA:vivado实现串口的接收端

补充一些串口里用到的数值的相关知识点。

loveyousosad的博客 714

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

FPGA项目四:串口通信

文章目录第四章 串口通信第1节 项目背景第2节 设计目标第3节 设计实现3.1 顶层信号3.2 信号设计3.2.1 边沿检测电路设计3.2.2 异步信号同步化3.3 信号定义 第四章 串口通信 第1节 项目背景 信息数据被逐位按顺序传送的通讯方式称为串行通信。串行接口(Serial Interface),简称串口, 即是采用串行通信方式的扩展接口。其采用一位一位的方式顺序的传送数据,又可称串行通信接口或 串行通讯接口(通常指 COM 接口)。串行接口的特点是通信线路简单,只要一对传输线就可以实现 双向通信,

da.的博客 6377

上位机串口控制FPGA开发板LED

实验目的:        上位机软件控制FPGA开发板上4个LED灯的亮灭,同时数码管显示LED灯亮的个数,实验效果如下图。 实验背景:    一直都想学习FPGA,这次算是入门了,我是看书学习的,所以FPGA的代码是参考着书本上的修改的,其实很高兴,因为这个实验是我自己发散出来的,书上的开发板和我用的开发板不一样,并且小软件也是自己用C#写的,总之,挺开心吧,本着开源的精神,所有的上位

王文松的博客 8640
上一篇: Unity动态合批实战:如何用Dynamic Batching优化你的移动端游戏性能
下一篇: ARCHPR暴力破解 vs 字典攻击:如何选择最高效的密码破解方式?
gitlab7runner
博客等级 码龄4年 78粉丝 1747原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值