STM32单片机入门学习——第26节: [9-2] USART串口外设

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做!

本文写于:2025.04.08

STM32开发板学习——第26节: [9-2] USART串口外设

  • 前言
  • 开发板说明
  • 引用
  • 解答和科普
  • 一、USART结构
  • 二、数据帧
  • 问题
  • 总结

前言

   本次笔记是用来记录我的学习过程,同时把我需要的困难和思考记下来,有助于我的学习,同时也作为一种习惯,可以督促我学习,是一个激励自己的过程,让我们开始32单片机的学习之路。
   欢迎大家给我提意见,能给我的嵌入式之旅提供方向和路线,现在作为小白,我就先学习32单片机了,就跟着B站上的江协科技开始学习了.
   在这里会记录下江协科技32单片机开发板的配套视频教程所作的实验和学习笔记内容,因为我之前有一个开发板,我大概率会用我的板子模仿着来做.让我们一起加油!
   另外为了增强我的学习效果:每次笔记把我不知道或者问题在后面提出来,再下一篇开头作为解答!

开发板说明

   本人采用的是慧净的开发板,因为这个板子是我N年前就买的板子,索性就拿来用了。另外我也购买了江科大的学习套间。
   原理图如下
1、开发板原理图
在这里插入图片描述
2、STM32F103C6和51对比
在这里插入图片描述
3、STM32F103C6核心板
在这里插入图片描述

视频中的都用这个开发板来实现,如果有资源就利用起来。另外也计划实现江协科技的套件。

下图是实物图
在这里插入图片描述

引用

【STM32入门教程-2023版 细致讲解 中文字幕】
还参考了下图中的书籍:
STM32库开发实战指南:基于STM32F103(第2版)
在这里插入图片描述
数据手册
在这里插入图片描述

解答和科普

一、USART结构

在这里插入图片描述
波特率发生器:就是分频器;
波特率,数据位,停止位,校验位配置;
硬件流控制,A发的太快了B原本只能抛弃新数据或者覆盖原数据,如果有硬件流控制,在硬件电路上,会多出一根线,如果B没准备好接受,置高电平,如果准备好了就置低电平,A接受到了B反馈的信号,就只会在B准备好的时候,才发数据;可以防止B处理数据慢,导致数据丢失;STM32也有,一般不用。兼容其他的的协议。
USART1(APB2) 开启时钟注意一下;
在这里插入图片描述
这里有TX和RX,这两个就是发送和接受引脚,下面的 SW_RX、IRDA_OUT/IN这些是智能卡和IRDA通信的引脚,我们不用这些协议,所以这些引脚就不用管,
在这里插入图片描述
在这里插入图片描述
发送或接收的字节数据就存在这里,上面有两个数据寄存器,一个是发送数据寄存器TDR,另一个是接受数据寄存器RDR,这两个寄存器占用同一个地址,就和51单片机串口的SBUFF寄存器一样,在程序上,只表现为一个寄存器,就是数据寄存器DR,但实际硬件中,是分成了两个寄存器,一个用于发送TDR,一个用于接受RDR,TDR是只写的,RDR是只读的,当你进行写操作时,数据就写入到TDR,当你进行读操作时,数据就是从RDR读出来的;
下面是两个移位寄存器,一个用于发送,一个用于接受,发送移位寄存器的作用就是,把一个字节的数据一位一位地移出去,正好对应串口协议的波形数据位,这两个寄存器是怎么工作的,比如你在某时刻给TDR写入了0x55这个数据,在寄存器里就是二进制存储,0101 0101,那么此时硬件检测到你写入数据了,他就会检查,当前移位寄存器是不是有数据正在移位,如果没有这个0101 0101就会立刻,全部移动到发送移位寄存器,准备发送,当数据从TDR移动到移位寄存器时,会只一个标志位,叫TXE,发送寄存器空,我们检查这个标志位,如果置1了,我们就可以在TDR写入下一个数据了,注意一下,当TXE置1时,数据其实还没有发送数据,只要数据从TDR转移到发送移位寄存器了,TXE就会置1,我们就可以写入新的数据了;

在这里插入图片描述
然后发送移位寄存器就会在下面这里的发生器控制的驱动下,向右移位,然后一位一位地,把数据输出到TX引脚,这里是向右移位的,正好和串口协议规定的低位先行,是一致的,当数据移位完成后,新的数据就会再次自动地从TDR转移到发送移位寄存器里来,如果当前移位寄存器移位还没有完成,TDR的数据就会进行等待,一但移位完成,就会立刻转移过来,有了TDR和移位寄存器的双重缓存,可以保证连续发数据的时候,数据帧之间不会
有空闲,提高了工作效率,简单来说就是你数据一但从TDR转移到移位寄存器了,管你有没有移位完成,我就立刻把下一个数据放在TDR等着,一但移完了,新的数据就会立刻跟上,这样做,效率就会比较高;
接收端也是这样,数据从RX引脚通向接受移位寄存器,在接收器控制的驱动下,一位一位地读取 RX电平,先放在最高位,然后向右移,移位8次就接收一个字节,同样,串口协议规定低位先行,所以接受移位寄存器是从高位往低位这个方向移动的,之后,当一个字节移位完成之后,这一个字节的数据就会整体地一下子转移到接受寄存器RDR里面,在转移的过程中,也会置一个标志位,叫RXNE,接受寄存器为非空,当检测到RXNE置1之后,就可以把数据读走了,同样这里也是两个寄存器缓存,当数据从移位寄存器转移到RDR时,就可以直接移位接受下一帧数据了,这就是USART外设整个的工作流程,主要功能就差不多了,就是数据寄存器和移位寄存器,发送移位寄存器往TX引脚移位,接收移位寄存器从RX引脚移位,当然发送还需加上帧头帧尾,接受还需提出帧头帧尾,这些操作,它内部有电路自动执行,

发送器控制,就是用来控制发送移位寄存器的工作的,接收器控制,用来控制接受移位寄存器的工作,左边有一个硬件流控制,简称流控,如果设备发的太快,接收设备来不及处理,就会出现丢弃或覆盖数据的现象,那有了流控,就可以避免这个问题了,这里流控有两个引脚一个是nRTS:请求发送,也就是告诉别人,我当前能不能接收,是输出脚,一个是nCTS:也就是用来接收别人的nRTS信号的,n代表的是低电平有效,首先得找另一个支持流控的串口,它的TX接到我的RX,然后我的RTS要输出一个能不能接受的反馈信号,接到对方的CTS,当我能接收的时候,RTS就置低电平,请求对方发送,对方的CTS接收到之后,就可以一直发,当我处理不过来的时候,比如接受寄存器我一直没有读,又有新的数据过来了,现在就代表我没有及时处理,那RTS就会置高电平,对方CTS接收到之后,就会暂停发送,直到这里接受寄存器数据寄存器被读走,RTS被置低电平,新的数据才会继续发送,那反过来,当我的TX给对方发送数据时,我们CTS就要接到对方的RTS,用于判断 对方能不能接受,TX和CTS是一对,RX和RTS是一对,CTS和RTS也要交叉连接,这就是流控的工作模式;

右边这块电路是用来产生同步的时钟信号,它是配合发送移位寄存器输出的,发送寄存器每移位一次,同步时钟电平就跳变一个周期,时钟告诉对方,我移出去一位数据了,你看要不要让我这个时钟信号来指导你接收一下,当然这个时钟只支持输出,不支持输入,所以两个USART之间,不能实现同步的串口通信,那这个时钟有什么用呢:第一个,兼容别的协议,比如串口加上时钟之后,就更SPI协议特别像,所以有了时钟输出的串口,就可以兼容SPI,另外这个时钟也可以做自适应波特率,比如接收设备不确定发送设备给的什么波特率,那就可以测量一下这个时钟周期,然后再计算得到波特率,不过这就需要另外写程序来实现这个功能了,这个时钟功能一般不用;

唤醒单元:这部分的作用是实现串口挂载多设备,我们之前说,串口一般是点对点的通信,点对点,只支持两个设备互相通信,想发数据直接发就行,而多设备,在一条总线上,可以接多个从设备,每个设备分配一个地址,我想和某个设备通信,就先进行寻址,确定通信对象,再进行数据收发,那回到这里,这个唤醒单元就可以用来实现多设备的功能,在这里,可以给串口分配一个地址,当你发送指定地址时,此设备唤醒开始工作,当你发送别的设备地址时候,别的设备就唤醒工作,这个设备没收到地址,就会保持沉默,这样就可以实现多设备的串口通信了,一般也不用;

中断输出控制,中断申请位,就是状态寄存器这里的各种标志位,状态寄存器这里,有两个标志位比较重要,一个是TXE发送寄存器,另一个是RXNE接受寄存器非空,这两个是判断发送状态和接受状态的必要标志位,剩下的标志位,了解一下就行;
中断输出控制:就是配置中断是不是能通向NVIC;
最下面时波特率发生器:其实就是分频器,APB时钟进行分频,得到发送和接受移位的时钟,这里时钟输入是fPCLKx(x=1或2), USART1挂载在APB2,所以就是PCLK2的时钟,一般是72M,其他的都挂载在APB1,所以是PCLK1的时钟,一般是36M,之后这个时钟进行分频,除以个USARTDIV的分频系数,USARTDIV里面就是右边这样,是一个数值,并且分为了整数部分和小数部分,因为有些波特率,用72M除一个整数的话,可能除不尽,会有误差,所以这里分频系数是支持小数点后4位的,分频就更加精准,之后分频完之后,还要再除个16,得到发送器时钟和接收器时钟,通向控制部分,然后右边这里,如果TE(TX Enable)为1,就是发送器使能了,发送部分的波特率就有效;如果RE为1,那就是接收器使能了,接收部分的波特率就有效。到这里这个串口的主体结构就看完了。
看看寄存器描述,就知道怎么控制的。

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

在这里插入图片描述

在这里插入图片描述
这些引脚都必须按照引脚定义里规定的来,或者看看有没有重映射。
在这里插入图片描述
最左边是波特率发生器,用于产生约定的通信速率,时钟来源是PCLK2或1,经过波特率分频器后,产生的时钟通向发送控制器和接收控制器,发送控制器和接收控制器,用来控制发送移位和接收移位,之后,由发送数据寄存器和发送移位寄存器这两个寄存器的配合,将数据一位一位地移出去,通过GPIO的复用输出,输出到TX引脚,产生串口协议规定的波形,这里画了几个右移的符号,就是代表这个移位寄存器是往右移的,是低位先行,当数据由数据寄存器转到移位寄存器时,会置一个TXE的标志位,我们判断这个标志位,就可以知道是不是可以写下一个数据了,然后接收部分也是类似;
RX引脚的波形,通过GPIO输入,在接收控制器的控制下,一位一位地移入接收移位寄存器,这里画了右移的符号,也是右移的,因为是低位先行,所以要从左边开始移进来,移完一帧数据后,数据就会统一转运到接受数据寄存器,在转移的同时,置一个RXNE标志位,我们检查这个标志位,就可以知道是不是收到数据了,同时这个标志位也是可以去申请中断,这样就可以在收到数据时,直接进入中断函数,然后快速地读取和保存数据,那右边实际上有四个寄存器,但在软件寄存器,只有一个DR寄存器可以供我们读写,写入DR时,数据走上面这条路,进行发送,读取DR时,数据走下面这条路,进行接收,这就是USART进行串口数据收发的过程;
最后右下角,是一个开关控制,就是配置完成之后,用Cmd开启一下外设。

二、数据帧

在这里插入图片描述
这个图是在程序中配置8位字长和9位字长的波形比较,这里的字长就是前面说的数据位长度,它这里的字长,是包含校验位的额,是这种描述方式。
第一条时序,很明显就是TX发送或者RX接收的数据帧格式,空闲高电平,然后起始位0,然后根据写入的数据,置1或0,一次发送位0到位8,加起来就是9位,最后停止位1,数据帧结束;在这里位8,也就是第9个位置,是一个可能的奇偶校验位,通过配置寄存器就可以配置成奇校验、偶校验或者无校验,这里可以选择配置成8位有效载荷+1位校验位,也可以选择9位全都是有效载荷,不过既然选择了9位字长,一般都是要加上校验位的,因为8位有效载荷,正好对应一个字节;
下面这个时钟,就是之前说的同步时钟输出的功能,可以看到,这里在每个数据位的中间,都有一个时钟上升沿,时钟的频率,和数据速率也是一样的,接收端可以在时钟上升沿进行采样,这样就可以精准定位每一位数据,这个时钟的最后一位,可以通过这个LBCL位控制,要不要输出,另外这个时钟的极性、相位什么的,也是可以通过配置寄存器配置;
一个是空闲帧,一个是断开帧是局域网用的。

8位字长的波形,这里的数据位是从位0一直到位7,总共是8位,比上面这个少了一个位8,同样这个最后一位位7,也是一个可能的奇偶校验位,还是同样既然你选择了8位字长,那这里最好就选择无校验,要不然你校验位占1位,有效载荷就剩下7位了,一个字节都发不了;总共有4种选择:9位字长,有校验无校验,8位字长,有校验无校验;最好选择9位字长,有校验或者8位字长,无校验这两种,这样每一帧的有效载荷都会死一个字节,比较舒服。

在这里插入图片描述
数据帧不同停止位:STM32串口可以配置停止位长度为0.5,1,1.5,2这四种,这四种参数的区别就是停止位的时长不一样:
1个停止位:这时停止位的时长就和数据位的一位,时长一样;
1.5个停止位:这时停止位就是数据位一位时长的1.5倍;
2个停止位:这时停止位就是数据位一位时长的2倍;
0.5个停止位:这时停止位就是数据位一位时长的0.5倍.
在这里插入图片描述
这两个图展示的是USART电路输入数据的一些策略:对于串口来说,根据前面的介绍,可以想到,串口的输出TX应该是比输入RX简单很多,输入你就定时翻转TX引脚高低电平就行了,但是输入,就复杂一些,你不仅要保证,输入的采样频率和波特率一致, 还要保证每次输入采样的位置,要正好处于每一位的正中间,只有在每个电平的正中间采样,这样的高低电平读进来,才是最可靠的,如果你采样点过于靠前或者靠后,那就可能高低电平还在翻转,电平还不稳定,或者少有误差,数据就采样错了,另外,输入最后还要对噪声有一定的判断能力,如果是噪声,最好能置个标志位提醒我一下,这些就是输入数据所面临的问题,那看一下STM32是如何来设计输入电路的。
首先第一个图,这里展示的是USART的起始位 帧测 ,当输入电路侦测到一个数据帧的起始位后,就会以波特率的频率,连续采样一帧数据,同时,从起始位开始,采样位置就要对齐到位的正中间,只要第一位对齐了,后面就肯定都是对齐的,那为了实现这些功能,首先输入的这部分电路对采样时钟进行了细分,它会以波特率的16倍频率进行采样,也就是在一位的时间里,可以进行16次采样,最开始,空闲状态高电平,那采样就一直是1,在某个位置,突然采到一个0,那么就说明,在这两次采样之间,出现了下降沿,如果没有噪声,那之后就应该是起始位了,在起始位,会进行连续16次采样,没有噪声的话,这16位采样肯定就都是0,这没问题,但是实际电路还是会存在一些噪声的,所以及时这里出现下降沿了,后续也要再采样几次,以防万一,根据手册的描述,这会接收电路,还会在下降沿之后的第3次、5次、7次,进行一批采样,在第8次、9次、10次,再进行一批采样,且这两批采样,都要要求每3位里面至少应有2个0,没有噪声,那肯定全是0,满足情况,如果有一些轻微噪声,导致这3位里面只有两个0,另一个是1,那也算是检测到了起始位,但是在状态寄存器会置一个NE,噪声标志位,就是提醒你一下,数据我收到了,但是有噪声,你小心点,如果这三位只有一个0,那就不算检测到了起始位,可能前面那个下降沿是噪声导致的,这时电路就忽略前面的数据,重新开始捕捉下降沿,这就是STM32的串口,在接收过程中,对噪声的处理,如果通过了这个起始位侦测,那接受状态就由空闲,变为接收起始位,同时第8、9、10次采样的位置,就正好是起始位的正中间,之后,接收数据位时,就都在第8、9、10次,进行采样,这样就能保证采样位置在位的正中间了,这就是起始位侦测和采样位置对齐的策略;

在这里插入图片描述

这里,从1到16,是一个数据位的时间长度,在一个数据位,有16个采样时钟,由于起始位侦测已经对齐了采样时钟,所以这里就直接在第8、9、10次采样数据位,为了保证数据的可靠性,这里是连续采样3次,没有噪声的理想情况下,这3次肯定全为1或者全为0,全为1,就认为收到了1,全为0,就认为收到了0,如果有噪声,导致3次采样不是全为1,或者全为0,那就按照2:1的规则来,2次为1,那就认为收到了1,在这种情况下,噪声标志位NE也会置1,告诉你,我收到数据了,但是有噪声,你小心点,这就是检测噪声的数据采样,可见STM32对这个电路的设计考虑还是很充分的;
在这里插入图片描述
波特率发生器就是分频器,发送器和接收器的波特率由波特率寄存器BRR里面的DIV确定,DIV分为整数和小数部分,可以实现更细腻的分频,那波特率和分频系数的关系,可以由这个计算公式进行计算:波特率=PCLK2/1的时钟频率/16倍的DIV,为什么这里多了一个16,因为它内部还有一个16倍波特率的采样时钟,所以这里输入时钟/DIV要等于16倍的波特率,最终计算波特率,自然要多除一个16了,几个例子,比如我要配置USART1为9600的波特率,那如何配置这个BRR寄存器,代入公式,9600=72M/(16*DIV),解出来DIV=72M/9600/16,468.75,转换成二进制,11101 0100 .11;
在这里插入图片描述

最左边是USB端口,USB有四根线,GND、D+、D-、VCC, USB标准供电时5V,然后中间D+和D-是通信线,走的也是USB协议,所以这里需要一个CH340芯片转换一下,转换之后输出的就是TXD和RXD,是串口协议,最后通过排针引出来,那需要注意的就是这边的供电策略,首先,所有的电都是这个VCC+5V来的,然后VCC+5V通过这个稳压管电路进行降压,得到VCC+3.3V,之后VCC+5V和VCC+3.3V,都通过排针引出来了,所以这个第6脚和第4脚,是分别有5V和3.3V输出的,很多人迷惑的是这个第5脚,板子上标的是VCC,这个引脚,通过原理图可以看到,它是通向CH340芯片的VCC上,所以这个第5脚,实际上是CH340的电影输入脚,一般我们这个模块的排针会有一个跳线帽,这个跳线帽需要插在4、5脚或者5、6脚上,右边也有文字说明,5V到VCC,CH340供电为5V,TTL电平为5V,短路3V3到VCC,CH340供电为3.3V,TTL电平为3.3V,所以这个跳线帽是用来选择通信电平的,也是给CH340供电的,所以最好不要拿掉,如果你拿掉了,就相当于这整个芯片,没有供电,即使把跳线帽拔掉,不给芯片供电,这个串口还是能工作的,可能是从别的地方汲取的电流,也有可能是其他地方,测试一下,不差跳线帽,通信电平是3.3V,不过为了稳定,最好还是插上跳线帽,STM32通信需要3.3V,所以把跳线帽插在4,5脚上就行了。

然后就是数据手册了。

问题

总结

本节课主要学了STM32的USART串口的外设,以及工作流程是什么样的,最左边是波特率发生器,用于产生约定的通信速率,时钟来源是PCLK2或1,经过波特率分频器后,产生的时钟通向发送控制器和接收控制器,发送控制器和接收控制器,用来控制发送移位和接收移位,之后,由发送数据寄存器和发送移位寄存器这两个寄存器的配合,将数据一位一位地移出去,通过GPIO的复用输出,输出到TX引脚,产生串口协议规定的波形,这里画了几个右移的符号,就是代表这个移位寄存器是往右移的,是低位先行,当数据由数据寄存器转到移位寄存器时,会置一个TXE的标志位,我们判断这个标志位,就可以知道是不是可以写下一个数据了,然后接收部分也是类似;
RX引脚的波形,通过GPIO输入,在接收控制器的控制下,一位一位地移入接收移位寄存器,这里画了右移的符号,也是右移的,因为是低位先行,所以要从左边开始移进来,移完一帧数据后,数据就会统一转运到接受数据寄存器,在转移的同时,置一个RXNE标志位,我们检查这个标志位,就可以知道是不是收到数据了,同时这个标志位也是可以去申请中断,这样就可以在收到数据时,直接进入中断函数,然后快速地读取和保存数据,那右边实际上有四个寄存器,但在软件寄存器,只有一个DR寄存器可以供我们读写,写入DR时,数据走上面这条路,进行发送,读取DR时,数据走下面这条路,进行接收,这就是USART进行串口数据收发的过程;
最后右下角,是一个开关控制,就是配置完成之后,用Cmd开启一下外设。
还学习了USB转串口的原理图。

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

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

相关文章

【学Rust写CAD】31 muldiv255函数(muldiv255.rs,已经取消)

源码 // Calculates floor(a*b/255 0.5) #[inline] pub fn muldiv255(a: u32, b: u32) -> u32 {// The deriviation for this formula can be// found in "Three Wrongs Make a Right" by Jim Blinn.let tmp a * b 128;(tmp (tmp >> 8)) >> 8 }代…

LLM+js实现大模型对话

代码运行效果图&#xff1a;前提是你有一个可用的openai服务&#xff0c;然后用下面一个html页即可启动 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthd…

用claude3.7,不到1天写了一个工具小程序(11个工具6个游戏)

一、功能概览和本文核心 本次开发&#xff0c;不是1天干撸&#xff0c;而是在下班后或早起搞的&#xff0c;总体加和计算了一下&#xff0c;大概1天的时间&#xff08;12个小时&#xff09;&#xff0c;平常下班都是9点的衰仔&#xff0c;好在还有双休&#xff0c;谢天谢地。 …

C++实现文件断点续传:原理剖析与实战指南

文件传输示意图 一、断点续传的核心价值 1.1 大文件传输的痛点分析 网络闪断导致重复传输&#xff1a;平均重试3-5次。 传输进度不可回溯&#xff1a;用户无法查看历史进度。 带宽利用率低下&#xff1a;每次中断需从头开始。 1.2 断点续传技术优势 指标传统传输断点续传…

升级 SAP S/4 HANA 之 EWM 攻略

目录 简介 知识点 数据迁移 简介 仓库管理&#xff0c;SAP 升级不管是否启动 EWM 功能&#xff0c;评估 EWM 是必经之路&#xff0c;不仅是因为 EWM 是 SAP 主推的仓库解决方案&#xff0c;更是其功能强大而便捷&#xff0c;不管是简易仓库、复杂仓库、立体仓库、高架仓库、…

知识表示方法之六:过程表示法(Procedural Representation)

在人工智能的发展史中&#xff0c;关于知识的表示方法曾存在两种不同的观点。一种观点认为知识主要是陈述性的&#xff0c;其表示方法应着重将其静态特性&#xff0c;即事物的属性以及事物间的关系表示出来&#xff0c;称以这种观点表示知识的方法为陈述式或说明式表示法&#…

绿色供应链管理体系认证:开启企业可持续发展的绿色新篇章

在全球“双碳”目标驱动下&#xff0c;绿色供应链管理已成为企业高质量发展的核心议题。据国际权威机构预测&#xff0c;到2030年&#xff0c;绿色供应链相关市场规模将突破万亿美元。在此背景下&#xff0c;绿色供应链管理体系认证不仅是企业合规的“通行证”&#xff0c;更是…

MATLAB如何打印一个桃心形状

在MATLAB中打印一个桃心形状&#xff0c;您可以使用绘图函数来创建一个心形图案。以下是一个简单的例子&#xff0c;展示了如何使用MATLAB绘制一个心形&#xff1a; 定义心形的参数方程&#xff1a;心形可以通过一组参数方程来描述。 使用MATLAB的绘图函数&#xff1a;plot函…

前端知识(vue3)

1.Vue3 1.1 介绍 Vue&#xff08;读音 /vjuː/, 类似于 view&#xff09;是一款用于构建用户界面的渐进式的JavaScript框架 官网&#xff1a;https://cn.vuejs.org 1.2 常见指令 指令&#xff1a;指的是HTML 标签上带有 v- 前缀的特殊属性&#xff0c;不同指令具有不同含义…

状态机思想编程

1. LED流水灯的FPGA代码 一个使用状态机思想来实现LED流水灯的FPGA代码 这个例子采用VHDL编写 VHDL代码示例&#xff1a; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;entity led_flowing isPort ( clk …

网络安全小知识课堂(五)

病毒与蠕虫&#xff1a;你的电脑为何会 “生病” 和 “传染”&#xff1f; 引言 你是否见过这样的场景&#xff1a;电脑突然弹窗广告暴增&#xff0c;文件莫名消失&#xff0c;甚至整个公司网络集体瘫痪&#xff1f;这些症状背后&#xff0c;可能是 ** 病毒&#xff08;Virus…

RVOS-1.环境搭建与系统引导

0.环境搭建 riscv-operating-system-mooc: 开放课程《循序渐进&#xff0c;学习开发一个 RISC-V 上的操作系统》配套教材代码仓库。 mirror to https://github.com/plctlab/riscv-operating-system-mooc 在 Ubuntu 20.04 以上环境下我们可以直接使用官方提供的 GNU工具链和 QEM…

UNet 改进(5):结合SE模块提升图像分割性能

U-Net是医学图像分割领域最成功的架构之一&#xff0c;其对称的编码器-解码器结构和跳跃连接使其能够有效捕捉多尺度特征。本文将解析一个改进版的U-Net实现&#xff0c;该版本通过引入Squeeze-and-Excitation(SE)模块进一步提升了模型性能。 一、架构概览 这个改进的U-Net保持…

机器人拧螺丝紧固装配(Robot screw fastening assembly)

机器人拧螺丝紧固装配技术正以其高精度、高效率和高灵活性&#xff0c;重塑着传统制造业的生产范式。这项融合了机械臂定位、扭矩控制、视觉引导与数据分析的自动化解决方案&#xff0c;不仅将工人从重复性高强度劳动中解放出来&#xff0c;更通过实时数据反馈与精准执行&#…

图像处理中的 Gaussina Blur 和 SIFT 算法

Gaussina Blur 高斯模糊 高斯模糊的数学定义 高斯模糊是通过 高斯核(Gaussian Kernel) 对图像进行卷积操作实现的. 二维高斯函数定义为 G ( x , y , σ ) 1 2 π σ 2 e − x 2 y 2 2 σ 2 G(x, y, \sigma) \frac{1}{2\pi \sigma^2} e^{-\frac{x^2 y^2}{2\sigma^2}} G(x…

在Unity中实现《幽灵行者》风格的跑酷动作

基础设置 角色控制器选择&#xff1a; 使用Character Controller组件或Rigidbody Capsule Collider 推荐使用Character Controller以获得更精确的运动控制 输入系统&#xff1a; 使用Unity的新输入系统(Input System Package)处理玩家输入 滑铲实现 public class Slide…

青蛙吃虫--dp

1.dp数组有关元素--路长和次数 2.递推公式 3.遍历顺序--最终影响的是路长&#xff0c;在外面 其次次数遍历&#xff0c;即这次路长所有情况都更新 最后&#xff0c;遍历次数自然就要遍历跳长 4.max时时更新 dp版本 #include<bits/stdc.h> using namespace std; #def…

Tiktok 关键字 视频及评论信息爬虫(2) [2025.04.07]

&#x1f64b;‍♀️Tiktok APP的基于关键字检索的视频及评论信息爬虫共分为两期&#xff0c;希望对大家有所帮助。 第一期&#xff1a;基于关键字检索的视频信息爬取 第二期见下文。 1.Node.js环境配置 首先配置 JavaScript 运行环境&#xff08;如 Node.js&#xff09;&…

Matlab绘图—‘‘错误使用 plot输入参数的数目不足‘‘

原因1&#xff1a; ❤️ 文件列名不是合法变量名 在excel中数据列名称为Sample:float,将:删除就解决了

Kotlin问题汇总

Kotlin问题汇总 真机安装调试 查看真机的Android版本&#xff0c;将build.gradle文件中的minSdk改为手机的Android版本&#xff0c;点Sync Now更新设置 apk安装失败 在gradle.properties全局配置中设置android.injected.testOnlyfalse Unresolved reference: 在activity_…