verilog练习:i2c slave 模块设计
文章目录
- 前言
- 1. 结构
- 2.代码
- 2.1 iic_slave.v
- 2.2 sync.v
- 2.3 wr_fsm.v
- 2.3.1 状态机状态解释
- 2.4 ram.v
- 3. 波形展示
- 4. 建议
- 5. 资料总结
前言
首先就不啰嗦iic协议了,网上有不少资料都是叙述此协议的。
下面将是我本次设计的一些局部设计汇总,如果对读者有借鉴意义那最好,如果没有的话也无所谓,互相交流而已。(这是我早期的版本,注释比较少,代码编写比较混乱,读者自便)
希望读者发现问题可在下方留言,我会及时回答或者修改。
1. 结构
顶层结构图
master结构图
slave结构图
2.代码
2.1 iic_slave.v
`timescale 1ns/1psmodule iic_slave (input rstn,input clk,input scl,inout sda,input [7:0] q, // RAM data to slaveoutput wen,output [7:0] d, // Slave data to RAMoutput [7:0] a // Slave address to RAM
);// Internal signals
wire sync_scl_1;
wire sync_sda_1;
wire sda_posedge;
wire sda_negedge;
wire scl_posedge;
wire scl_negedge;
wire sda_out;
wire sda_oen;// Three-state gate for SDA
assign sda = (sda_oen) ? sda_out : 1'bz;// Instantiate sync module
sync sync (.clk(clk),.rstn(rstn),.scl(scl),.sda(sda),.sync_scl_1(sync_scl_1),.sync_sda_1(sync_sda_1),.sda_posedge(sda_posedge),.sda_negedge(sda_negedge),.scl_posedge(scl_posedge),.scl_negedge(scl_negedge)
);// Instantiate RAM module
ram ram (.clk(clk),.rstn(rstn),.d(d),.a(a),.q(q),.wen(wen)
);// Instantiate write FSM module
wr_fsm wr_fsm (.clk(clk),.rstn(rstn),.sync_scl_1(sync_scl_1),.sync_sda_1(sync_sda_1),.scl_posedge(scl_posedge),.scl_negedge(scl_negedge),.sda_posedge(sda_posedge),.sda_negedge(sda_negedge),.d(d),.a(a),.q(q),.wen(wen),.sda_out(sda_out),.sda_oen(sda_oen)
);endmodule
2.2 sync.v
`timescale 1ns/1ps
module sync (rstn,clk,scl,sda,sync_scl_1,sync_sda_1,sda_posedge,sda_negedge,scl_posedge,scl_negedge
);input rstn;input clk;input scl;input sda;output sync_scl_1;output sync_sda_1;output sda_posedge;output sda_negedge;output scl_posedge;output scl_negedge;reg sync_scl_1;reg sync_sda_1;reg sync_scl_0;reg sync_sda_0;always @(posedge clk or negedge rstn) beginif (!rstn) beginsync_scl_1 <= 1'b0;sync_sda_1 <= 1'b0;sync_scl_0 <= 1'b0;sync_sda_0 <= 1'b0;end else beginsync_scl_0 <= scl;sync_sda_0 <= sda;sync_scl_1 <= sync_scl_0;sync_sda_1 <= sync_sda_0;endendassign sda_posedge = (sync_sda_0) & (~sync_sda_1);assign sda_negedge = (~sync_sda_0) & (sync_sda_1);assign scl_posedge = (sync_scl_0) & (~sync_scl_1);assign scl_negedge = (~sync_scl_0) & (sync_scl_1);endmodule
2.3 wr_fsm.v
`timescale 1ns/1ps
module wr_fsm (rstn,clk,sync_scl_1,sync_sda_1,scl_posedge,scl_negedge,sda_posedge,sda_negedge,q,d,a,wen,sda_out,sda_oen
);input rstn, clk;input sync_scl_1;input sync_sda_1;input scl_posedge;input scl_negedge;input sda_posedge;input sda_negedge;input [7:0] q;output [7:0] d;output [7:0] a;output wen;output sda_out;output sda_oen;reg wen; // write and read flags regreg [7:0] scl_cnt; // clk delay counterreg [3:0] bit_cnt; // valid transfer bytereg [7:0] a; // a = save word addr, shift data to ramreg sda_out; // data out regreg sda_oen; // three state gate flag bitreg [7:0] save_ctrl; // store ctrl wordreg [7:0] save_q_data; // store data of qwire [7:0] q;parameter slave_addr = 7'b1101101; // parameter slave addrparameter scl_cnt_max = 60-1;reg [3:0] state; // state transformparameter idle = 4'd0,w_start = 4'd1,w_ctrl = 4'd2,ack1 = 4'd3,w_addr = 4'd4,ack2 = 4'd5,w_data = 4'd6,ack3 = 4'd7,r_start = 4'd8,r_ctrl = 4'd9,ack4 = 4'd10,r_data = 4'd11,ack5 = 4'd12,stop = 4'd13;always @(posedge clk or negedge rstn)beginif (!rstn) beginstate <= idle;sda_oen <= 1'b0;sda_out <= 1'b1;scl_cnt <= 8'b0;bit_cnt <= 4'b0;sda_out <= 1'b0;end else begincase (state)idle: begin// Initialize state and signalsstate <= w_start;sda_oen <= 1'b0;sda_out <= 1'b1;scl_cnt <= 8'b0;bit_cnt <= 4'b0;sda_out <= 1'b0;endw_start: begin// Wait for start conditionif (sync_scl_1 && sda_negedge)beginstate <= w_ctrl;bit_cnt <= 4'd8;endelsestate <= w_start;endw_ctrl: begin// Control word transferif (scl_negedge)beginsave_ctrl <= {save_ctrl[6:0], sync_sda_1};bit_cnt <= bit_cnt - 1;if (bit_cnt == 4'd0)beginstate <= ack1;bit_cnt <= 4'd8;endelsestate <= w_ctrl;endelsestate <= w_ctrl;endack1: begin// Acknowledge control wordif (save_ctrl[7:1] == slave_addr)beginscl_cnt <= scl_cnt + 8'b1;if (scl_cnt == scl_cnt_max >> 2)beginsda_out <= 0;sda_oen <= 1;state <= ack1;endelse if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)beginstate <= w_addr;sda_oen <= 0;scl_cnt <= 8'b0;bit_cnt <= 4'd7;endelsestate <= ack1;endelsestate <= stop;endw_addr: begin// Write addressif (scl_negedge)beginbit_cnt <= bit_cnt - 4'b1;wen <= save_ctrl[0]; // write operationa <= {a[6:0], sync_sda_1};if (bit_cnt == 4'd0)beginbit_cnt <= 4'd7;state <= ack2;endelsestate <= w_addr;endelsestate <= w_addr;endack2: begin// Acknowledge addressscl_cnt <= scl_cnt + 8'b1;if (scl_cnt == scl_cnt_max >> 2)beginsda_out <= 1'b0;sda_oen <= 1'b1;state <= ack2;endelse if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)beginsda_oen <= 1'b0;scl_cnt <= 8'b0;if (wen == 0) // decide write or readstate <= w_data;elsestate <= r_start;endelsestate <= ack2;endw_data: begin// Write dataif (scl_negedge)begind <= {d[6:0], sync_sda_1};bit_cnt <= bit_cnt - 4'b1;if (bit_cnt == 4'd0)beginbit_cnt <= 4'd7;state <= ack3;endelsestate <= w_data;endelsestate <= w_data;endack3: begin// Acknowledge datascl_cnt <= scl_cnt + 8'b1;if (scl_cnt == scl_cnt_max >> 2)beginsda_out <= 0;sda_oen <= 1'b1;state <= ack3;endelse if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)beginsda_oen <= 1'b0;scl_cnt <= 8'b0;state <= stop;endelsestate <= ack3;endr_start: begin// Read start conditionif (sync_scl_1 && sda_negedge)beginsda_oen <= 1'b0;bit_cnt <= 4'd8;state <= r_ctrl;endelsestate <= r_start;endr_ctrl: begin// Read control wordif (scl_negedge)beginbit_cnt <= bit_cnt - 4'b1;save_ctrl <= {save_ctrl[6:0], sync_sda_1};if (bit_cnt == 4'd0)beginwen <= save_ctrl[0];bit_cnt <= 4'd7;state <= ack4;endelsestate <= r_ctrl;endelsestate <= r_ctrl;endack4: begin// Acknowledge control wordif (save_ctrl[7:1] == slave_addr)beginscl_cnt <= scl_cnt + 8'b1;if (scl_cnt == scl_cnt_max >> 2)beginsda_out <= 0;sda_oen <= 1;state <= ack4;endelse if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)beginsda_oen <= 1'b0;scl_cnt <= 8'b0;if (wen)beginstate <= r_data;sda_oen <= 1'b1;sda_out <= sync_sda_1;endelsestate <= w_data;endelsestate <= ack4;endelsestate <= stop;endr_data: begin// Read dataif (scl_negedge)beginsave_q_data <= q[7:0];bit_cnt <= bit_cnt - 4'b1;sda_out <= save_q_data[7];if (bit_cnt == 4'd0)beginstate <= ack5;bit_cnt <= 4'd7;sda_oen <= 0;endelsebeginstate <= r_data;sda_oen <= 1;save_q_data <= {save_q_data[6:0], 1'b0};endendelsestate <= r_data;endack5: begin// Acknowledge dataif (scl_posedge)beginif (sync_sda_1 == 1)state <= stop;elsestate <= idle;endelsestate <= ack5;endstop: begin// Stop conditionif (sync_scl_1 && sda_posedge)beginstate <= idle;sda_oen <= 1'b0;sda_out <= 1'b1;endelsestate <= stop;enddefault: state <= idle;endcaseendend
endmodule
2.3.1 状态机状态解释
当然可以!以下是优化后的代码中每个状态的作用解释:
reg [3:0] state; // state transform
parameter idle = 4'd0,w_start = 4'd1,w_ctrl = 4'd2,ack1 = 4'd3,w_addr = 4'd4,ack2 = 4'd5,w_data = 4'd6,ack3 = 4'd7,r_start = 4'd8,r_ctrl = 4'd9,ack4 = 4'd10,r_data = 4'd11,ack5 = 4'd12,stop = 4'd13;
状态作用解释
- idle (4’d0):
- 作用: 初始状态,等待复位信号或起始条件。
- 描述: 在这个状态下,所有信号被初始化,状态机等待复位信号 rstn 或起始条件(sync_scl_1 和 sda_negedge)。
- w_start (4’d1):
- 作用: 等待起始条件。
- 描述: 在这个状态下,状态机检测起始条件(sync_scl_1 和 sda_negedge)。如果检测到起始条件,状态机进入 w_ctrl 状态。
- w_ctrl (4’d2):
- 作用: 接收控制字。
- 描述: 在这个状态下,状态机接收控制字(save_ctrl),并将其存储在寄存器中。控制字的接收通过 scl_negedge 信号完成。当接收到完整的控制字后,状态机进入 ack1 状态。
- ack1 (4’d3):
- 作用: 发送 ACK 信号。
- 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。如果接收到的控制字匹配从设备地址(slave_addr),状态机进入 w_addr 状态。否则,状态机进入 stop 状态。
- w_addr (4’d4):
- 作用: 接收地址。
- 描述: 在这个状态下,状态机接收地址数据(a),并将其存储在寄存器中。地址的接收通过 scl_negedge 信号完成。当接收到完整的地址后,状态机进入 ack2 状态。
- ack2 (4’d5):
- 作用: 发送 ACK 信号。
- 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。根据控制字中的写入标志(wen),状态机决定进入 w_data 状态(写入数据)或 r_start 状态(读取数据)。
- w_data (4’d6):
- 作用: 写入数据。
- 描述: 在这个状态下,状态机接收数据(d),并将其存储在寄存器中。数据的接收通过 scl_negedge 信号完成。当接收到完整的数据后,状态机进入 ack3 状态。
- ack3 (4’d7):
- 作用: 发送 ACK 信号。
- 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。然后状态机进入 stop 状态。
- r_start (4’d8):
- 作用: 等待读取起始条件。
- 描述: 在这个状态下,状态机检测读取起始条件(sync_scl_1 和 sda_negedge)。如果检测到起始条件,状态机进入 r_ctrl 状态。
- r_ctrl (4’d9):
- 作用: 接收控制字。
- 描述: 在这个状态下,状态机接收控制字(save_ctrl),并将其存储在寄存器中。控制字的接收通过 scl_negedge 信号完成。当接收到完整的控制字后,状态机进入 ack4 状态。
- ack4 (4’d10):
- 作用: 发送 ACK 信号。
- 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。如果接收到的控制字匹配从设备地址(slave_addr),状态机进入 r_data 状态。否则,状态机进入 stop 状态。
- r_data (4’d11):
- 作用: 读取数据。
- 描述: 在这个状态下,状态机读取数据(q),并将其存储在寄存器中。数据的读取通过 scl_negedge 信号完成。当读取完数据后,状态机进入 ack5 状态。
13。 ack5 (4’d12): - 作用: 发送 ACK 信号。
- 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。然后状态机进入 idle 状态。
- stop (4’d13):
- 作用: 停止状态。
- 描述: 在这个状态下,状态机等待停止条件(sync_scl_1 和 sda_posedge)。如果检测到停止条件,状态机进入 idle 状态。
每个状态的作用如下:
- idle: 初始状态,等待复位或起始条件。
- w_start: 等待起始条件。
- w_ctrl: 接收控制字。
- ack1: 发送 ACK 信号,确认控制字接收。
- w_addr: 接收地址。
- ack2: 发送 ACK 信号,确认地址接收。
- w_data: 写入数据。
- ack3: 发送 ACK 信号,确认数据写入。
- r_start: 等待读取起始条件。
- r_ctrl: 接收控制字。
- ack4: 发送 ACK 信号,确认控制字接收。
- r_data: 读取数据。
- ack5: 发送 ACK 信号,确认数据读取。
- stop: 停止状态,等待停止条件。
这些状态共同构成了一个完整的 I2C 从设备写入和读取的有限状态机,确保数据的正确传输和接收。
2.4 ram.v
`timescale 1ns/1ps
module ram (clk,rstn,d,a,q,wen
);// Input portsinput clk, rstn;input [7:0] a; // Address inputinput [7:0] d; // Data inputinput wen; // Write enable// Output portsoutput [7:0] q; // Data output// Internal registersreg [7:0] ram [255:0]; // RAM arrayinteger i; // Loop counterreg [7:0] q; // Output data register// Always block for RAM operationsalways @(posedge clk or negedge rstn)beginif (!rstn) begin// Initialize RAM on resetfor (i = 0; i <= 255; i = i + 1)ram[i] <= 8'b0;end else beginif (!wen) begin// Write operation: wen = 0ram[a] <= d;end else begin// Read operation: wen = 1q <= ram[a];endendendendmodule
3. 波形展示
4. 建议
必看
此设计还存在一些问题,后续有时间我会完善的。
在同步的时候我建议还是使用两个寄存器缓冲,而不是使用一个,使用多个更加的稳妥一些,我这个就是使用了较少的寄存器缓冲,所以波形中有问题。(我把这段字打个红色背景)。(是因为在边沿检测的时候无法确认信号是否同步还是异步所以在设计的时候还是使用双寄存器进行消除亚稳态)。
5. 资料总结
练习时的一些思路。
https://blog.csdn.net/weixin_46163885/article/details/107170689
相关文章:

verilog练习:i2c slave 模块设计
文章目录 前言1. 结构2.代码2.1 iic_slave.v2.2 sync.v2.3 wr_fsm.v2.3.1 状态机状态解释 2.4 ram.v 3. 波形展示4. 建议5. 资料总结 前言 首先就不啰嗦iic协议了,网上有不少资料都是叙述此协议的。 下面将是我本次设计的一些局部设计汇总,如果对读者有…...
3.5 Go(特殊函数)
目录 一、匿名函数 1、匿名函数的特点: 2、匿名函数代码示例 2、匿名函数的类型 二、递归函数 1. 递推公式版本 2. 循环改递归 三、嵌套函数 1、嵌套函数用途 2、代码示例 3、作用域 & 变量生存周期 四、闭包 1、闭包使用场景 2、代码示例 五、De…...
Android的MQTT客户端实现
在 Android 平台上实现 MQTT 客户端的完整技术方案,涵盖基础实现、安全连接、性能优化和最佳实践: 一、技术选型与依赖配置 推荐库 Eclipse Paho Android Service(官方维护,支持后台运行) gradle 复制 // build.gradl…...

国产编辑器EverEdit - 编辑辅助功能介绍
1 编辑辅助功能 1.1 各编辑辅助选项说明 1.1.1 行号 打开该选项时,在编辑器主窗口左侧显示行号,如下图所示: 1.1.2 文档地图 打开该选项时,在编辑器主窗口右侧靠近垂直滚动条的地方显示代码的缩略图,如下图所示&…...
WPF 在后台使TextBox失去焦点的方法
在软件设计开发的时候,偶尔会遇到在后台xaml.cs后台中,要将TextBox控件的焦点取消或者使TextBox控件获取焦点,下面介绍讲述一种简单的“只让特定的 TextBox 失去焦点”方法: 前端xaml代码示例: <StackPanel Orientation"…...

工作案例 - python绘制excell表中RSRP列的CDF图
什么是CDF图 CDF(Cumulative Distribution Function)就是累积分布函数,是概率密度函数的积分。CDF函数是一个在0到1之间的函数,描述了随机变量小于或等于一个特定值的概率。在可视化方面,CDF图表明了一个随机变量X小于…...

CTF SQL注入学习笔记
部分内容来自于SQL注入由简入精_哔哩哔哩_bilibili SQL语句 1.mysqli_error():返回最近调用函数的最后一个错误描述 语法:mysqli_error(connection) 规定要使用的Mysql连接; 返回一个带有错误描述的字符串。如果没有错误发生则返回 "" 2…...
element-plus el-tree-select 修改 value 字段
element-plus el-tree-select 修改 value 字段 ,不显示label 需要注意两个地方: <el-tree-select v-model"value" :data"data" multiple :render-after-expand"false" show-checkbox style"width: 240px" …...

基于javaweb的SpringBoot小区智慧园区管理系统(源码+文档+部署讲解)
🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 运行环境开发工具适用功能说明 运行环境 Java≥8、MySQL≥5.7、Node.js≥14 开发工具 后端:eclipse/idea/myeclipse…...

SpringBoot学习之shardingsphere实现分库分表(基于Mybatis-Plus)(四十九)
一、shardingsphere介绍 ShardingSphere是一款起源于当当网内部的应用框架。2015年在当当网内部诞生,最初就叫ShardingJDBC。2016年的时候,由其中一个主要的开发人员张亮,带入到京东数科,组件团队继续开发。在国内历经了当当网、电信翼支付、京东数科等多家大型互联网企业的…...

23.PPT:校摄影社团-摄影比赛作品【5】
目录 NO12345 NO6 NO7/8/9/10 单元格背景填充表格背景填充文本框背景填充幻灯片背景格式设置添加考生文件夹下的版式 NO12345 插入幻灯片和放入图片☞快速:插入→相册→新建相册→文件→图片版式→相框形状→调整边框宽度左下角背景图片:视图→…...

Baumer工业相机堡盟相机的相机传感器芯片清洁指南
Baumer工业相机堡盟相机的相机传感器芯片清洁指南 Baumer工业相机1.Baumer工业相机传感器芯片清洁工具和清洁剂2.Baumer工业相机传感器芯片清洁步骤2.1、准备步骤2.2、清洁过程1.定位清洁工具2.清洁传感器3.使用吹风装置 Baumer工业相机传感器芯片清洁的优势设计与结…...
Spring Boot 整合 JPA 实现数据持久化
目录 前言 一、JPA 核心概念与实体映射 1. 什么是 JPA? 2. JPA 的主要组件 3. 实体映射 4. 常见的字段映射策略 二、Repository 接口与自定义查询 1. 什么是 Repository 接口? 2. 动态查询方法 3. 自定义查询 4. 分页与排序 三、实战案例&…...

快速在wsl上部署学习使用c++轻量化服务器-学习笔记
知乎上推荐的Tinywebserver这个服务器,快速部署搭建,学习c服务器开发 仓库地址 githubhttps://link.zhihu.com/?targethttps%3A//github.com/qinguoyi/TinyWebServerhttps://link.zhihu.com/?targethttps%3A//github.com/qinguoyi/TinyWebServer 在…...

【R语言】数据操作
一、查看和编辑数据 1、查看数据 直接打印到控制台 x <- data.frame(a1:20, b21:30) x View()函数 此函数可以将数据以电子表格的形式进行展示。 用reshape2包中的tips进行举例: library("reshape2") View(tips) head()函数 查看前几行数据&…...

MariaDB MaxScale实现mysql8主从同步读写分离
一、MaxScale基本介绍 MaxScale是maridb开发的一个mysql数据中间件,其配置简单,能够实现读写分离,并且可以根据主从状态实现写库的自动切换,对多个从服务器能实现负载均衡。 二、MaxScale实验环境 中间件192.168.121.51MaxScale…...

【python】简单的flask做页面。一组字母组成的所有单词。这里的输入是一组字母,而输出是所有可能得字母组成的单词列表
目录结构如下: https://github.com/kaede316/Pythons_pj.git 效果: 后续可扩展为工具网站: 更新 2025.02.09 1、增加等间距制作人 时间信息 2、增加判断润年的功能...

单片机之基本元器件的工作原理
一、二极管 二极管的工作原理 二极管是一种由P型半导体和N型半导体结合形成的PN结器件,具有单向导电性。 1. PN结形成 P型半导体:掺入三价元素,形成空穴作为多数载流子。N型半导体:掺入五价元素,形成自由电子作为多…...

吴恩达深度学习——卷积神经网络的特殊应用
内容来自https://www.bilibili.com/video/BV1FT4y1E74V,仅为本人学习使用。 文章目录 人脸识别相关定义Similarity函数使用Siamese网络实现函数d使用Triplet损失学习参数 神经风格迁移深度卷积网络可视化神经风格迁移的代价函数内容损失函数风格损失函数 人脸识别 …...

安宝特方案 | AR助力制造业安全巡检智能化革命!
引言: 在制造业中,传统巡检常面临流程繁琐、质量波动、数据难以追溯等问题。安宝特AR工作流程标准化解决方案,通过增强现实AR技术,重塑制造业安全巡检模式,以标准化作业流程为核心,全面提升效率、质量与…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...

DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...

EasyRTC音视频实时通话功能在WebRTC与智能硬件整合中的应用与优势
一、WebRTC与智能硬件整合趋势 随着物联网和实时通信需求的爆发式增长,WebRTC作为开源实时通信技术,为浏览器与移动应用提供免插件的音视频通信能力,在智能硬件领域的融合应用已成必然趋势。智能硬件不再局限于单一功能,对实时…...