<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="/rss.xsl"?>

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Embedded Development on NomadJoe</title>
        <link>https://NomadJoeviolet.github.io/categories/embedded-development/</link>
        <description>Recent content in Embedded Development on NomadJoe</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <copyright>NomadJoe</copyright>
        <lastBuildDate>Thu, 09 Apr 2026 19:44:59 +0800</lastBuildDate><atom:link href="https://NomadJoeviolet.github.io/categories/embedded-development/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>基于CubeMX的STM32学习笔记</title>
        <link>https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</link>
        <pubDate>Thu, 09 Apr 2026 19:44:59 +0800</pubDate>
        
        <guid>https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</guid>
        <description>&lt;p&gt;个人学习笔记&lt;/p&gt;
&lt;h2 id=&#34;中断简介&#34;&gt;中断简介
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;中断定义&lt;/strong&gt;
CPU执行程序中，由于发生了某种随机的事件(外部或内部)，引起CPU暂时 中断正在运行的程序，转去执行一段特殊的服务程序(称为中断服务程序或 中断处理程序)，以处理该事件，该事件处理完后又返回被中断的程序继续 执行，这一过程称为中断
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E4%B8%AD%E6%96%AD%E5%9B%BE%E5%BD%A2%E5%8C%96%E5%B1%95%E7%A4%BA.png&#34;
	width=&#34;1079&#34;
	height=&#34;273&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E4%B8%AD%E6%96%AD%E5%9B%BE%E5%BD%A2%E5%8C%96%E5%B1%95%E7%A4%BA_hu11109119314971648775.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E4%B8%AD%E6%96%AD%E5%9B%BE%E5%BD%A2%E5%8C%96%E5%B1%95%E7%A4%BA_hu369186688277173012.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;395&#34;
		data-flex-basis=&#34;948px&#34;
	
&gt;
对于单片机来说&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;中断事件发生&lt;/li&gt;
&lt;li&gt;产生中断信号&lt;/li&gt;
&lt;li&gt;单片机接收到中断信号，停止执行当前函数，跳转至中断处理函数&lt;/li&gt;
&lt;li&gt;执行完中断处理函数后，单片机自动跳转回主函数执行被中断处&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;nvic&#34;&gt;NVIC
&lt;/h3&gt;
&lt;p&gt;NVIC是嵌套向量中断控制器，控制着整个芯片中断相关的功能，它跟内核紧密耦合，是内核里面的一个外设。同时掌控中断优先级和中断向量表。&lt;/p&gt;
&lt;h3 id=&#34;中断流程&#34;&gt;中断流程
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E4%B8%AD%E6%96%AD%E6%B5%81%E7%A8%8B.png&#34;
	width=&#34;809&#34;
	height=&#34;347&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E4%B8%AD%E6%96%AD%E6%B5%81%E7%A8%8B_hu16743848446356959870.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E4%B8%AD%E6%96%AD%E6%B5%81%E7%A8%8B_hu13285446596805099177.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;233&#34;
		data-flex-basis=&#34;559px&#34;
	
&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;请求挂起寄存器的改变由外设导致&lt;/li&gt;
&lt;li&gt;中断信号传递至&lt;code&gt;NVIC&lt;/code&gt;，然后&lt;code&gt;NVIC&lt;/code&gt;查找对应中断向量，执行中断处理函数&lt;/li&gt;
&lt;li&gt;另外中断处理函数都需要去清除请求挂起寄存器对应位，避免中断处理函数被重复调用&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;hal库的中断处理及回调函数实现流程&#34;&gt;HAL库的中断处理及回调函数实现流程
&lt;/h3&gt;
&lt;p&gt;首先是外设发出中断请求信号，&lt;code&gt;NVIC&lt;/code&gt;接收到后会根据中断向量表查询对应中断处理函数的入口，在&lt;code&gt;HAL&lt;/code&gt;中是对应外设的&lt;code&gt;外设number_IRQHandler&lt;/code&gt;，然后再进入&lt;code&gt;HAL&lt;/code&gt;库统一的外设中断处理函数&lt;code&gt;HAL_外设_IRQHandler&lt;/code&gt;，再调用对应的回调函数
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E4%B8%AD%E6%96%AD%E6%9C%BA%E5%88%B6%E5%9B%BE%E8%A7%A3.png&#34;
	width=&#34;4617&#34;
	height=&#34;1803&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E4%B8%AD%E6%96%AD%E6%9C%BA%E5%88%B6%E5%9B%BE%E8%A7%A3_hu11704804992811952000.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E4%B8%AD%E6%96%AD%E6%9C%BA%E5%88%B6%E5%9B%BE%E8%A7%A3_hu13115145147307207397.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;256&#34;
		data-flex-basis=&#34;614px&#34;
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;nvic嵌套向量中断控制器&#34;&gt;NVIC嵌套向量中断控制器
&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-NVIC%E4%B8%AD%E6%96%AD%E5%90%91%E9%87%8F%E8%A1%A8.png&#34;
	width=&#34;747&#34;
	height=&#34;573&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-NVIC%E4%B8%AD%E6%96%AD%E5%90%91%E9%87%8F%E8%A1%A8_hu888945057154268459.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-NVIC%E4%B8%AD%E6%96%AD%E5%90%91%E9%87%8F%E8%A1%A8_hu13410774968200508393.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;130&#34;
		data-flex-basis=&#34;312px&#34;
	
&gt;
&lt;code&gt;NVIC&lt;/code&gt;会一直检测某一个中断线是否处于激活状态，当中断处理函数运行完成后，需要在中断处理函数中将请求挂起寄存器对应的位清除为0，避免&lt;code&gt;NVIC&lt;/code&gt;一直检测到1，一直重复执行中断处理函数，而这一部分代码，在&lt;code&gt;HAL&lt;/code&gt;库写的总&lt;code&gt;IRQHandler&lt;/code&gt;中已经完成。&lt;/p&gt;
&lt;p&gt;另外，&lt;code&gt;NVIC&lt;/code&gt;对于中断还有中断优先级的设置，&lt;code&gt;stm32f103c8t6&lt;/code&gt;中断优先级由&lt;code&gt;NVIC&lt;/code&gt;的优先级寄存器里的4位决定。中断优先级分为抢占优先级和响应优先级（它们一起用这4位）&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;抢占优先级的级别越高，越能够抢占中断通道，优先执行中断&lt;/li&gt;
&lt;li&gt;响应优先级的级别越高，可以优先排队。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中断的优先级，都是数字越小，优先级越高&lt;/strong&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-NVIC%E4%B8%AD%E6%96%AD%E4%BC%98%E5%85%88%E7%BA%A7%E8%AE%BE%E7%BD%AE.png&#34;
	width=&#34;1218&#34;
	height=&#34;375&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-NVIC%E4%B8%AD%E6%96%AD%E4%BC%98%E5%85%88%E7%BA%A7%E8%AE%BE%E7%BD%AE_hu16306281975614368527.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-NVIC%E4%B8%AD%E6%96%AD%E4%BC%98%E5%85%88%E7%BA%A7%E8%AE%BE%E7%BD%AE_hu7054262566145385.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;324&#34;
		data-flex-basis=&#34;779px&#34;
	
&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;exti外部中断&#34;&gt;EXTI外部中断
&lt;/h2&gt;
&lt;h3 id=&#34;exti外部中断实现&#34;&gt;EXTI外部中断实现
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-GPIO%E7%9A%84EXTI%E6%A8%A1%E5%BC%8F%E7%A1%AC%E4%BB%B6%E5%9B%BE.png&#34;
	width=&#34;1160&#34;
	height=&#34;582&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-GPIO%E7%9A%84EXTI%E6%A8%A1%E5%BC%8F%E7%A1%AC%E4%BB%B6%E5%9B%BE_hu715386912825956584.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-GPIO%E7%9A%84EXTI%E6%A8%A1%E5%BC%8F%E7%A1%AC%E4%BB%B6%E5%9B%BE_hu4992292154030760620.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;199&#34;
		data-flex-basis=&#34;478px&#34;
	
&gt;
&lt;code&gt;EXTI&lt;/code&gt; 可分为两大部分功能，一个是产生中断，另一个是产生事件，这两个功能从硬件上就有所不同。我们的主要关注点是中断。
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E5%A4%96%E9%83%A8%E4%B8%AD%E6%96%AD%E4%BA%8B%E4%BB%B6%E6%8E%A7%E5%88%B6%E5%99%A8.png&#34;
	width=&#34;1944&#34;
	height=&#34;1052&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E5%A4%96%E9%83%A8%E4%B8%AD%E6%96%AD%E4%BA%8B%E4%BB%B6%E6%8E%A7%E5%88%B6%E5%99%A8_hu7594255552516290353.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E5%A4%96%E9%83%A8%E4%B8%AD%E6%96%AD%E4%BA%8B%E4%BB%B6%E6%8E%A7%E5%88%B6%E5%99%A8_hu16082129239239522654.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;184&#34;
		data-flex-basis=&#34;443px&#34;
	
&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;边沿检测电路用来检测输入的电平信号的高低电平的转换，同时会根据 上升沿/下降沿触发选择寄存器来决定是否向后产生高电平信号&lt;/li&gt;
&lt;li&gt;软件中断事件寄存器使用软件来模拟产生一个中断&lt;/li&gt;
&lt;li&gt;请求挂起寄存器接收到高电平后会将对应通道的位置1（例如EXTI_9产生高电平进入请求挂起寄存器，则该寄存器会将第9位置1）&lt;/li&gt;
&lt;li&gt;最后上面的线路就会进入&lt;code&gt;NVIC(嵌套向量中断控制器)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;下面的线路，脉冲发生器作为事件信号送到对应外设，这个脉冲信号可以给其他外设电路使用，比如定时器TIM、模拟数字转换器ADC等等，这样的脉冲信号一般用来触发TIM或者ADC开始转换
产生中断线路目的是把输入信号输入到&lt;code&gt;NVIC&lt;/code&gt;，进一步会运行中断服务函数，实现功能，这样是软件级的。
产生事件线路目的就是传输一个脉冲信号给其他外设使用，并且是电路级别的信号传输，属于硬件级的。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;调用流程&#34;&gt;调用流程
&lt;/h3&gt;
&lt;p&gt;以&lt;code&gt;EXTI1&lt;/code&gt;为例，下降沿触发，当出现下降沿时，就会触发&lt;code&gt;EXTI5&lt;/code&gt;的外部中断，进入&lt;code&gt;EXTI9_5_IRQHandler&lt;/code&gt;，在&lt;code&gt;EXTI9_5_IRQHandler&lt;/code&gt;中调用&lt;code&gt;HAL_GPIO_EXTI_IRQHandler&lt;/code&gt;函数统一处理外部中断，在该函数中对挂起寄存器进行清0操作，并调用&lt;code&gt;HAL_GPIO_EXTI_Callback&lt;/code&gt;中断回调函数&lt;/p&gt;
&lt;h3 id=&#34;按键实现外部中断控制小灯亮灭&#34;&gt;按键实现外部中断控制小灯亮灭
&lt;/h3&gt;
&lt;h4 id=&#34;cube配置&#34;&gt;Cube配置
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-Cube%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;688&#34;
	height=&#34;736&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-Cube%E9%85%8D%E7%BD%AE_hu10381672920257679102.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-Cube%E9%85%8D%E7%BD%AE_hu2006250321636698059.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;93&#34;
		data-flex-basis=&#34;224px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;exti配置&#34;&gt;EXTI配置
&lt;/h4&gt;
&lt;p&gt;打开中断&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-EXTI%E4%B8%AD%E6%96%AD%E5%BC%80%E5%90%AF.png&#34;
	width=&#34;697&#34;
	height=&#34;99&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-EXTI%E4%B8%AD%E6%96%AD%E5%BC%80%E5%90%AF_hu14162493153675042262.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-EXTI%E4%B8%AD%E6%96%AD%E5%BC%80%E5%90%AF_hu6564623695607794588.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;704&#34;
		data-flex-basis=&#34;1689px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;配置的是下降沿触发，检测下降沿，上拉模式
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-EXTI%E6%A8%A1%E5%BC%8F.png&#34;
	width=&#34;681&#34;
	height=&#34;185&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-EXTI%E6%A8%A1%E5%BC%8F_hu9443233446426704176.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-EXTI%E6%A8%A1%E5%BC%8F_hu3534635838158394966.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;368&#34;
		data-flex-basis=&#34;883px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;配置参数解释&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;上升沿触发：指的是当引脚电平从低电平(0)转变为高电平(1)时，触发事件&lt;/li&gt;
&lt;li&gt;下降沿触发：指的是当引脚电平从高电平(1)转变为低电平(0)时，触发事件&lt;/li&gt;
&lt;li&gt;双边沿触发：指的是当引脚的电平发生任何变化（即从低电平到高电平或从高电平到低电平）时，都会触发事件&lt;/li&gt;
&lt;li&gt;上拉：指使引脚在未连接（悬空）时默认为 高电平(1)&lt;/li&gt;
&lt;li&gt;下拉：指使引脚在未连接（悬空）时默认为 低电平(0)&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;gpio配置&#34;&gt;GPIO配置
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-EXTI%E7%9A%84GPIO%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;672&#34;
	height=&#34;239&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-EXTI%E7%9A%84GPIO%E9%85%8D%E7%BD%AE_hu2535807990968646796.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-EXTI%E7%9A%84GPIO%E9%85%8D%E7%BD%AE_hu13095151565543276717.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;281&#34;
		data-flex-basis=&#34;674px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;推挽模式，初始输出为&lt;code&gt;Low&lt;/code&gt;低电平&lt;/p&gt;
&lt;h4 id=&#34;按键消抖&#34;&gt;按键消抖
&lt;/h4&gt;
&lt;h4 id=&#34;方式1&#34;&gt;方式1
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_GPIO_EXTI_Callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_Pin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//外部中断回调函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_Pin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_PIN_5&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	    &lt;span class=&#34;c1&#34;&gt;//HAL_Delay(10);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;72000&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//空循环延时
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	    &lt;span class=&#34;nf&#34;&gt;HAL_GPIO_TogglePin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPIOA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_PIN_2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;方式2&#34;&gt;方式2
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;lastTick&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_GPIO_EXTI_Callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_Pin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//外部中断回调函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_Pin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_PIN_5&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_GetTick&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lastTick&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;150&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;nf&#34;&gt;HAL_GPIO_TogglePin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPIOA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_PIN_2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;n&#34;&gt;lastTick&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_GetTick&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;代码实现&#34;&gt;代码实现
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;lastTick&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_GPIO_EXTI_Callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_Pin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//外部中断回调函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_Pin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_PIN_5&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_GetTick&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lastTick&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;150&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;nf&#34;&gt;HAL_GPIO_TogglePin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPIOA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_PIN_2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;n&#34;&gt;lastTick&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_GetTick&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;tim定时器定时中断&#34;&gt;TIM定时器定时中断
&lt;/h2&gt;
&lt;p&gt;在&lt;code&gt;f103c8t6&lt;/code&gt;中，&lt;code&gt;TIM1&lt;/code&gt;是高级定时器，&lt;code&gt;TIM2&lt;/code&gt;，&lt;code&gt;TIM3&lt;/code&gt;，&lt;code&gt;TIM4&lt;/code&gt;是通用计时器
下面例子中配置的是&lt;code&gt;TIM1&lt;/code&gt;，实现每秒翻转1次小灯亮灭&lt;/p&gt;
&lt;h3 id=&#34;调用流程-1&#34;&gt;调用流程
&lt;/h3&gt;
&lt;p&gt;触发更新中断后进入更新中断服务函数&lt;code&gt;TIM1_UP_IRQHandler&lt;/code&gt;，其中调用&lt;code&gt;HAL_TIM_IRQHandler&lt;/code&gt;，在该函数中调用了&lt;code&gt;HAL_TIM_PeriodElapsedCallback&lt;/code&gt;回调函数&lt;/p&gt;
&lt;h3 id=&#34;cubemx参数配置&#34;&gt;CubeMX参数配置
&lt;/h3&gt;
&lt;p&gt;使用内部时钟模式&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F.png&#34;
	width=&#34;675&#34;
	height=&#34;177&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F_hu5309645045050208546.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F_hu9881976903012931188.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;381&#34;
		data-flex-basis=&#34;915px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;参数配置如下，实现1s触发一次定时器更新中断&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;686&#34;
	height=&#34;237&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE_hu12829645387105645740.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE_hu162320815802914554.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;289&#34;
		data-flex-basis=&#34;694px&#34;
	
&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Prescaler&lt;/code&gt;:预分频，实际分频数是&lt;code&gt;number+1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Counter Mode&lt;/code&gt;:计数模式设置&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Counter Period&lt;/code&gt;:自动重装载计数器计数值&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Internal Clock Division&lt;/code&gt;:内部时钟预分频&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Repetition Counter&lt;/code&gt;:重复计数器 (&lt;strong&gt;RCR&lt;/strong&gt; -8 bits)，属于高级控制寄存器专用寄存器位，利用它可以非常容易控制输出 PWM 的个数，与内部时钟模式无关&lt;/li&gt;
&lt;li&gt;&lt;code&gt;auto-reload preload&lt;/code&gt;:是否开启影子寄存器模式&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;还需要开启定时器更新中断
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD.png&#34;
	width=&#34;685&#34;
	height=&#34;165&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD_hu3931705140757947726.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD_hu9647680572974795723.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;415&#34;
		data-flex-basis=&#34;996px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;代码实现-1&#34;&gt;代码实现
&lt;/h3&gt;
&lt;p&gt;用的&lt;code&gt;PA2&lt;/code&gt;作&lt;code&gt;GPIO&lt;/code&gt;输出&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_TIM_PeriodElapsedCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;nf&#34;&gt;HAL_GPIO_TogglePin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPIOA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPIO_PIN_2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN 1 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END 1 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* MCU Configuration--------------------------------------------------------*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Reset of all peripherals, Initializes the Flash interface and the Systick. */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;HAL_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN Init */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END Init */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Configure the system clock */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;SystemClock_Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN SysInit */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END SysInit */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Initialize all configured peripherals */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;MX_GPIO_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;MX_TIM1_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN 2 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nf&#34;&gt;HAL_TIM_Base_Start_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END 2 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Infinite loop */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN WHILE */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* USER CODE END WHILE */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN 3 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END 3 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;usart中断&#34;&gt;USART中断
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;USART&lt;/code&gt;的轮询模式会阻塞程序运行，浪费CPU资源&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;说明：本节保留“中断视角”的基础讲解；若需要串口 + DMA + 空闲中断的完整实践，请结合后文“UART、DMA与空闲中断（综合）”章节阅读。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;轮询模式&#34;&gt;轮询模式
&lt;/h3&gt;
&lt;p&gt;CPU不断查询发送数据寄存器或者接受数据寄存器导致程序的阻塞&lt;/p&gt;
&lt;h4 id=&#34;发送&#34;&gt;发送
&lt;/h4&gt;
&lt;p&gt;在&lt;code&gt;UART&lt;/code&gt;底层有发送移位寄存器和发送数据寄存器，发送数据时，需要CPU将发送数据寄存器的数据移动至发送移位寄存器，然后&lt;code&gt;UART&lt;/code&gt;按照指定的波特率发送数据，CPU则不断查询数据发送寄存器是否空，如果空则需要移动数据进来&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E5%8F%91%E9%80%81.png&#34;
	width=&#34;631&#34;
	height=&#34;244&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E5%8F%91%E9%80%81_hu15405304221731860814.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E5%8F%91%E9%80%81_hu11465131017380306252.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;258&#34;
		data-flex-basis=&#34;620px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;接收&#34;&gt;接收
&lt;/h4&gt;
&lt;p&gt;在&lt;code&gt;UART&lt;/code&gt;底层有接收移位寄存器和接收数据寄存器，接收数据时，&lt;code&gt;UART&lt;/code&gt;按照指定的波特率接收数据至接收移位寄存器，然后数据会存储在接收数据寄存器，CPU则不断查询数据接收寄存器是否有数据，如果有数据，CPU会把寄存器的数据移动至我们用来接收数据的变量的内存里&lt;/p&gt;
&lt;p&gt;当&lt;code&gt;HAL_UART_Receive&lt;/code&gt;执行完成，我们就可以知道数据接收完成
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E8%BD%AE%E8%AF%A2%E6%8E%A5%E6%94%B6.png&#34;
	width=&#34;589&#34;
	height=&#34;299&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E8%BD%AE%E8%AF%A2%E6%8E%A5%E6%94%B6_hu13280145308343782189.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E8%BD%AE%E8%AF%A2%E6%8E%A5%E6%94%B6_hu12241757098732507153.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;196&#34;
		data-flex-basis=&#34;472px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;中断模式&#34;&gt;中断模式
&lt;/h3&gt;
&lt;p&gt;底层中断实现数据每传送一字节，召回CPU继续运输数据，不需要我们考虑，&lt;code&gt;HAL&lt;/code&gt;库底层已经帮我们实现
上层中断实现数据接收完成后的数据处理，通过中断回调函数实现，需要我们自己设计&lt;/p&gt;
&lt;h4 id=&#34;发送-1&#34;&gt;发送
&lt;/h4&gt;
&lt;p&gt;CPU将数据送入 发送数据寄存器，然后就去执行其他代码，当发送移位寄存器的数据发送后，发送数据寄存器空，会触发发送数据寄存器空中断，CPU再次将数据送入 发送数据寄存器，然后又去执行其他代码，所有数据发送完成后会触发 传送完成中断，调用&lt;code&gt;HAL_UART_TxCpltCallback&lt;/code&gt;中断回调函数
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E4%B8%AD%E6%96%AD%E5%8F%91%E9%80%81.png&#34;
	width=&#34;924&#34;
	height=&#34;355&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E4%B8%AD%E6%96%AD%E5%8F%91%E9%80%81_hu12903841339894141808.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E4%B8%AD%E6%96%AD%E5%8F%91%E9%80%81_hu8863444947271062853.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;260&#34;
		data-flex-basis=&#34;624px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;接收-1&#34;&gt;接收
&lt;/h4&gt;
&lt;p&gt;CPU在处理其他代码，接收移位寄存器将一帧数据移动至 接受数据寄存器后，会触发 接收数据寄存器非空中断，CPU会回来将 接收数据寄存器 的数据移动至我们用来接收数据的变量的内存里，然后又去执行其他代码，所有数据完成后会调用&lt;code&gt;_HAL_UART_RxCpltCallback_&lt;/code&gt;中断回调函数处理接收的数据
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E6%8E%A5%E6%94%B6%E4%B8%AD%E6%96%AD.png&#34;
	width=&#34;780&#34;
	height=&#34;312&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E6%8E%A5%E6%94%B6%E4%B8%AD%E6%96%AD_hu6741878258720157272.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E4%B8%AD%E6%96%AD-UART%E6%8E%A5%E6%94%B6%E4%B8%AD%E6%96%AD_hu15906450670116678087.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;250&#34;
		data-flex-basis=&#34;600px&#34;
	
&gt;
而执行&lt;code&gt;HAL_UART_Receive_IT&lt;/code&gt;后，我们不能直接对数据继续处理，数据还没接收完成，因为CPU不会进入阻塞态，会去执行其他代码，需要通过&lt;code&gt;HAL_UART_RxCpltCallback&lt;/code&gt;回调函数处理接收的数据&lt;/p&gt;
&lt;h2 id=&#34;定时器中断补充&#34;&gt;定时器中断（补充）
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;说明：本节偏“更新中断”专题补充；如果想系统学习定时器，优先看后文的“定时器（系统学习）”章节。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/658791565&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;基于HAL库 STM32中断详述 - 知乎&lt;/a&gt;
&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/m0_56399733/article/details/134979299&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32&amp;ndash;中断使用（超详细！）_stm32中断-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;中断机制图解
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E4%B8%AD%E6%96%AD%E6%9C%BA%E5%88%B6%E5%9B%BE%E8%A7%A3.png&#34;
	width=&#34;4617&#34;
	height=&#34;1803&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E4%B8%AD%E6%96%AD%E6%9C%BA%E5%88%B6%E5%9B%BE%E8%A7%A3_hu11704804992811952000.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E4%B8%AD%E6%96%AD%E6%9C%BA%E5%88%B6%E5%9B%BE%E8%A7%A3_hu13115145147307207397.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;256&#34;
		data-flex-basis=&#34;614px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;tim定时器中断&#34;&gt;TIM定时器中断
&lt;/h3&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.bilibili.com/video/BV1X1421475z?vd_source=5a0790755035f26a67935abfbfcdfd5b&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;25_1_TIM，UPDATE定时中断（B站）&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;定时器更新中断&#34;&gt;定时器更新中断
&lt;/h4&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/77004732&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;【话说定时器系列】之四：STM32定时器更新事件及案例分享 - 知乎&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;更新操作是一种动作，是更新事件的源头，即事件源；
更新事件是基于更新操作所导致的后续影响或结果。&lt;/p&gt;
&lt;p&gt;部分更新事件触发定时器更新中断或触发DMA请求。&lt;/p&gt;
&lt;p&gt;软件更新操作，触发了更新事件，它不仅仅实现了影子寄存器的数据更新，同时还置位了状态寄存器的更新中断标志位，且使能定时器更新中断，之后就会进入更新中断服务程序。&lt;/p&gt;
&lt;h4 id=&#34;初始化后立即进入定时器更新中断&#34;&gt;初始化后立即进入定时器更新中断
&lt;/h4&gt;
&lt;p&gt;基于此，在&lt;code&gt;MX_TIMx_Init()&lt;/code&gt;中，初始化了影子寄存器（自动重装载寄存器等），进行了数据的更新，同时还置位了更新中断标志位，所以在时基参数初始化，使能定时器中断之后，就会进入更新中断服务程序。若要解决此问题，我们可以在时基参数初始化完成之后，使能定时器更新中断&lt;code&gt;HAL_TIM_Base_Init_IT()&lt;/code&gt;之前，做更新中断标志的清除操作。
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%BC%80%E5%90%AFTIM%E6%97%B6%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86.png&#34;
	width=&#34;1007&#34;
	height=&#34;101&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%BC%80%E5%90%AFTIM%E6%97%B6%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86_hu2790487887584429588.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%BC%80%E5%90%AFTIM%E6%97%B6%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86_hu7224389806914459737.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;997&#34;
		data-flex-basis=&#34;2392px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;复位模式trigger触发后进入更新中断&#34;&gt;复位模式&lt;code&gt;trigger&lt;/code&gt;触发后进入更新中断
&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;trigger&lt;/code&gt;触发后，计数寄存器被置零，会置位状态寄存器的更新中断标志位，如果使能了更新中断，则会进入更新中断服务函数&lt;/p&gt;
&lt;h4 id=&#34;更新操作事件源&#34;&gt;更新操作事件源
&lt;/h4&gt;
&lt;p&gt;可能的更新操作【事件源】有3类：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;核心计数器的溢出【上溢或下溢】&lt;/li&gt;
&lt;li&gt;软件复位操作【对UG@TIMX_EGR置位】&lt;/li&gt;
&lt;li&gt;工作在复位模式下的定时器收到触发信号【即复位触发信号】
【特别提醒，对于高级定时器必须发生RCR+1次溢出动作后才可以产生更新事件。对于通用或基本定时器，每溢出一次都可以产生更新事件。】&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;adc模块&#34;&gt;ADC模块
&lt;/h2&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/wallace89/article/details/117048846&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32H743-梳理ADC模数转换器在CubeMX上的配置_overrun behaviour-CSDN博客&lt;/a&gt;（写的很好，很详细）&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.cnblogs.com/qu-yang/p/13221161.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32-HAL库-ADC学习 - 曲杨 - 博客园&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;adc定义&#34;&gt;ADC定义
&lt;/h3&gt;
&lt;p&gt;模数转换器(Analog to Digital Converter,ADC)
模拟信号-&amp;gt;数字信号转换器&lt;/p&gt;
&lt;p&gt;通过对输入的模拟信号进行测量，将其分级转换为数字信号&lt;/p&gt;
&lt;h3 id=&#34;stm32单片机中的adc&#34;&gt;STM32单片机中的ADC
&lt;/h3&gt;
&lt;p&gt;一般计算采用一下逻辑方式进行转换&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;V&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V_ref_low&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;V&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V_ref_high&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V_ref_low&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V_ref_high&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V_ref_low&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;X&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;c1&#34;&gt;//归一化，再按照配置的x进行转换
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;erro&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;STM32单片机中的ADC，x一般是12，也可以是其他数值
一般情况下，参考电压为0V，参考高电压为3.3V&lt;/p&gt;
&lt;h3 id=&#34;分辨率与精度&#34;&gt;分辨率与精度
&lt;/h3&gt;
&lt;p&gt;分辨率与位数有关，精度与性能有关，位数越高，分辨率越高，性能越高，波动越小，精度越强
ADC位数为12位，则分辨率是1/4096&lt;/p&gt;
&lt;p&gt;使用时PLCK频率控制在36MHz以内，不然ADC模块的精度会大幅降低&lt;/p&gt;
&lt;h3 id=&#34;stm32cubemx配置&#34;&gt;STM32CubeMX配置
&lt;/h3&gt;
&lt;p&gt;这里以STM32C8T6为例&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;x即Resolution 12bits( 15ADC时钟周期 )（看芯片型号，有的需要配置）&lt;/li&gt;
&lt;li&gt;数据选择右对齐，得到的数据就是转换后的值&lt;/li&gt;
&lt;li&gt;Mode选择Independent mode
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/ADC%E5%9F%BA%E6%9C%AC%E8%AE%BE%E7%BD%AE_1.png&#34;
	width=&#34;416&#34;
	height=&#34;203&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/ADC%E5%9F%BA%E6%9C%AC%E8%AE%BE%E7%BD%AE_1_hu405425321350879967.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/ADC%E5%9F%BA%E6%9C%AC%E8%AE%BE%E7%BD%AE_1_hu9995998333739149559.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;204&#34;
		data-flex-basis=&#34;491px&#34;
	
&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Scan Conversion Mode（扫描转换模式），会采集ADC开启的所有通道，按顺序采集所有通道
Continuous Conversion Mode（连续转换模式），可以在使能ADC时自动开始采集，而非手动采集
Discontinuous Conversion Mode（间断采集模式），可以在一轮采集完成后暂停等待指令控制下一轮采集&lt;/p&gt;
&lt;p&gt;Number Of Discontinuous Conversions（单次转换次数）此参数定义每次触发后ADC执行的转换次数，每次转换完都需要&lt;code&gt;HAL_ADC_GetValue&lt;/code&gt;来获取值。  如果它设为2，且ADC1使能了通道1，2，5，7的话，那么第一次触发ADC1采样时，就会采样通道1与通道2的值，再一次触发ADC1采样的话，就会采样通道5与通道7值，如此类推。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ADC_Regular_ConversionMode&lt;/code&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/ADC%E5%9F%BA%E6%9C%AC%E8%AE%BE%E7%BD%AE_2.png&#34;
	width=&#34;747&#34;
	height=&#34;245&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/ADC%E5%9F%BA%E6%9C%AC%E8%AE%BE%E7%BD%AE_2_hu17733844297870722250.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/ADC%E5%9F%BA%E6%9C%AC%E8%AE%BE%E7%BD%AE_2_hu3913388146016014527.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;304&#34;
		data-flex-basis=&#34;731px&#34;
	
&gt;
可以配置每个通道的采集顺序和采样时间&lt;/p&gt;
&lt;h3 id=&#34;代码使用&#34;&gt;代码使用
&lt;/h3&gt;
&lt;p&gt;1.开始采集&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_ADC_Start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;2.采集后转换&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_ADC_PollForConversion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//地址，等待时间
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;关于多数据通道采集&#34;&gt;关于多数据通道采集
&lt;/h4&gt;
&lt;p&gt;ADC_value[1]对应rank_1的通道的值，第一次采集rank1通道
ADC_value[2]对应rank_2的通道的值，第一次采集rank2通道
rank指在ADC_Regular_ConversionMode中的rank设置&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;nf&#34;&gt;HAL_ADC_Start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;nf&#34;&gt;HAL_ADC_PollForConversion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//采集后转换
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;		&lt;span class=&#34;n&#34;&gt;AD_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_ADC_GetValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//采集十次，平均值处理
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;检测&#34;&gt;检测
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_IS_BIT_SET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_ADC_GetState&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HAL_ADC_STATE_REG_EOC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//检测是否正常采集
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;n&#34;&gt;ADC_value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_ADC_GetValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;关于number-of-discontinuous-conversions&#34;&gt;关于Number Of Discontinuous Conversions
&lt;/h3&gt;
&lt;p&gt;在STM32CubeMX中，&lt;strong&gt;Number Of Discontinuous Conversions&lt;/strong&gt;（单次转换次数）是ADC（模数转换器）的一个配置选项，主要用于控制ADC在&lt;strong&gt;非连续采样模式（Discontinuous Mode&lt;/strong&gt;下的转换行为。以下是详细解释和使用方法：&lt;/p&gt;
&lt;h4 id=&#34;1-功能含义&#34;&gt;1. 功能含义
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：&lt;br&gt;
当ADC配置为非连续模式（Discontinuous Mode）时，此参数定义每次触发后ADC执行的转换次数。
&lt;ul&gt;
&lt;li&gt;例如，设置为&lt;code&gt;3&lt;/code&gt;，则每次触发ADC后，会自动连续完成3次转换（无需额外触发信号）。&lt;/li&gt;
&lt;li&gt;若设置为&lt;code&gt;1&lt;/code&gt;，则每次触发仅执行1次转换（等同于标准单次模式）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;应用场景&lt;/strong&gt;：&lt;br&gt;
适用于需要&lt;strong&gt;分组采样&lt;/strong&gt;的场景，例如：
&lt;ul&gt;
&lt;li&gt;周期性触发ADC，但每次触发需采集多个通道的数据。&lt;/li&gt;
&lt;li&gt;降低CPU干预频率（通过一次触发完成多次转换）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;2-配置步骤stm32cubemx&#34;&gt;2. 配置步骤（STM32CubeMX）
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;启用Discontinuous Mode&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;在ADC配置界面，勾选 &lt;strong&gt;&lt;code&gt;Discontinuous Mode&lt;/code&gt;&lt;/strong&gt;（通常在Parameter Settings选项卡中）。&lt;/li&gt;
&lt;li&gt;此时，&lt;strong&gt;Number Of Discontinuous Conversions&lt;/strong&gt;选项会生效。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;设置转换次数&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;输入需要的转换次数（取值范围取决于型号，通常为1~8）。&lt;/li&gt;
&lt;li&gt;该值必须 &lt;strong&gt;≤ 总启用通道数&lt;/strong&gt;（例如，若启用5个通道，最多可设置为5）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置触发源&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;选择触发方式（如定时器触发、外部引脚触发等）。&lt;/li&gt;
&lt;li&gt;每次触发信号到来时，ADC会自动完成设定的转换次数。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;3-工作流程示例&#34;&gt;&lt;strong&gt;3. 工作流程示例&lt;/strong&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;硬件环境&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;ADC通道：CH0、CH1、CH2&lt;/li&gt;
&lt;li&gt;配置：&lt;code&gt;Discontinuous Mode&lt;/code&gt; + &lt;code&gt;Number Of Discontinuous Conversions = 2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;行为&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;触发信号到来（如定时器溢出）。&lt;/li&gt;
&lt;li&gt;ADC自动连续转换&lt;strong&gt;2个通道&lt;/strong&gt;（例如CH0→CH1）。&lt;/li&gt;
&lt;li&gt;转换完成后产生中断/DMA请求。&lt;/li&gt;
&lt;li&gt;下次触发时，继续从下一个通道开始（CH2→CH0，依此类推）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在该配置下（&lt;code&gt;Discontinuous Mode&lt;/code&gt; + &lt;code&gt;Number Of Discontinuous Conversions = 2&lt;/code&gt;），每次触发后ADC会连续转换&lt;strong&gt;2个通道&lt;/strong&gt;（例如CH0→CH1），因此你需要调用两次 &lt;strong&gt;&lt;code&gt;HAL_ADC_GetValue(&amp;amp;hadc2)&lt;/code&gt;&lt;/strong&gt; 来分别读取这两个通道的转换结果。以下是具体说明和注意事项：&lt;/p&gt;
&lt;h4 id=&#34;1-数据读取方式&#34;&gt;&lt;strong&gt;1. 数据读取方式&lt;/strong&gt;
&lt;/h4&gt;
&lt;h4 id=&#34;方法一轮询模式polling&#34;&gt;&lt;strong&gt;方法一：轮询模式（Polling）&lt;/strong&gt;
&lt;/h4&gt;
&lt;p&gt;每次触发后，需手动读取两次ADC值：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_ADC_Start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 启动ADC（或通过触发信号启动）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//开启一次，采集两次
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_ADC_PollForConversion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//采集后第一次转换
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ch0_value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_ADC_GetValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 读取CH0结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_ADC_PollForConversion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//采集后第二次转换
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ch1_value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_ADC_GetValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 读取CH1结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;注意&lt;/strong&gt;：每次调用 &lt;code&gt;HAL_ADC_GetValue()&lt;/code&gt; 会返回&lt;strong&gt;最后一次完成的转换结果&lt;/strong&gt;，因此需按顺序读取。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;方法二中断模式interrupt&#34;&gt;&lt;strong&gt;方法二：中断模式（Interrupt）&lt;/strong&gt;
&lt;/h4&gt;
&lt;p&gt;在ADC转换完成中断中读取：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_ADC_ConvCpltCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ADC_HandleTypeDef&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hadc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ch0_value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_ADC_GetValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 第一次转换结果（CH0）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ch1_value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_ADC_GetValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 第二次转换结果（CH1）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;关键点&lt;/strong&gt;：在中断回调中需连续读取两次，顺序由ADC的&lt;strong&gt;Rank配置&lt;/strong&gt;决定。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;方法三dma模式推荐&#34;&gt;&lt;strong&gt;方法三：DMA模式（推荐）&lt;/strong&gt;
&lt;/h4&gt;
&lt;p&gt;若启用DMA，ADC会自动将多次转换结果存入指定数组，无需手动调用 &lt;code&gt;HAL_ADC_GetValue()&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;adc_results&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 存储2次转换结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_ADC_Start_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hadc2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;adc_results&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 启动DMA传输
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;结果存储&lt;/strong&gt;：&lt;br&gt;
&lt;code&gt;adc_results[0]&lt;/code&gt; → CH0的值，&lt;code&gt;adc_results[1]&lt;/code&gt; → CH1的值（顺序由Rank决定）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;4-注意事项&#34;&gt;&lt;strong&gt;4. 注意事项&lt;/strong&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;与连续模式（Continuous Mode）的区别&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;连续模式&lt;/strong&gt;：ADC无限循环转换所有启用通道，无需触发。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;非连续模式&lt;/strong&gt;：需外部触发，且每次触发仅转换设定的次数。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DMA配合&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;建议启用DMA，以高效搬运多组转换结果（尤其是高频触发场景）。&lt;/li&gt;
&lt;li&gt;DMA缓冲区大小需 ≥ 转换次数 × 通道数。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通道顺序&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;转换顺序由&lt;strong&gt;Rank&lt;/strong&gt;（在ADC配置中定义）决定，而非通道编号。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;总结&#34;&gt;&lt;strong&gt;总结&lt;/strong&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Number Of Discontinuous Conversions&lt;/strong&gt; 是ADC非连续模式下每次触发的转换次数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键配置&lt;/strong&gt;：启用Discontinuous Mode → 设置转换次数 → 配置触发源。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优势&lt;/strong&gt;：灵活控制采样节奏，减少CPU负担，适合分组采样需求。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.bilibili.com/video/BV1HY411D7Ar?vd_source=5a0790755035f26a67935abfbfcdfd5b&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;中科大RM电控合集：CAN通信+STM32CubeMX编程（B站）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/ShenZhen_zixian/article/details/132652405&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32 CAN快速配置（HAL库版本）_stm32 can hal-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/mengenqing/article/details/132583180&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;一文搞懂CAN和CAN FD总线协议_fdcan-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;fdcan&#34;&gt;FDCAN
&lt;/h2&gt;
&lt;h3 id=&#34;cubemx配置解析&#34;&gt;CubeMX配置解析
&lt;/h3&gt;
&lt;p&gt;这里的配置以&lt;code&gt;STM32G474CET6&lt;/code&gt;为例
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-FDCAN%E7%9A%84Cube%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90.png&#34;
	width=&#34;903&#34;
	height=&#34;1031&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-FDCAN%E7%9A%84Cube%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90_hu7157238711978379387.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-FDCAN%E7%9A%84Cube%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90_hu4946150270157719123.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;87&#34;
		data-flex-basis=&#34;210px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;frame-format&#34;&gt;Frame-Format
&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;Classic mode&lt;/code&gt;：普通CAN
&lt;code&gt;FD mode without BitRate Switching&lt;/code&gt;：FDCAN，没有波特率转换
&lt;code&gt;FD mode with BitRate Switching&lt;/code&gt;：FDCAN，带有波特率转换，数据段使用更高波特率
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-FrameFormat.png&#34;
	width=&#34;973&#34;
	height=&#34;188&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-FrameFormat_hu4354359993436785605.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-FrameFormat_hu14267893887804085537.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;517&#34;
		data-flex-basis=&#34;1242px&#34;
	
&gt;
注意选用&lt;code&gt;FD mode with BitRate Switching&lt;/code&gt;后还可以通过&lt;code&gt;txheader&lt;/code&gt;去选定是否开启&lt;code&gt;BitRateSwithcing&lt;/code&gt;，以及是 采用&lt;code&gt;CAN&lt;/code&gt;的帧格式还是 &lt;code&gt;FDCAN&lt;/code&gt;帧格式&lt;/p&gt;
&lt;p&gt;也就是说这个帧格式选择是决定 是否允许拥有&lt;code&gt;FDCAN&lt;/code&gt;的特殊格式和能否开启&lt;code&gt;BitRateSwitching&lt;/code&gt;，至于发送的帧实际是否用，取决于&lt;code&gt;txheader&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;从这一段&lt;code&gt;HAL_FDCAN_Init&lt;/code&gt;初始化代码中可以看出，只有&lt;code&gt;FD mode with BitRate Switching&lt;/code&gt;才会去初始化数据段的传输参数&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tickstart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Check FDCAN handle */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;cm&#34;&gt;/* Check function parameters */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FrameFormat&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_FRAME_FD_BRS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;assert_param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IS_FDCAN_DATA_PRESCALER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DataPrescaler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;assert_param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IS_FDCAN_DATA_SJW&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DataSyncJumpWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;assert_param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IS_FDCAN_DATA_TSEG1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DataTimeSeg1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;assert_param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IS_FDCAN_DATA_TSEG2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DataTimeSeg2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;//....
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;1-classic-mode传统模式&#34;&gt;1. Classic Mode（传统模式）
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;本质&lt;/strong&gt;：完全兼容传统 CAN 2.0B 协议，不启用 FDCAN 的扩展功能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据长度&lt;/strong&gt;：最大 8 字节（DLC=0~8）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;波特率&lt;/strong&gt;：全程使用&lt;strong&gt;标称波特率（Nominal Bit Rate）&lt;/strong&gt;，无速率切换&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;帧结构&lt;/strong&gt;：与传统 CAN 帧一致，仅包含仲裁段、控制段、数据段（≤8 字节）、CRC 段等&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;核心作用&lt;/strong&gt;：用于对接仅支持传统 CAN 协议的设备（如老旧传感器、执行器），确保兼容性&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;2-fd-mode-with-bitrate-switching带波特率切换的-fd-模式&#34;&gt;2. FD mode with BitRate Switching（带波特率切换的 FD 模式）
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;本质&lt;/strong&gt;：启用 FDCAN 的核心扩展功能，支持高速长数据传输，且数据段使用更高波特率&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据长度&lt;/strong&gt;：最大 64 字节（DLC=0&lt;del&gt;15，其中 DLC=9&lt;/del&gt;15 对应 32~64 字节）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;波特率&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;仲裁段（Arbitration Phase）&lt;/strong&gt;：使用标称波特率（与传统模式一致，确保仲裁兼容性）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据段（Data Phase）&lt;/strong&gt;：使用更高的&lt;strong&gt;数据波特率（Data Bit Rate）&lt;/strong&gt;（可配置为标称波特率的 2~8 倍，如 8Mbps）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;3-fd-mode-without-bitrate-switching不带波特率切换的-fd-模式&#34;&gt;3. FD mode without BitRate Switching（不带波特率切换的 FD 模式）
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;本质&lt;/strong&gt;：启用 FDCAN 的长数据功能，但不切换波特率，全程使用标称波特率&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据长度&lt;/strong&gt;：最大 64 字节（与带切换的 FD 模式一致）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;波特率&lt;/strong&gt;：仲裁段和数据段均使用&lt;strong&gt;标称波特率&lt;/strong&gt;，无速率提升&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;帧结构&lt;/strong&gt;：包含 FD 帧标志（FDF），但无波特率切换标志（BRS=0）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;核心作用&lt;/strong&gt;：用于需要长数据传输（＞8 字节）但总线上存在不支持高速数据段的设备场景，或因硬件限制（如线缆质量差）无法使用高速率的场景&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;mode&#34;&gt;Mode
&lt;/h4&gt;
&lt;p&gt;一般使用&lt;code&gt;Normal mode&lt;/code&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-Mode%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;877&#34;
	height=&#34;187&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-Mode%E9%85%8D%E7%BD%AE_hu5674897828685483828.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-Mode%E9%85%8D%E7%BD%AE_hu15021940551582674318.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;468&#34;
		data-flex-basis=&#34;1125px&#34;
	
&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Normal mode（正常模式）&lt;/li&gt;
&lt;li&gt;Restricted operation（受限操作模式）&lt;/li&gt;
&lt;li&gt;Bus Monitoring mode（总线监听模式）&lt;/li&gt;
&lt;li&gt;Internal LoopBack mode（内部回环模式）&lt;/li&gt;
&lt;li&gt;External LoopBack mode（外部回环模式）&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;auto-retransmission--transmit-pause--protocol-exception&#34;&gt;Auto-Retransmission &amp;amp; Transmit-Pause &amp;amp; Protocol-Exception
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-%E4%B8%89%E4%B8%AA%E9%A2%9D%E5%A4%96%E6%A8%A1%E5%BC%8F.png&#34;
	width=&#34;598&#34;
	height=&#34;88&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-%E4%B8%89%E4%B8%AA%E9%A2%9D%E5%A4%96%E6%A8%A1%E5%BC%8F_hu17982564046468859407.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-%E4%B8%89%E4%B8%AA%E9%A2%9D%E5%A4%96%E6%A8%A1%E5%BC%8F_hu12520894332944574700.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;679&#34;
		data-flex-basis=&#34;1630px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Auto-Retransmission&lt;/code&gt;：自动重传，如果发送的帧没有收到应答，出现错误，就不断重新发送，在总线负载较高的时候一定要关掉，会严重拉低控制频率&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Transmit-Pause&lt;/code&gt;：一种临时停止 FDCAN 发送功能的机制，用于在特定场景下主动暂停数据发送，避免干扰总线或等待特定条件，可以通过软件主动触发，调用&lt;code&gt;HAL&lt;/code&gt;库函数&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Protocol-Exception&lt;/code&gt;：检测到异常情况（帧格式错误等），会去触发异常处理机制（例如异常处理中断）&lt;/p&gt;
&lt;h4 id=&#34;data--nominal&#34;&gt;Data &amp;amp; Nominal
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-Data&amp;amp;Nominal.png&#34;
	width=&#34;709&#34;
	height=&#34;443&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-Data&amp;amp;Nominal_hu16084052005595761327.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-Data&amp;amp;Nominal_hu15075206644771715187.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;160&#34;
		data-flex-basis=&#34;384px&#34;
	
&gt;
此处提一下，&lt;code&gt;Data Sync Jump Width&lt;/code&gt;（数据段同步跳转宽度）是针对&lt;strong&gt;数据波特率（Data Bit Rate）&lt;/strong&gt; 配置的关键时序参数&lt;/p&gt;
&lt;h4 id=&#34;data数据波特率相关&#34;&gt;Data（数据波特率相关）
&lt;/h4&gt;
&lt;p&gt;“Data” 特指 FDCAN 在&lt;strong&gt;FD 模式（Flexible Data Rate Mode）&lt;/strong&gt; 下，帧的&lt;strong&gt;数据段（Data Phase）&lt;/strong&gt; 所使用的传输速率，即&lt;strong&gt;数据波特率（Data Bit Rate）&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;nominal标称波特率相关&#34;&gt;Nominal（标称波特率相关）
&lt;/h4&gt;
&lt;p&gt;“Nominal” 特指 FDCAN 帧在&lt;strong&gt;仲裁段（Arbitration Phase）&lt;/strong&gt;、&lt;strong&gt;控制段（Control Phase）&lt;/strong&gt;、&lt;strong&gt;CRC 段（CRC Phase）&lt;/strong&gt; 和&lt;strong&gt;ACK 段（Acknowledgment Phase）&lt;/strong&gt; 中使用的传输速率，即&lt;strong&gt;标称波特率（Nominal Bit Rate）&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;filter-and-std-filters-nbrext-filters-nbr&#34;&gt;Filter and Std-Filters-Nbr&amp;amp;Ext-Filters-Nbr
&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Std Filters Nbr（标准帧过滤器数量）&lt;/strong&gt; 和&lt;strong&gt;Ext Filters Nbr（扩展帧过滤器数量）&lt;/strong&gt; 是配置 FDCAN（Flexible Data Rate CAN）接收过滤功能的核心参数。它们分别用于定义&lt;strong&gt;标准帧（11 位 ID）&lt;/strong&gt; 和&lt;strong&gt;扩展帧（29 位 ID）&lt;/strong&gt; 的硬件过滤器数量，直接影响 FDCAN 控制器能接收的帧类型和数量&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Std Filters Nbr&lt;/strong&gt;：配置&lt;strong&gt;标准帧（11 位 ID）&lt;/strong&gt; 的过滤器数量。每个过滤器可匹配一个或多个标准 ID，或通过掩码模式匹配 ID 范围&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ext Filters Nbr&lt;/strong&gt;：配置&lt;strong&gt;扩展帧（29 位 ID）&lt;/strong&gt; 的过滤器数量。每个过滤器可匹配一个或多个扩展 ID，或通过掩码模式匹配 ID 范围&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;过滤器类型&#34;&gt;过滤器类型
&lt;/h4&gt;
&lt;p&gt;FDCAN 支持多种过滤模式，不同模式对过滤器数量的需求不同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;掩码模式（Mask Mode）&lt;/strong&gt;：
通过 ID 和掩码匹配 ID 范围。例如，1 个标准过滤器可匹配 0x100~0x1FF 范围内的所有 ID（掩码 = 0x100，ID=0x1FF）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;双 ID 模式（Dual ID Mode）&lt;/strong&gt;：
匹配两个特定 ID。例如，1 个扩展过滤器可同时匹配 0x12345678 和 0x87654321&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;范围模式（Range Mode）&lt;/strong&gt;：
匹配 ID 在两个值之间的所有帧。例如，1 个标准过滤器可匹配 0x000~0x0FF 范围内的 ID&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;配置示例&#34;&gt;配置示例
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 配置4个扩展过滤器，每个匹配1个特定ID（双ID模式）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_FilterTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IdType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_EXTENDED_ID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_FILTER_DUAL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterConfig&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_FILTER_TO_RXBUFFER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 过滤器0匹配ID=0x01
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterIndex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterID1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x01&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterID2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x01&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxBufferIndex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_ConfigFilter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 过滤器1匹配ID=0x02
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterIndex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterID1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x02&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterID2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x02&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxBufferIndex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_ConfigFilter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 依此类推配置过滤器2和3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;txheader&#34;&gt;Txheader
&lt;/h4&gt;
&lt;p&gt;关于&lt;code&gt;Txheader&lt;/code&gt;的配置&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;FDCAN_TxHeaderTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Txheader_gimbal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;Txheader_gimbal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DataLength&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x08&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//数据长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;n&#34;&gt;Txheader_gimbal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Identifier&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x1FF&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//标识符
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;n&#34;&gt;Txheader_gimbal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TxFrameType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_DATA_FRAME&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;Txheader_gimbal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IdType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_STANDARD_ID&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;Txheader_gimbal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorStateIndicator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_ESI_ACTIVE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//开启错误状态指示
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;n&#34;&gt;Txheader_gimbal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BitRateSwitch&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_BRS_OFF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;Txheader_gimbal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDFormat&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_CLASSIC_CAN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//传统的CAN模式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;c1&#34;&gt;//Txheader_gimbal.FDFormat=FDCAN_FD_CAN;//FDCAN模式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;n&#34;&gt;Txheader_gimbal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TxEventFifoControl&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_NO_TX_EVENTS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//无发送事件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;Txheader_gimbal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MessageMarker&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;时间片&#34;&gt;时间片
&lt;/h4&gt;
&lt;p&gt;不做解析，硬件方面计算出来拿来用即可&lt;/p&gt;
&lt;h3 id=&#34;使用代码&#34;&gt;使用代码
&lt;/h3&gt;
&lt;h4 id=&#34;filterinit-and-fdcanstart&#34;&gt;FilterInit-and-FDCANStart
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;FDCAN_IntFilterAndStart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;//--------FDCAN1 Filter and Start--------//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;FDCAN_FilterTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IdType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_STANDARD_ID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterIndex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_FILTER_MASK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterConfig&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_FILTER_TO_RXFIFO0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterID1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//0x500;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterID2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//0x780;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_ConfigFilter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;FDCAN_ErrorHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_ConfigGlobalFilter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_REJECT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_REJECT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_FILTER_REMOTE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_FILTER_REMOTE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;FDCAN_ErrorHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_Start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;FDCAN_ErrorHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_ActivateNotification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_IT_RX_FIFO0_NEW_MESSAGE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;FDCAN_ErrorHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_ActivateNotification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_IT_BUS_OFF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;FDCAN_ErrorHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;解析一下&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_ConfigGlobalFilter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_REJECT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_REJECT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_FILTER_REMOTE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_FILTER_REMOTE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;HAL_FDCAN_ConfigGlobalFilter&lt;/code&gt;用于定义&lt;strong&gt;未被任何特定过滤器匹配的帧&lt;/strong&gt;的处理规则，参数含义如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第 2 个参数（&lt;code&gt;FDCAN_REJECT&lt;/code&gt;）：未匹配的&lt;strong&gt;标准帧&lt;/strong&gt;被 “拒绝”（不接收）；&lt;/li&gt;
&lt;li&gt;第 3 个参数（&lt;code&gt;FDCAN_REJECT&lt;/code&gt;）：未匹配的&lt;strong&gt;扩展帧&lt;/strong&gt;被 “拒绝”（不接收）；&lt;/li&gt;
&lt;li&gt;第 4 个参数（&lt;code&gt;FDCAN_FILTER_REMOTE&lt;/code&gt;）：未匹配的&lt;strong&gt;标准远程帧&lt;/strong&gt;被 “拒绝”；&lt;/li&gt;
&lt;li&gt;第 5 个参数（&lt;code&gt;FDCAN_FILTER_REMOTE&lt;/code&gt;）：未匹配的&lt;strong&gt;扩展远程帧&lt;/strong&gt;被 “拒绝”。
结合前面的过滤器配置（所有标准帧都被第 0 号过滤器匹配），这里的全局规则实际效果是：&lt;/li&gt;
&lt;li&gt;所有标准帧被第 0 号过滤器接收（存入 FIFO0）；&lt;/li&gt;
&lt;li&gt;扩展帧、远程帧（无论标准还是扩展）因未被匹配，全部被拒绝。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;数据发送&#34;&gt;数据发送
&lt;/h4&gt;
&lt;p&gt;如果需要兼容&lt;code&gt;CAN&lt;/code&gt;，将&lt;code&gt;FDFormat&lt;/code&gt;修改为&lt;code&gt;FDCAN_CLASSIC_CAN&lt;/code&gt;即可&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;FDCAN_InitTxHander&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_TxHeaderTypeDef&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pheader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dlc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;baudrateswitch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;can_type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pheader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Identifier&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x800&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	    &lt;span class=&#34;n&#34;&gt;pheader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IdType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_EXTENDED_ID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	    &lt;span class=&#34;n&#34;&gt;pheader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IdType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;FDCAN_STANDARD_ID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pheader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TxFrameType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;FDCAN_DATA_FRAME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pheader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DataLength&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dlc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pheader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorStateIndicator&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_ESI_ACTIVE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//开启错误状态指示
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;pheader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BitRateSwitch&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;baudrateswitch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pheader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDFormat&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;can_type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pheader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TxEventFifoControl&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_NO_TX_EVENTS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pheader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MessageMarker&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;FDCAN_SendMessageWithBaudSwitch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pdata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dlc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;FDCAN_TxHeaderTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txhead&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;FDCAN_InitTxHander&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txhead&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dlc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_BRS_ON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_FD_CAN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_AddMessageToTxFifoQ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txhead&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pdata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;FDCAN_SendMessageWithOutBaudSwitch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pdata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dlc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;FDCAN_TxHeaderTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txhead&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;FDCAN_InitTxHander&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txhead&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dlc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_BRS_OFF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_CLASSIC_CAN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_AddMessageToTxFifoQ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txhead&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pdata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_AddMessageToTxFifoQ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txhead&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pdata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;FDCAN_ErrorHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;数据接收&#34;&gt;数据接收
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RxData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_RxFifo0Callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDCAN_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RxFifo0ITs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxFifo0ITs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_IT_RX_FIFO0_NEW_MESSAGE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RESET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//判断是否是新消息中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Instance&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//Slave Arm
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nf&#34;&gt;HAL_FDCAN_GetRxMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hfdcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FDCAN_RX_FIFO0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RxData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;can&#34;&gt;CAN
&lt;/h2&gt;
&lt;h3 id=&#34;cube配置-1&#34;&gt;Cube配置
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-CAN%E7%9A%84Cube%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;889&#34;
	height=&#34;517&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-CAN%E7%9A%84Cube%E9%85%8D%E7%BD%AE_hu3062212629618048469.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-CAN%E7%9A%84Cube%E9%85%8D%E7%BD%AE_hu13144796004444087730.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;171&#34;
		data-flex-basis=&#34;412px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;模式设置mode&#34;&gt;模式设置（Mode）
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-CAN%E7%9A%84mode.png&#34;
	width=&#34;899&#34;
	height=&#34;193&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-CAN%E7%9A%84mode_hu14813646946158995366.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-CAN%E7%9A%84mode_hu15444955145760101.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;465&#34;
		data-flex-basis=&#34;1117px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Normal mode&lt;/strong&gt;（正常模式）：正常发送和接收帧，用于实际总线通信&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loopback mode&lt;/strong&gt;（回环模式）：发送的帧会被自身接收，无需外部总线，用于调试&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Silent mode&lt;/strong&gt;（静默模式）：只能接收帧，不能发送，用于监听总线&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Silent Loopback mode&lt;/strong&gt;（静默回环模式）：结合静默和回环，仅内部测试&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;波特率&#34;&gt;波特率
&lt;/h4&gt;
$$波特率 = APB时钟频率 / [ Prescaler × (1 + TimeSeg1 + TimeSeg2) ]$$&lt;p&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN_%E6%B3%A2%E7%89%B9%E7%8E%87%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;753&#34;
	height=&#34;234&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN_%E6%B3%A2%E7%89%B9%E7%8E%87%E9%85%8D%E7%BD%AE_hu14887586793497255969.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN_%E6%B3%A2%E7%89%B9%E7%8E%87%E9%85%8D%E7%BD%AE_hu16209401040093241942.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;321&#34;
		data-flex-basis=&#34;772px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;CAN 的波特率由&lt;strong&gt;位时间（Bit Time）&lt;/strong&gt; 决定，位时间 = 1 / 波特率（如 1Mbps 对应位时间 1μs）。位时间由 3 部分组成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prescaler&lt;/strong&gt;（预分频器）：将 APB 时钟（如 APB1=36MHz）分频为时间量子（TQ），公式：&lt;code&gt;TQ = 1/(APB时钟频率 / Prescaler)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sync Jump Width (SJW)&lt;/strong&gt;：同步跳转宽度，用于补偿节点间时钟偏差，取值 1~4TQ（通常设为 1 或 2）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Time Seg1&lt;/strong&gt;：包含传播段（PropSeg）和相位段 1（PS1），取值 4~16TQ（用于补偿总线延迟）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Time Seg2&lt;/strong&gt;：相位段 2（PS2），取值 2~8TQ（用于同步补偿）&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;basic-parameters&#34;&gt;Basic-Parameters
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-CAN-Basic-Parameters.png&#34;
	width=&#34;743&#34;
	height=&#34;213&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-CAN-Basic-Parameters_hu15874198689003734250.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32FDCAN&amp;amp;CAN-CAN-Basic-Parameters_hu18154244688467312360.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;348&#34;
		data-flex-basis=&#34;837px&#34;
	
&gt;
Time Triggered Communication（时间触发通信）&lt;/p&gt;
&lt;p&gt;Automatic Bus-Off Management（自动总线关闭管理）
当节点因错误计数超限进入 “总线关闭” 状态（无法发送和接收帧）时，是否需要软件手动恢复，还是控制器自动恢复&lt;/p&gt;
&lt;p&gt;Automatic WakeUP mode（自动唤醒模式） 是一种针对&lt;strong&gt;低功耗场景&lt;/strong&gt;的功能，用于让 CAN 控制器在休眠（低功耗）状态下，通过检测总线上的有效活动（如特定 CAN 帧）自动恢复到正常工作状态，无需软件手动触发唤醒&lt;/p&gt;
&lt;p&gt;Automatic Retransmission（自动重传）&lt;/p&gt;
&lt;p&gt;Receive FIFO Locked Mode（接收 FIFO 锁定模式）
当接收 FIFO（CAN 通常有 2 个接收 FIFO，FIFO0 和 FIFO1）存储的帧数量达到最大深度（如 3 个或 6 个，依芯片型号而定）时，新接收的帧是否覆盖旧的帧&lt;/p&gt;
&lt;p&gt;Transmit FIFO Priority（发送 FIFO 优先级）
当发送 FIFO（CAN 通常有 1 个发送 FIFO，可存储多个待发送帧）中有多个帧等待发送时，帧的发送顺序规则&lt;/p&gt;
&lt;h3 id=&#34;使用代码-1&#34;&gt;使用代码
&lt;/h3&gt;
&lt;h4 id=&#34;filterinit-and-fdcanstart-1&#34;&gt;FilterInit-and-FDCANStart
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;CAN_Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;CAN_FilterTypeDef&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Configure the CAN Filter */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterBank&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;                      &lt;span class=&#34;c1&#34;&gt;// 过滤器编号，使用一个CAN，则可选0-13；使用两个CAN可选0-27
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterMode&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CAN_FILTERMODE_IDMASK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 过滤器模式，掩码模式或列表模式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterScale&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CAN_FILTERSCALE_32BIT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 过滤器位宽
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterIdHigh&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x0000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;               &lt;span class=&#34;c1&#34;&gt;// 过滤器验证码ID高16位，0-0xFFFF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterIdLow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x0000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;                &lt;span class=&#34;c1&#34;&gt;// 过滤器验证码ID低16位，0-0xFFFF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterMaskIdHigh&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x0000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;           &lt;span class=&#34;c1&#34;&gt;// 过滤器掩码ID高16位，0-0xFFFF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterMaskIdLow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x0000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;            &lt;span class=&#34;c1&#34;&gt;// 过滤器掩码ID低16位，0-0xFFFF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterFIFOAssignment&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CAN_FilterFIFO0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// FIFOx，0或1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FilterActivation&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ENABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;           &lt;span class=&#34;c1&#34;&gt;// 使能过滤器
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SlaveStartFilterBank&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;           &lt;span class=&#34;c1&#34;&gt;// 从过滤器编号，0-27，对于单CAN实例该参数没有意义
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_CAN_ConfigFilter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hcan1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sFilterConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* Filter configuration Error */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Start the CAN peripheral */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_CAN_Start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hcan1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* Start Error */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Activate CAN RX notification */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_CAN_ActivateNotification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hcan1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CAN_IT_RX_FIFO0_MSG_PENDING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* Notification Error */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;发送-2&#34;&gt;发送
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;CAN_Send_Msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TxMailbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;CAN_TxHeaderTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CAN_TxHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;// 设置发送参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;CAN_TxHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;StdId&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;                 &lt;span class=&#34;c1&#34;&gt;// 标准标识符(12bit)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;//CAN_TxHeader.ExtId = 0x00;                 // 扩展标识符(29bit)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;CAN_TxHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IDE&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CAN_ID_STD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;             &lt;span class=&#34;c1&#34;&gt;// 使用标准帧
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;CAN_TxHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RTR&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CAN_RTR_DATA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;           &lt;span class=&#34;c1&#34;&gt;// 数据帧
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;CAN_TxHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DLC&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x08&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;                    &lt;span class=&#34;c1&#34;&gt;// 发送长度      
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;CAN_TxHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TransmitGlobalTime&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DISABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭can的时间触发通信模式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 装载数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;memset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0xFF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0xFF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;// 发送CAN消息
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_CAN_AddTxMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hcan1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CAN_TxHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TxMailbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;接收-2&#34;&gt;接收
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_CAN_RxFifo0MsgPendingCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CAN_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 收到CAN数据会触发接收中断，进入该回调函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RxData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;CAN_RxHeaderTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CAN_RxHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_CAN_GetRxMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hcan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CAN_RX_FIFO0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CAN_RxHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RxData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hcan&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hcan1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 只处理CAN1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 处理CAN1接收到的数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;switch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CAN_RxHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;StdId&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 标准标识符
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x201&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// 处理ID为0x201的消息
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;n&#34;&gt;test_motor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;motor_raw_angle&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RxData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;test_motor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;motor_angle&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_motor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;motor_raw_angle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;8191.f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;360.f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;test_motor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;motor_speed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RxData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;test_motor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;motor_current&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RxData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;test_motor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RxData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;定时器系统学习&#34;&gt;定时器（系统学习）
&lt;/h2&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/as480133937/article/details/99231677&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;【STM32】HAL库 STM32CubeMX教程七&amp;mdash;PWM输出(呼吸灯)_stm32 hal pwm-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/demonneverhunts/article/details/135001314&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32CubeIde中互补PWM配置项的详细解读_ch idle state-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;【【STM32入门教程】应该是全B站最好的STM32教程了！！】(&lt;a class=&#34;link&#34; href=&#34;https://www.bilibili.com/video/BV12v4y1y7uV?vd_source=5a0790755035f26a67935abfbfcdfd5b&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.bilibili.com/video/BV12v4y1y7uV?vd_source=5a0790755035f26a67935abfbfcdfd5b&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;基于上述博客以及&lt;code&gt;keysking&lt;/code&gt;STM32教程写的个人学习文档&lt;/p&gt;
&lt;h3 id=&#34;定时器简介&#34;&gt;定时器简介
&lt;/h3&gt;
&lt;h4 id=&#34;hal库开启定时器的基本函数&#34;&gt;HAL库开启定时器的基本函数
&lt;/h4&gt;
&lt;p&gt;开启定时器&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_TIM_Base_Start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//仅开启定时器
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_TIM_Base_Start_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//开启定时器和中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_TIM_Base_Stop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭定时器
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_TIM_Base_Stop_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//既关闭定时器，同时关闭中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;框架&#34;&gt;框架
&lt;/h4&gt;
&lt;p&gt;解释整个&lt;code&gt;TIM&lt;/code&gt;外设的构成
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E6%A1%86%E6%9E%B6.png&#34;
	width=&#34;1816&#34;
	height=&#34;1046&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E6%A1%86%E6%9E%B6_hu7246255291864279068.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E6%A1%86%E6%9E%B6_hu2875189494378041386.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;173&#34;
		data-flex-basis=&#34;416px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;计数信号来源&#34;&gt;计数信号来源
&lt;/h4&gt;
&lt;p&gt;有内部时钟以及外部时钟
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E6%97%B6%E9%92%9F%E6%BA%90%E6%9D%A5%E6%BA%90.png&#34;
	width=&#34;1900&#34;
	height=&#34;864&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E6%97%B6%E9%92%9F%E6%BA%90%E6%9D%A5%E6%BA%90_hu5088459183591891140.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E6%97%B6%E9%92%9F%E6%BA%90%E6%9D%A5%E6%BA%90_hu16582452387122152923.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;219&#34;
		data-flex-basis=&#34;527px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;内部时钟模式&#34;&gt;内部时钟模式
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F.png&#34;
	width=&#34;675&#34;
	height=&#34;177&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F_hu5309645045050208546.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F_hu9881976903012931188.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;381&#34;
		data-flex-basis=&#34;915px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;f103c8t6&lt;/code&gt;中，&lt;code&gt;TIM1&lt;/code&gt;是高级定时器，&lt;code&gt;TIM2&lt;/code&gt;，&lt;code&gt;TIM3&lt;/code&gt;，&lt;code&gt;TIM4&lt;/code&gt;是通用计时器&lt;/p&gt;
&lt;h4 id=&#34;cubemx参数配置-1&#34;&gt;CubeMX参数配置
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;686&#34;
	height=&#34;237&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE_hu12829645387105645740.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE_hu162320815802914554.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;289&#34;
		data-flex-basis=&#34;694px&#34;
	
&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Prescaler&lt;/code&gt;:预分频，实际分频数是&lt;code&gt;number+1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Counter Mode&lt;/code&gt;:计数模式设置&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Counter Period&lt;/code&gt;:自动重装载计数器计数值&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Internal Clock Division&lt;/code&gt;:内部时钟预分频&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Repetition Counter&lt;/code&gt;:重复计数器 (&lt;strong&gt;RCR&lt;/strong&gt; -8 bits)，属于高级控制寄存器专用寄存器位，利用它可以非常容易控制输出 PWM 的个数，与内部时钟模式无关&lt;/li&gt;
&lt;li&gt;&lt;code&gt;auto-reload preload&lt;/code&gt;:是否开启影子寄存器模式&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;还需要开启定时器更新中断&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD.png&#34;
	width=&#34;685&#34;
	height=&#34;165&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD_hu3931705140757947726.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%86%85%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD_hu9647680572974795723.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;415&#34;
		data-flex-basis=&#34;996px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;代码实现-2&#34;&gt;代码实现
&lt;/h4&gt;
&lt;p&gt;用的&lt;code&gt;PA2&lt;/code&gt;作&lt;code&gt;GPIO&lt;/code&gt;输出&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_TIM_PeriodElapsedCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//中断回调函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;nf&#34;&gt;HAL_GPIO_TogglePin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPIOA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPIO_PIN_2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN 1 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END 1 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* MCU Configuration--------------------------------------------------------*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Reset of all peripherals, Initializes the Flash interface and the Systick. */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;HAL_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN Init */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END Init */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Configure the system clock */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;SystemClock_Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN SysInit */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END SysInit */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Initialize all configured peripherals */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;MX_GPIO_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;MX_TIM1_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN 2 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nf&#34;&gt;HAL_TIM_Base_Start_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END 2 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Infinite loop */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN WHILE */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* USER CODE END WHILE */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN 3 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END 3 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;外部时钟模式&#34;&gt;外部时钟模式
&lt;/h3&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.bilibili.com/video/BV1N94y1u7Uz?vd_source=5a0790755035f26a67935abfbfcdfd5b&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32动画讲解定时器外部时钟 &amp;amp; 实战传送带测速装置（B站）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;__HAL_GET_COUNTER(&amp;amp;htim)&lt;/code&gt;获取计数值&lt;/p&gt;
&lt;h4 id=&#34;外部时钟模式2&#34;&gt;外部时钟模式2
&lt;/h4&gt;
&lt;p&gt;在Clock Source处选择&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/TIM%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F2%E7%9A%84clock_source%E9%80%89%E6%8B%A9.png&#34;
	width=&#34;774&#34;
	height=&#34;473&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/TIM%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F2%E7%9A%84clock_source%E9%80%89%E6%8B%A9_hu11490052635626140431.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/TIM%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F2%E7%9A%84clock_source%E9%80%89%E6%8B%A9_hu14576272573499853989.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;163&#34;
		data-flex-basis=&#34;392px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;注意外部时钟的滤波器&lt;code&gt;Clock Filter&lt;/code&gt;，输入滤波
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%BB%A4%E6%B3%A2.png&#34;
	width=&#34;996&#34;
	height=&#34;216&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%BB%A4%E6%B3%A2_hu9563077849774446580.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%BB%A4%E6%B3%A2_hu10049620090529568470.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;461&#34;
		data-flex-basis=&#34;1106px&#34;
	
&gt;
输入滤波，极性选择，预分频器&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;采样频率等于内部时钟的频率&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E6%BB%A4%E6%B3%A2%E5%8E%9F%E7%90%86.png&#34;
	width=&#34;1450&#34;
	height=&#34;885&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E6%BB%A4%E6%B3%A2%E5%8E%9F%E7%90%86_hu10908971946265844383.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E6%BB%A4%E6%B3%A2%E5%8E%9F%E7%90%86_hu8987433854676132003.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;163&#34;
		data-flex-basis=&#34;393px&#34;
	
&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%BB%A4%E6%B3%A2%E8%AE%BE%E7%BD%AE.png&#34;
	width=&#34;1477&#34;
	height=&#34;768&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%BB%A4%E6%B3%A2%E8%AE%BE%E7%BD%AE_hu16572390343706948322.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%BB%A4%E6%B3%A2%E8%AE%BE%E7%BD%AE_hu16397634823087448288.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;192&#34;
		data-flex-basis=&#34;461px&#34;
	
&gt;
一般推荐选择1110（15）&lt;/p&gt;
&lt;h4 id=&#34;外部时钟模式1&#34;&gt;外部时钟模式1
&lt;/h4&gt;
&lt;p&gt;通过定时器的Slave Mode 进行选择
启用从模式，选择外部时钟模式1
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F1Cube%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;764&#34;
	height=&#34;420&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F1Cube%E9%85%8D%E7%BD%AE_hu11866422407166467253.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F1Cube%E9%85%8D%E7%BD%AE_hu736928791234625645.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;181&#34;
		data-flex-basis=&#34;436px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;选择Trigger Source时，就是选择什么方式来外部计数
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8Triggersource%E9%80%89%E6%8B%A9.png&#34;
	width=&#34;470&#34;
	height=&#34;310&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8Triggersource%E9%80%89%E6%8B%A9_hu3995889018324661563.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8Triggersource%E9%80%89%E6%8B%A9_hu6757351429611777207.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;151&#34;
		data-flex-basis=&#34;363px&#34;
	
&gt;
就是选择触发器的来源
&lt;code&gt;TI_ED&lt;/code&gt;是双边沿触发，且只能是双边沿触发&lt;/p&gt;
&lt;h4 id=&#34;使用外部计数etr&#34;&gt;使用外部计数ETR
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;可以在外部时钟模式1下，Trigger Source选择ETR1
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F1Triggersource%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;767&#34;
	height=&#34;103&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F1Triggersource%E9%85%8D%E7%BD%AE_hu16708479085199084006.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F1Triggersource%E9%85%8D%E7%BD%AE_hu385851263168015434.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;744&#34;
		data-flex-basis=&#34;1787px&#34;
	
&gt;
芯片上会有引脚被设置为ETR1&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;直接选择外部时钟模式2，引脚上会自动有一个ETR2
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F2Triggersource%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;785&#34;
	height=&#34;155&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F2Triggersource%E9%85%8D%E7%BD%AE_hu589057229500730813.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F2Triggersource%E9%85%8D%E7%BD%AE_hu15069757756629320421.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;506&#34;
		data-flex-basis=&#34;1215px&#34;
	
&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F2%E5%BC%95%E8%84%9A.png&#34;
	width=&#34;242&#34;
	height=&#34;138&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F2%E5%BC%95%E8%84%9A_hu14398155876919048593.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%A4%96%E9%83%A8%E6%97%B6%E9%92%9F%E6%A8%A1%E5%BC%8F2%E5%BC%95%E8%84%9A_hu10642979747135549966.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;175&#34;
		data-flex-basis=&#34;420px&#34;
	
&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;关于定时器的事件更新中断&#34;&gt;关于定时器的事件更新中断
&lt;/h3&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;#%e5%ae%9a%e6%97%b6%e5%99%a8%e4%b8%ad%e6%96%ad%e8%a1%a5%e5%85%85&#34; &gt;关于定时器中断（本笔记内）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;计数值到达自动重装载值时，触发更新中断
在Cube中开启&lt;code&gt;global interrupt&lt;/code&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E4%B8%AD%E6%96%AD.png&#34;
	width=&#34;695&#34;
	height=&#34;125&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E4%B8%AD%E6%96%AD_hu3098622195240813322.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E4%B8%AD%E6%96%AD_hu9360666073227511213.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;556&#34;
		data-flex-basis=&#34;1334px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;关于mx_tim2_init启动时会将中断标志位置1&#34;&gt;关于MX_TIM2_Init()启动时会将中断标志位置1
&lt;/h4&gt;
&lt;p&gt;在MX_TIM2_Init()时，会将定时器更新中断标志位置1，在调用HAL_TIM_Base_Start_IT后，NVIC会检测到更新中断标志位被置1，会立马触发中断&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-MX_TIM2_Init%28%29%E5%90%AF%E5%8A%A8%E6%97%B6%E4%BC%9A%E5%B0%86%E4%B8%AD%E6%96%AD%E6%A0%87%E5%BF%97%E4%BD%8D%E7%BD%AE1.png&#34;
	width=&#34;505&#34;
	height=&#34;133&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-MX_TIM2_Init%28%29%E5%90%AF%E5%8A%A8%E6%97%B6%E4%BC%9A%E5%B0%86%E4%B8%AD%E6%96%AD%E6%A0%87%E5%BF%97%E4%BD%8D%E7%BD%AE1_hu10909019122286373041.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-MX_TIM2_Init%28%29%E5%90%AF%E5%8A%A8%E6%97%B6%E4%BC%9A%E5%B0%86%E4%B8%AD%E6%96%AD%E6%A0%87%E5%BF%97%E4%BD%8D%E7%BD%AE1_hu6249090256107097936.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;379&#34;
		data-flex-basis=&#34;911px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;在HAL_TIM_Base_Start_IT前选择下面两个函数其中一个写上即可
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%BC%80%E5%90%AFTIM%E6%97%B6%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86.png&#34;
	width=&#34;1007&#34;
	height=&#34;101&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%BC%80%E5%90%AFTIM%E6%97%B6%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86_hu2790487887584429588.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%BC%80%E5%90%AFTIM%E6%97%B6%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86_hu7224389806914459737.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;997&#34;
		data-flex-basis=&#34;2392px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;事件更新中断的逻辑&#34;&gt;事件更新中断的逻辑
&lt;/h4&gt;
&lt;p&gt;先是NVIC中断向量表查找到TIM2_IRQhandler，在该函数中，调用了HAL_TIM_IRQhandler函数
其中的事件更新处理的代码(HAL库中&lt;code&gt;HAL_TIM_IRQHandler&lt;/code&gt;中的处理事件更新中断的代码)
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM_IRQHandler%E4%BB%A3%E7%A0%81%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86.png&#34;
	width=&#34;1582&#34;
	height=&#34;539&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM_IRQHandler%E4%BB%A3%E7%A0%81%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86_hu440923548277402571.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM_IRQHandler%E4%BB%A3%E7%A0%81%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86_hu10801739267182522720.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;293&#34;
		data-flex-basis=&#34;704px&#34;
	
&gt;
判断标志位，判断是否开启事件更新中断，清零标志位，调用&lt;code&gt;HAL_TIM_PeriodElapsedCallback&lt;/code&gt;函数&lt;/p&gt;
&lt;h3 id=&#34;定时器的从模式&#34;&gt;定时器的从模式
&lt;/h3&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.bilibili.com/video/BV1mU421o7vt?vd_source=5a0790755035f26a67935abfbfcdfd5b&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32一看就懂的定时器从模式讲解（B站）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;定时器从模式&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Reset Mode 复位模式&lt;/li&gt;
&lt;li&gt;Gate Mode 门模式&lt;/li&gt;
&lt;li&gt;Trigger Mode 触发模式&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;复位模式&#34;&gt;复位模式
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%A4%8D%E4%BD%8D%E6%A8%A1%E5%BC%8F.png&#34;
	width=&#34;1886&#34;
	height=&#34;921&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%A4%8D%E4%BD%8D%E6%A8%A1%E5%BC%8F_hu11725483115849287689.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%A4%8D%E4%BD%8D%E6%A8%A1%E5%BC%8F_hu1943116284556190292.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;204&#34;
		data-flex-basis=&#34;491px&#34;
	
&gt;
设定为复位模式时&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;选取计数信号，计数信号可以时内部时钟，也可以是外部时钟模式2（不是从模式控制器下外部时钟模式1）&lt;/li&gt;
&lt;li&gt;触发器的信号，每出现一次，执行一次复位操作（向上计数模式恢复为0，向下计数模式恢复为自动重装载值）
例子：选取计数信号为内部时钟，计数器不断计数，当触发器信号来临时（TI1的TIFP1检测到信号上升沿），则触发一次更新事件，计数器值复位&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;注意：如果开启定时器的事件更新中断，触发器信号也会触发事件更新中断&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;复位模式下的从模式控制器，在接收到触发信号后，就会让计数器重新开始计数，并且会触发定时器更新中断&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;如何判断事件更新中断的产生原因&#34;&gt;如何判断事件更新中断的产生原因
&lt;/h4&gt;
&lt;p&gt;在复位模式中，需要区分事件更新中断是触发信号的复位导致还是自动挡重装载时导致&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM%E7%8A%B6%E6%80%81%E5%AF%84%E5%AD%98%E5%99%A8%E5%88%A4%E6%96%AD.png&#34;
	width=&#34;1545&#34;
	height=&#34;495&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM%E7%8A%B6%E6%80%81%E5%AF%84%E5%AD%98%E5%99%A8%E5%88%A4%E6%96%AD_hu6598019580509237006.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM%E7%8A%B6%E6%80%81%E5%AF%84%E5%AD%98%E5%99%A8%E5%88%A4%E6%96%AD_hu16163515373619946038.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;312&#34;
		data-flex-basis=&#34;749px&#34;
	
&gt;
从模式收到触发信号后，会设置触发器中断标志位，可以借此来区分中断原因&lt;/p&gt;
&lt;p&gt;使用该函数来获取触发器中断标志位
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM_GET_FLAG.png&#34;
	width=&#34;1288&#34;
	height=&#34;85&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM_GET_FLAG_hu15910363570811033068.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM_GET_FLAG_hu7437791743752868895.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;1515&#34;
		data-flex-basis=&#34;3636px&#34;
	
&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_TIM_GET_FLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_FLAG_UPDATE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//可以获取定时器对应标志位的值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;TIM_FLAG_TRIGGER&lt;/code&gt;是触发器中断标志位&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_TIM_GET_FLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_FLAG_TRIGGER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;使用上述语句可以获取其标志位
使用时需要注意，HAL库为了方便我们判断，并不会对该标志位清零，所以在获取标志位的值后，需要对其进行清零&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_TIM_GET_FLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_FLAG_TRIGGER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nf&#34;&gt;__HAL_TIM_CLEAR_FLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_FLAG_TRIGGER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;HAL_TIM_PeriodElapsedCallback&lt;/code&gt;回调函数&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_TIM_PeriodElapsedCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TIM_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;__HAL_TIM_GET_FLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_FLAG_TRIGGER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SET&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//获取触发标志位，用来区分复位引起的中断还是自动重装载引起的中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;		&lt;span class=&#34;nf&#34;&gt;__HAL_TIM_CLEAR_FLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_FLAG_TRIGGER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;triggerMsg&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;strlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;triggerMsg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;updateMsg&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;strlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;updateMsg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;关于mx_tim2_init启动时会将中断标志位置1-1&#34;&gt;关于MX_TIM2_Init()启动时会将中断标志位置1
&lt;/h4&gt;
&lt;p&gt;在MX_TIM2_Init()时，会将定时器更新中断标志位置1，在调用HAL_TIM_Base_Start_IT后，NVIC会检测到更新中断标志位被置1，会立马触发中断&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-MX_TIM2_Init%28%29%E5%90%AF%E5%8A%A8%E6%97%B6%E4%BC%9A%E5%B0%86%E4%B8%AD%E6%96%AD%E6%A0%87%E5%BF%97%E4%BD%8D%E7%BD%AE1.png&#34;
	width=&#34;505&#34;
	height=&#34;133&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-MX_TIM2_Init%28%29%E5%90%AF%E5%8A%A8%E6%97%B6%E4%BC%9A%E5%B0%86%E4%B8%AD%E6%96%AD%E6%A0%87%E5%BF%97%E4%BD%8D%E7%BD%AE1_hu10909019122286373041.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-MX_TIM2_Init%28%29%E5%90%AF%E5%8A%A8%E6%97%B6%E4%BC%9A%E5%B0%86%E4%B8%AD%E6%96%AD%E6%A0%87%E5%BF%97%E4%BD%8D%E7%BD%AE1_hu6249090256107097936.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;379&#34;
		data-flex-basis=&#34;911px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;在HAL_TIM_Base_Start_IT前选择下面两个函数其中一个写上即可
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%BC%80%E5%90%AFTIM%E6%97%B6%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86.png&#34;
	width=&#34;1007&#34;
	height=&#34;101&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%BC%80%E5%90%AFTIM%E6%97%B6%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86_hu2790487887584429588.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%BC%80%E5%90%AFTIM%E6%97%B6%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86_hu7224389806914459737.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;997&#34;
		data-flex-basis=&#34;2392px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;事件更新中断的逻辑-1&#34;&gt;事件更新中断的逻辑
&lt;/h4&gt;
&lt;p&gt;先是NVIC中断向量表查找到TIM2_IRQhandler，在该函数中，调用了HAL_TIM2_IRQhandler函数
其中的事件更新处理处的代码(HAL库中&lt;code&gt;HAL_TIM_IRQHandler&lt;/code&gt;中的处理事件更新中断的代码)
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM_IRQHandler%E4%BB%A3%E7%A0%81%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86.png&#34;
	width=&#34;1582&#34;
	height=&#34;539&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM_IRQHandler%E4%BB%A3%E7%A0%81%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86_hu440923548277402571.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-TIM_IRQHandler%E4%BB%A3%E7%A0%81%E6%9B%B4%E6%96%B0%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86_hu10801739267182522720.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;293&#34;
		data-flex-basis=&#34;704px&#34;
	
&gt;
判断标志位，判断是否开启事件更新中断，清零标志位，调用HAL_TIM_PeriodElapsedCallback函数&lt;/p&gt;
&lt;h4 id=&#34;门模式&#34;&gt;门模式
&lt;/h4&gt;
&lt;p&gt;如果TI1的TI1FP1为上升沿检测，则是当触发信号是高电平时，时钟信号可以正常进入定时器，定时器能正常计数
当触发信号时低电平时，门关闭，时钟信号不能正常进入定时器，定时器停止计数
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E9%97%A8%E6%A8%A1%E5%BC%8F.png&#34;
	width=&#34;1846&#34;
	height=&#34;1003&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E9%97%A8%E6%A8%A1%E5%BC%8F_hu14482877859231893830.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E9%97%A8%E6%A8%A1%E5%BC%8F_hu15862409341785774361.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;184&#34;
		data-flex-basis=&#34;441px&#34;
	
&gt;
若将触发器的极性改为检测下降沿的话，门的控制作用则相反
触发器的极性选择
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8Trigger%E6%9E%81%E6%80%A7%E9%80%89%E6%8B%A9.png&#34;
	width=&#34;638&#34;
	height=&#34;125&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8Trigger%E6%9E%81%E6%80%A7%E9%80%89%E6%8B%A9_hu3005372532932280779.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8Trigger%E6%9E%81%E6%80%A7%E9%80%89%E6%8B%A9_hu12576360874264416519.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;510&#34;
		data-flex-basis=&#34;1224px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;需要注意，在门模式情况下，上升下降沿的时刻，也会将触发器中断标志位置1，但是&lt;strong&gt;不会触发事件更新中断&lt;/strong&gt;（因为没有对计数值进行复位，就不会触发事件更新中断）
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E9%97%A8%E6%A8%A1%E5%BC%8FTrigger%E4%B8%AD%E6%96%AD.png&#34;
	width=&#34;1459&#34;
	height=&#34;924&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E9%97%A8%E6%A8%A1%E5%BC%8FTrigger%E4%B8%AD%E6%96%AD_hu2944559667312651129.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E9%97%A8%E6%A8%A1%E5%BC%8FTrigger%E4%B8%AD%E6%96%AD_hu10939188625029366002.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;157&#34;
		data-flex-basis=&#34;378px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;触发模式&#34;&gt;触发模式
&lt;/h4&gt;
&lt;p&gt;在检测到设定的边沿后，让定时器开始计数
开始后不能设定停止
触发模式仅能启动定时器，并不能停止计数器计数&lt;/p&gt;
&lt;p&gt;一般配合计时器的单脉冲模式使用
单脉冲模式，是指计数器计数到重装载计数值后，就停止计数（不再循环计数）
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%A7%A6%E5%8F%91%E6%A8%A1%E5%BC%8F.png&#34;
	width=&#34;879&#34;
	height=&#34;608&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%A7%A6%E5%8F%91%E6%A8%A1%E5%BC%8F_hu12071710814715075892.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%A7%A6%E5%8F%91%E6%A8%A1%E5%BC%8F_hu15375127490993028844.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;144&#34;
		data-flex-basis=&#34;346px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;一般需要勾选单脉冲模式&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%8D%95%E8%84%89%E5%86%B2%E8%A7%A6%E5%8F%91%E6%A8%A1%E5%BC%8F.png&#34;
	width=&#34;369&#34;
	height=&#34;171&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%8D%95%E8%84%89%E5%86%B2%E8%A7%A6%E5%8F%91%E6%A8%A1%E5%BC%8F_hu4330916582684147670.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%8D%95%E8%84%89%E5%86%B2%E8%A7%A6%E5%8F%91%E6%A8%A1%E5%BC%8F_hu5523703620707339034.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;215&#34;
		data-flex-basis=&#34;517px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;三种模式的总结&#34;&gt;三种模式的总结
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E4%B8%89%E7%A7%8D%E6%A8%A1%E5%BC%8F%E6%80%BB%E7%BB%93.png&#34;
	width=&#34;1696&#34;
	height=&#34;929&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E4%B8%89%E7%A7%8D%E6%A8%A1%E5%BC%8F%E6%80%BB%E7%BB%93_hu13832106499077563247.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E4%B8%89%E7%A7%8D%E6%A8%A1%E5%BC%8F%E6%80%BB%E7%BB%93_hu2416660951214798472.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;182&#34;
		data-flex-basis=&#34;438px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;trigger-source-触发源的滤波器设置&#34;&gt;Trigger Source 触发源的滤波器设置
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%BB%A4%E6%B3%A2%E8%AE%BE%E7%BD%AE.png&#34;
	width=&#34;1477&#34;
	height=&#34;768&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%BB%A4%E6%B3%A2%E8%AE%BE%E7%BD%AE_hu16572390343706948322.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%BB%A4%E6%B3%A2%E8%AE%BE%E7%BD%AE_hu16397634823087448288.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;192&#34;
		data-flex-basis=&#34;461px&#34;
	
&gt;
在有触发源的时候，对触发源的信号的滤波设置
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E6%BB%A4%E6%B3%A2%E8%AE%BE%E7%BD%AE.png&#34;
	width=&#34;1519&#34;
	height=&#34;918&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E6%BB%A4%E6%B3%A2%E8%AE%BE%E7%BD%AE_hu6408856822874507352.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E6%BB%A4%E6%B3%A2%E8%AE%BE%E7%BD%AE_hu9709839833768929992.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;165&#34;
		data-flex-basis=&#34;397px&#34;
	
&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8TriggerFilter%E8%AE%BE%E7%BD%AE.png&#34;
	width=&#34;615&#34;
	height=&#34;137&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8TriggerFilter%E8%AE%BE%E7%BD%AE_hu4088854993856135708.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8TriggerFilter%E8%AE%BE%E7%BD%AE_hu14367292676400960520.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;448&#34;
		data-flex-basis=&#34;1077px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;定时器的输入捕获&#34;&gt;定时器的输入捕获
&lt;/h3&gt;
&lt;h4 id=&#34;软件层面上的模拟&#34;&gt;软件层面上的模拟
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E7%9A%84%E8%BD%AF%E4%BB%B6%E6%A8%A1%E6%8B%9F.png&#34;
	width=&#34;1953&#34;
	height=&#34;993&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E7%9A%84%E8%BD%AF%E4%BB%B6%E6%A8%A1%E6%8B%9F_hu1208606487945857974.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E7%9A%84%E8%BD%AF%E4%BB%B6%E6%A8%A1%E6%8B%9F_hu15486102283531148421.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;196&#34;
		data-flex-basis=&#34;472px&#34;
	
&gt;
在软件层面检测Echo端的电平高低，进行计时，到那时再极高精度要求的情况则 力不足&lt;/p&gt;
&lt;h4 id=&#34;输入捕获的概括&#34;&gt;输入捕获的概括
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7.png&#34;
	width=&#34;1403&#34;
	height=&#34;936&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7_hu12150519234846394577.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7_hu2387246482467657621.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;149&#34;
		data-flex-basis=&#34;359px&#34;
	
&gt;
硬件在检测到上升或者下降沿时，就记录计数器值到捕获寄存器&lt;/p&gt;
&lt;h4 id=&#34;输入捕获的运行机制&#34;&gt;输入捕获的运行机制
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E8%BF%90%E8%A1%8C%E6%9C%BA%E5%88%B6.png&#34;
	width=&#34;1964&#34;
	height=&#34;976&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E8%BF%90%E8%A1%8C%E6%9C%BA%E5%88%B6_hu1348731604447446013.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E8%BF%90%E8%A1%8C%E6%9C%BA%E5%88%B6_hu1768863916071223908.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;201&#34;
		data-flex-basis=&#34;482px&#34;
	
&gt;
在TI1检测到上升沿时，捕获寄存器立即复制计数器的值
还可以开启输入捕获中断，输入捕获后，启动中断，可以快速处理捕获寄存器上的值&lt;/p&gt;
&lt;p&gt;一个通道只能进行一种边沿检测
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E7%9B%B4%E6%8E%A5%E9%97%B4%E6%8E%A5%E6%A8%A1%E5%BC%8F.png&#34;
	width=&#34;1942&#34;
	height=&#34;978&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E7%9B%B4%E6%8E%A5%E9%97%B4%E6%8E%A5%E6%A8%A1%E5%BC%8F_hu17717979065058431200.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E7%9B%B4%E6%8E%A5%E9%97%B4%E6%8E%A5%E6%A8%A1%E5%BC%8F_hu6899220920855103433.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;198&#34;
		data-flex-basis=&#34;476px&#34;
	
&gt;
捕获的模式
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%B8%A4%E7%A7%8D%E6%A8%A1%E5%BC%8F%E7%BB%93%E5%90%88.png&#34;
	width=&#34;1662&#34;
	height=&#34;418&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%B8%A4%E7%A7%8D%E6%A8%A1%E5%BC%8F%E7%BB%93%E5%90%88_hu10512785567504860820.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%B8%A4%E7%A7%8D%E6%A8%A1%E5%BC%8F%E7%BB%93%E5%90%88_hu4843270472408465732.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;397&#34;
		data-flex-basis=&#34;954px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;注意：TI3和TI4没有接入从模式控制器中
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B74%E4%B8%AA%E9%80%9A%E9%81%93.png&#34;
	width=&#34;1816&#34;
	height=&#34;1046&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B74%E4%B8%AA%E9%80%9A%E9%81%93_hu7246255291864279068.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B74%E4%B8%AA%E9%80%9A%E9%81%93_hu2875189494378041386.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;173&#34;
		data-flex-basis=&#34;416px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B74%E4%B8%AA%E9%80%9A%E9%81%93%E6%96%B9%E6%B3%95%E5%9B%BE.png&#34;
	width=&#34;1355&#34;
	height=&#34;491&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B74%E4%B8%AA%E9%80%9A%E9%81%93%E6%96%B9%E6%B3%95%E5%9B%BE_hu8151643682100602727.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B74%E4%B8%AA%E9%80%9A%E9%81%93%E6%96%B9%E6%B3%95%E5%9B%BE_hu15963921000820360802.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;275&#34;
		data-flex-basis=&#34;662px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;TI1和TI2是一对，可以相互借用
TI3和TI4是一对，可以相互借用
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B74%E4%B8%AA%E9%80%9A%E9%81%93%E9%85%8D%E5%AF%B9%E5%85%B3%E7%B3%BB.png&#34;
	width=&#34;1751&#34;
	height=&#34;600&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B74%E4%B8%AA%E9%80%9A%E9%81%93%E9%85%8D%E5%AF%B9%E5%85%B3%E7%B3%BB_hu14045364042602557867.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B74%E4%B8%AA%E9%80%9A%E9%81%93%E9%85%8D%E5%AF%B9%E5%85%B3%E7%B3%BB_hu511363242770130273.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;291&#34;
		data-flex-basis=&#34;700px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;cube上的配置&#34;&gt;Cube上的配置
&lt;/h4&gt;
&lt;p&gt;注意设置边沿检测
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E7%9B%B4%E6%8E%A5%E9%97%B4%E6%8E%A5%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;1256&#34;
	height=&#34;462&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E7%9B%B4%E6%8E%A5%E9%97%B4%E6%8E%A5%E9%85%8D%E7%BD%AE_hu5422131849685207703.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E7%9B%B4%E6%8E%A5%E9%97%B4%E6%8E%A5%E9%85%8D%E7%BD%AE_hu5174787296735538629.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;271&#34;
		data-flex-basis=&#34;652px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;打开捕获中断
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%BC%80%E5%90%AF%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%B8%AD%E6%96%AD.png&#34;
	width=&#34;1253&#34;
	height=&#34;268&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%BC%80%E5%90%AF%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%B8%AD%E6%96%AD_hu7030381676163352643.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E5%BC%80%E5%90%AF%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%B8%AD%E6%96%AD_hu18227866073269948008.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;467&#34;
		data-flex-basis=&#34;1122px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;启动，该例子中是需要在CHANNEL4捕获到后进行处理，所以CHANNEL44开启了中断
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%BB%A3%E7%A0%81%E5%88%9D%E5%A7%8B%E5%8C%96.png&#34;
	width=&#34;1187&#34;
	height=&#34;196&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%BB%A3%E7%A0%81%E5%88%9D%E5%A7%8B%E5%8C%96_hu292944159826191.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%BB%A3%E7%A0%81%E5%88%9D%E5%A7%8B%E5%8C%96_hu12801109800042694409.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;605&#34;
		data-flex-basis=&#34;1453px&#34;
	
&gt;
输入捕获的开启
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E5%BC%80%E5%90%AF.png&#34;
	width=&#34;1590&#34;
	height=&#34;1098&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E5%BC%80%E5%90%AF_hu15660898789581601865.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E5%BC%80%E5%90%AF_hu11235683347334909269.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;144&#34;
		data-flex-basis=&#34;347px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;可能遇到的问题
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E5%8F%AF%E8%83%BD%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98.png&#34;
	width=&#34;1619&#34;
	height=&#34;521&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E5%8F%AF%E8%83%BD%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98_hu2597053158824355837.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E5%8F%AF%E8%83%BD%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98_hu9796556603946980297.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;310&#34;
		data-flex-basis=&#34;745px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;用&lt;code&gt;SET_COUNTER&lt;/code&gt;来清零一下&lt;/p&gt;
&lt;p&gt;中断回调函数&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_TIM_IC_CaptureCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;回调函数的代码编写
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%B8%AD%E6%96%AD%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E7%BC%96%E5%86%99.png&#34;
	width=&#34;1960&#34;
	height=&#34;400&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%B8%AD%E6%96%AD%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E7%BC%96%E5%86%99_hu12196864162675659652.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32%E2%80%94%E2%80%94TIM%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%85%A5%E6%8D%95%E8%8E%B7%E4%B8%AD%E6%96%AD%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E7%BC%96%E5%86%99_hu8919324062346131731.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;490&#34;
		data-flex-basis=&#34;1176px&#34;
	
&gt;
判断是否是TIM1，判断是否是TIM1的4通道（HAL_TIM_ACTIVE_CHANNEL_4）
再读取指定寄存器的值&lt;/p&gt;
&lt;h3 id=&#34;定时器的输出比较模式&#34;&gt;定时器的输出比较模式
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%87%BA%E6%AF%94%E8%BE%83%E6%A8%A1%E5%BC%8F.png&#34;
	width=&#34;1446&#34;
	height=&#34;236&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%87%BA%E6%AF%94%E8%BE%83%E6%A8%A1%E5%BC%8F_hu11531026684352876851.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E8%BE%93%E5%87%BA%E6%AF%94%E8%BE%83%E6%A8%A1%E5%BC%8F_hu14198924481222301.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;612&#34;
		data-flex-basis=&#34;1470px&#34;
	
&gt;
较为鸡肋，对这些模式能理解其行为即可&lt;/p&gt;
&lt;h3 id=&#34;定时器的pwm&#34;&gt;定时器的PWM
&lt;/h3&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/as480133937/article/details/99231677&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;【STM32】HAL库 STM32CubeMX教程七&amp;mdash;PWM输出(呼吸灯)_stm32 hal pwm-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/demonneverhunts/article/details/135001314&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32CubeIde中互补PWM配置项的详细解读_ch idle state-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;pwm&#34;&gt;PWM
&lt;/h4&gt;
&lt;p&gt;脉冲宽度调制，用数字信号去模拟 模拟信号
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-PWM%E5%9B%BE%E8%A7%A3.png&#34;
	width=&#34;2279&#34;
	height=&#34;882&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-PWM%E5%9B%BE%E8%A7%A3_hu1515840751450853878.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-PWM%E5%9B%BE%E8%A7%A3_hu1814404565725477755.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;258&#34;
		data-flex-basis=&#34;620px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;pwm模式&#34;&gt;PWM模式
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-PWM%E7%9A%84%E5%87%A0%E7%A7%8D%E6%A8%A1%E5%BC%8F.png&#34;
	width=&#34;2023&#34;
	height=&#34;512&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-PWM%E7%9A%84%E5%87%A0%E7%A7%8D%E6%A8%A1%E5%BC%8F_hu6178332926466110193.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-PWM%E7%9A%84%E5%87%A0%E7%A7%8D%E6%A8%A1%E5%BC%8F_hu7638454572972725896.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;395&#34;
		data-flex-basis=&#34;948px&#34;
	
&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;PWM模式1 是 计数器值 小于 比较器值 时输出有效电平&lt;/li&gt;
&lt;li&gt;PWM模式2 是 计数器值 大于 比较器值 时输出有效电平&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;cube配置-2&#34;&gt;Cube配置
&lt;/h4&gt;
&lt;p&gt;为实现一个呼吸灯，进行以下配置
PWM的频率为&lt;code&gt;1000Hz&lt;/code&gt;，最大计数值为&lt;code&gt;1000-1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;STM32%e2%80%94%e2%80%94TIM%e5%ae%9a%e6%97%b6%e5%99%a8.md#%e5%86%85%e9%83%a8%e6%97%b6%e9%92%9f%e6%a8%a1%e5%bc%8f&#34; &gt;&lt;strong&gt;基础时钟配置&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%9F%BA%E7%A1%80%E6%97%B6%E9%92%9F%E8%AE%A1%E6%95%B0%E8%AE%BE%E7%BD%AE.png&#34;
	width=&#34;437&#34;
	height=&#34;176&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%9F%BA%E7%A1%80%E6%97%B6%E9%92%9F%E8%AE%A1%E6%95%B0%E8%AE%BE%E7%BD%AE_hu1633538757443388116.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-%E5%9F%BA%E7%A1%80%E6%97%B6%E9%92%9F%E8%AE%A1%E6%95%B0%E8%AE%BE%E7%BD%AE_hu16256555924781975787.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;248&#34;
		data-flex-basis=&#34;595px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;预分频器值，计数模式选择（向上计数模式，向下计数模式，中央对齐模式），自动重装载值，内部时钟分频，重复计数器值，是否开启影子寄存器&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PWM配置&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-PWM%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;460&#34;
	height=&#34;181&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-PWM%E9%85%8D%E7%BD%AE_hu17223923486060153282.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32TIM%E5%AE%9A%E6%97%B6%E5%99%A8-PWM%E9%85%8D%E7%BD%AE_hu5784584163411669148.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;254&#34;
		data-flex-basis=&#34;609px&#34;
	
&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Mode：选择PWM模式&lt;/li&gt;
&lt;li&gt;Pulse：设置比较寄存器的值&lt;/li&gt;
&lt;li&gt;Output compare preload：是否开启影子寄存器&lt;/li&gt;
&lt;li&gt;Fast Mode：是否需要输出非常高频的PWM信号&lt;/li&gt;
&lt;li&gt;CH Polarity：设置有效电平极性&lt;/li&gt;
&lt;li&gt;CH Idle State：空闲时，PWM通道的输出&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;hal库pwm常用函数&#34;&gt;HAL库PWM常用函数
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_TIM_PWM_Start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_CHANNEL_1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//开启PWM
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_TIM_PWM_Stop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_CHANNEL_1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭PWM
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_TIM_SET_COMPARE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_CHANNEL_1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//设置比较寄存器的值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;使用PWM控制流水灯
PWM的频率为&lt;code&gt;1000Hz&lt;/code&gt;，最大计数值为&lt;code&gt;1000-1&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN 1 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END 1 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* MCU Configuration--------------------------------------------------------*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Reset of all peripherals, Initializes the Flash interface and the Systick. */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;HAL_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN Init */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END Init */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Configure the system clock */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;SystemClock_Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN SysInit */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END SysInit */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Initialize all configured peripherals */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;MX_GPIO_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;MX_TIM1_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN 2 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;HAL_TIM_PWM_Start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_CHANNEL_1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END 2 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Infinite loop */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN WHILE */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;++&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;nf&#34;&gt;__HAL_TIM_SET_COMPARE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_CHANNEL_1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;nf&#34;&gt;HAL_Delay&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;nf&#34;&gt;__HAL_TIM_SET_COMPARE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;htim1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TIM_CHANNEL_1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;nf&#34;&gt;HAL_Delay&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* USER CODE END WHILE */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN 3 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END 3 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;编码器的使用&#34;&gt;编码器的使用
&lt;/h3&gt;
&lt;p&gt;（给我自己看的）
&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/weixin_44444810/article/details/120706435&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32CubeMX笔记（10）&amp;ndash;定时器TIM4的Encoder Mode（编码器模式）使用-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;uartdma与空闲中断综合&#34;&gt;UART、DMA与空闲中断（综合）
&lt;/h2&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/m0_47010960/article/details/128000029&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;（stm32之HAL库）UART工作在DMA模式要打开串口中断吗？_hal uart dma-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/577618858&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;10 通用同步异步收发器（USART） - 知乎&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;串口简介&#34;&gt;串口简介
&lt;/h3&gt;
&lt;p&gt;串口是串行接口的简称
常用串口：&lt;code&gt;RS232&lt;/code&gt;,&lt;code&gt;RS485&lt;/code&gt;,&lt;code&gt;USB(Universal Serial Bus)&lt;/code&gt;通用串行接口,&lt;code&gt;TTL&lt;/code&gt;串口
&lt;code&gt;TTL&lt;/code&gt;是&lt;code&gt;Transistor-Transistor Logic&lt;/code&gt;的简写，是一种电平逻辑，晶体管-晶体管逻辑&lt;/p&gt;
&lt;h3 id=&#34;usart简介&#34;&gt;USART简介
&lt;/h3&gt;
&lt;p&gt;USART，即通用同步/异步收发传输器（Universal Asynchronous Receiver/Transmitter)，是单片机上的一个外设&lt;/p&gt;
&lt;p&gt;UART遵循异步串行通信协议的，USART遵循同步串行通信协议
异步不需要统一时钟信号，同步需要统一时钟信号&lt;/p&gt;
&lt;p&gt;一般使用最多的是UART，我们此次学习也是针对UART&lt;/p&gt;
&lt;h3 id=&#34;uart通信协议&#34;&gt;UART通信协议
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32USART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-UART%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE.png&#34;
	width=&#34;1450&#34;
	height=&#34;346&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32USART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-UART%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE_hu2495030746923520299.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32USART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-UART%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE_hu16766829280963865577.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;419&#34;
		data-flex-basis=&#34;1005px&#34;
	
&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;起始位：发出1位低电平信号，表示开始传输字符&lt;/li&gt;
&lt;li&gt;数据位：真正发送的数据，一般为8位（1个字节），常采用ASCII编码，从最低位开始发送&lt;/li&gt;
&lt;li&gt;校验位：用于检验接收到的数据是否正确，分为奇校验和偶校验&lt;/li&gt;
&lt;li&gt;停止位：一组数据的结束传输的标志。可以是1位、1.5位、2位的高电平&lt;/li&gt;
&lt;li&gt;空闲位：空闲时数据线为高电平状态，代表无数据传输&lt;/li&gt;
&lt;li&gt;波特率：衡量传输速率的指标。UART通信中波特率等于比特率&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;uart发送接收机制&#34;&gt;UART发送/接收机制
&lt;/h3&gt;
&lt;p&gt;UART发送端口，首先是CPU将数据放入数据发送寄存器，然后发送移位寄存器会将数据从数据发送寄存器 取出进行移位并通过&lt;code&gt;UART_TX&lt;/code&gt;发送出去&lt;/p&gt;
&lt;p&gt;UART接收端口，首先是&lt;code&gt;UART_RX&lt;/code&gt;接收串行数据至接收移位寄存器，接收移位寄存器将串行数据移位变换为并行数据给数据接收寄存器，再通过APB总线给STM32内部&lt;/p&gt;
&lt;h3 id=&#34;uart模式&#34;&gt;UART模式
&lt;/h3&gt;
&lt;h4 id=&#34;轮询模式--中断模式去重说明&#34;&gt;轮询模式 / 中断模式（去重说明）
&lt;/h4&gt;
&lt;p&gt;这两种模式的底层原理与发送/接收时序，前文&lt;code&gt;USART中断&lt;/code&gt;章节已经完整展开，此处不再重复。&lt;/p&gt;
&lt;p&gt;如果你想快速回看：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;轮询模式：CPU持续查询寄存器状态，流程直观但会阻塞。&lt;/li&gt;
&lt;li&gt;中断模式：底层按字节触发中断搬运，上层在回调中处理完整数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;dma模式&#34;&gt;DMA模式
&lt;/h4&gt;
&lt;p&gt;DMA，全称为&lt;code&gt;Direct Memory Access&lt;/code&gt;，直接内存访问，本质是将传输数据从一个内存空间搬运至另一个内存空间，可以用来提供外设和内存，内存和外设之间的高速数据传输&lt;/p&gt;
&lt;p&gt;DMA模式中也会有中断参与，在&lt;code&gt;Cube&lt;/code&gt;配置中需要开启中断&lt;/p&gt;
&lt;h4 id=&#34;发送-3&#34;&gt;发送
&lt;/h4&gt;
&lt;p&gt;DMA接管“内存 -&amp;gt; 串口寄存器”的搬运，CPU不再逐字节参与发送中转。&lt;/p&gt;
&lt;h4 id=&#34;接收-3&#34;&gt;接收
&lt;/h4&gt;
&lt;p&gt;DMA接管“串口寄存器 -&amp;gt; 内存”的搬运，CPU主要负责在回调函数里处理数据。&lt;/p&gt;
&lt;h3 id=&#34;cube配置解析&#34;&gt;Cube配置解析
&lt;/h3&gt;
&lt;h4 id=&#34;基础参数配置&#34;&gt;基础参数配置
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-%E5%9F%BA%E7%A1%80%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;794&#34;
	height=&#34;309&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-%E5%9F%BA%E7%A1%80%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE_hu4541515614130285717.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-%E5%9F%BA%E7%A1%80%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE_hu5593458578770482069.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;256&#34;
		data-flex-basis=&#34;616px&#34;
	
&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Baud Rate：波特率&lt;/li&gt;
&lt;li&gt;Word Length：包含校验位在内的数据包长度&lt;/li&gt;
&lt;li&gt;Parity：奇偶校验位&lt;/li&gt;
&lt;li&gt;Stop Bits：停止位位数&lt;/li&gt;
&lt;li&gt;Data Direction：发送和&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;nvic配置&#34;&gt;NVIC配置
&lt;/h4&gt;
&lt;p&gt;如果使用中断模式，需要在&lt;code&gt;NVIC settings&lt;/code&gt;开启&lt;code&gt;USARTi global interrupt &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-NVIC%E8%AE%BE%E7%BD%AE.png&#34;
	width=&#34;1037&#34;
	height=&#34;113&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-NVIC%E8%AE%BE%E7%BD%AE_hu18289503046657738626.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-NVIC%E8%AE%BE%E7%BD%AE_hu5102099424962217469.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;917&#34;
		data-flex-basis=&#34;2202px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;dma配置&#34;&gt;DMA配置
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-DMA%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;1014&#34;
	height=&#34;466&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-DMA%E9%85%8D%E7%BD%AE_hu12594280780564786123.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-DMA%E9%85%8D%E7%BD%AE_hu14695578641400187003.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;217&#34;
		data-flex-basis=&#34;522px&#34;
	
&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add：选择添加&lt;code&gt;USARTi_RX&lt;/code&gt;的&lt;code&gt;DMA&lt;/code&gt;或者&lt;code&gt;USARTi_TX&lt;/code&gt;的&lt;code&gt;DMA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Delete：删除对应的DMA&lt;/li&gt;
&lt;li&gt;Mode：选择&lt;code&gt;normal&lt;/code&gt;模式或者&lt;code&gt;circular&lt;/code&gt;模式&lt;/li&gt;
&lt;li&gt;Data Byte：数据传输的位数&lt;/li&gt;
&lt;li&gt;Increment Address：开启地址自增，外设只有一个寄存器，地址固定，不需要开启地址自增，而内存中我们存数据的变量是数组，接受一字节数据后需要往后移，需要开启地址自增&lt;/li&gt;
&lt;li&gt;Priority：优先级设置&lt;/li&gt;
&lt;li&gt;Direction：方向，固定死的&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;gpio配置-1&#34;&gt;GPIO配置
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-GPIOsettings.png&#34;
	width=&#34;1012&#34;
	height=&#34;164&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-GPIOsettings_hu10464349181903929890.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-GPIOsettings_hu1805966639038626852.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;617&#34;
		data-flex-basis=&#34;1480px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;一般用来查看引脚的&lt;code&gt;GPIO&lt;/code&gt;配置，不需要更改（有特殊需求时，可以按需修改）
在&lt;code&gt;GPIO Settings&lt;/code&gt;处可以查看&lt;code&gt;TX&lt;/code&gt;和&lt;code&gt;RX&lt;/code&gt;的&lt;code&gt;GPIO&lt;/code&gt;引脚配置，此处可以看到&lt;code&gt;RX&lt;/code&gt;为输入模式，无上拉无下拉&lt;/p&gt;
&lt;h3 id=&#34;hal库uart常用函数&#34;&gt;HAL库UART常用函数
&lt;/h3&gt;
&lt;h4 id=&#34;轮询模式-1&#34;&gt;轮询模式
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_UART_Receive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_MAX_DELAY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//接收
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//发送
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;中断模式-1&#34;&gt;中断模式
&lt;/h4&gt;
&lt;p&gt;只能接收一次，接收完成后需要再次开启&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_UART_Receive_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//接收
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//发送
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//回调函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UART_RxCpltCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;dma模式-1&#34;&gt;DMA模式
&lt;/h4&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/m0_47010960/article/details/128000029&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;（stm32之HAL库）UART工作在DMA模式要打开串口中断吗？hal uart dma-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;HAL_UART_Receive_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//接收
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//发送
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//回调函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UART_RxCpltCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;HAL&lt;/code&gt;库中使用的&lt;code&gt;HAL_UART_Transmit_DMA&lt;/code&gt;，&lt;code&gt;HAL_UART_Receive_DMA&lt;/code&gt;等都有中断的参与，需要在&lt;code&gt;Cube&lt;/code&gt;中开启中断&lt;/p&gt;
&lt;h3 id=&#34;demo&#34;&gt;Demo
&lt;/h3&gt;
&lt;p&gt;接收定长数据&lt;code&gt;Nomad_violet&lt;/code&gt;，同时在主函数中翻转小灯&lt;/p&gt;
&lt;h4 id=&#34;轮询实现数据收发&#34;&gt;轮询实现数据收发
&lt;/h4&gt;
&lt;h4 id=&#34;cube配置-3&#34;&gt;Cube配置
&lt;/h4&gt;
&lt;p&gt;模式选择为异步&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;704&#34;
	height=&#34;103&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2%E9%85%8D%E7%BD%AE_hu9252176429549330016.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2%E9%85%8D%E7%BD%AE_hu8798023455270754163.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;683&#34;
		data-flex-basis=&#34;1640px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;波特率选择&lt;code&gt;115200 Bit/s&lt;/code&gt;，其余不动即可&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2%E9%85%8D%E7%BD%AE%E5%9F%BA%E7%A1%80%E5%8F%82%E6%95%B0.png&#34;
	width=&#34;692&#34;
	height=&#34;333&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2%E9%85%8D%E7%BD%AE%E5%9F%BA%E7%A1%80%E5%8F%82%E6%95%B0_hu16668396444744089662.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2%E9%85%8D%E7%BD%AE%E5%9F%BA%E7%A1%80%E5%8F%82%E6%95%B0_hu4223627293265520172.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;207&#34;
		data-flex-basis=&#34;498px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;将&lt;code&gt;PA8&lt;/code&gt;配置为&lt;code&gt;GPIO_Output&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2%E5%BC%95%E8%84%9A.png&#34;
	width=&#34;210&#34;
	height=&#34;108&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2%E5%BC%95%E8%84%9A_hu12445125660256453883.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2%E5%BC%95%E8%84%9A_hu12154975281623611940.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;194&#34;
		data-flex-basis=&#34;466px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPIO&lt;/code&gt;配置保持默认即可&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2GPIO%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;691&#34;
	height=&#34;76&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2GPIO%E9%85%8D%E7%BD%AE_hu1113707906726736272.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E8%BD%AE%E8%AF%A2GPIO%E9%85%8D%E7%BD%AE_hu14860898518155546774.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;909&#34;
		data-flex-basis=&#34;2182px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;代码实现-3&#34;&gt;代码实现
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;#34;string.h&amp;#34;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define rxBufferLen 16
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define txBufferLen 25
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;to feel,to experience &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 去感受，去经历「感其生，历其境」
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;HAL_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;SystemClock_Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;MX_GPIO_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;MX_USART1_UART_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;HAL_UART_Receive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_MAX_DELAY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//只能接收定长数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;		&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;strcmp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Nomad_violet&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//Nomad_violet 12字节
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;			&lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nf&#34;&gt;HAL_GPIO_TogglePin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPIOA&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_PIN_8&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;中断实现数据收发&#34;&gt;中断实现数据收发
&lt;/h4&gt;
&lt;h4 id=&#34;cube配置-4&#34;&gt;Cube配置
&lt;/h4&gt;
&lt;p&gt;配置同上，只需额外开启中断即可&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E4%B8%AD%E6%96%AD%E5%BC%80%E5%90%AF.png&#34;
	width=&#34;696&#34;
	height=&#34;118&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E4%B8%AD%E6%96%AD%E5%BC%80%E5%90%AF_hu2603047621200826920.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32UART%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-Demo%E4%B8%AD%E6%96%AD%E5%BC%80%E5%90%AF_hu106925818943637117.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;589&#34;
		data-flex-basis=&#34;1415px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;代码实现-4&#34;&gt;代码实现
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;#34;string.h&amp;#34;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define rxBufferLen 12
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define txBufferLen 25
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;to feel,to experience &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 去感受，去经历「感其生，历其境」
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UART_RxCpltCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;strcmp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Nomad_violet&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;nf&#34;&gt;HAL_UART_Receive_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;HAL_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;SystemClock_Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;MX_GPIO_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;MX_USART1_UART_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nf&#34;&gt;HAL_UART_Receive_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;nf&#34;&gt;HAL_GPIO_TogglePin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPIOA&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GPIO_PIN_8&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	    &lt;span class=&#34;nf&#34;&gt;HAL_Delay&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;500&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://shequ.stmicroelectronics.cn/thread-637349-1-1.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32 hal库串口空闲中断最新用法 - STM32团队 ST意法半导体中文论坛&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/as480133937/article/details/104927922&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;【STM32】 DMA原理，步骤超细详解，一文看懂DMA-CSDN博客&lt;/a&gt;（非常详细）&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.iotword.com/25305.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32CubeIDE HAL库DMA与UART不定长数据接收实现：空闲中断详解-物联沃-IOTWORD物联网&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/qq_47159466/article/details/124542339&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32 hal库串口空闲中断最新用法_stm32hal库串口空闲中断-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/soledade/article/details/129030082&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;HAL库 串口空闲中断+DMA接收不定长数据 详解及踩坑_hal库串口空闲中断-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/m0_47010960/article/details/128000029&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;（stm32之HAL库）UART工作在DMA模式要打开串口中断吗？hal uart dma-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;（写的非常好，非常有助于提升底层理解）&lt;/p&gt;
&lt;h2 id=&#34;dma补充&#34;&gt;DMA（补充）
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;说明：本节是 DMA 原理与细节补充，和上文“UART、DMA与空闲中断（综合）”互为补充。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;DMA，全称为&lt;code&gt;Direct Memory Access&lt;/code&gt;，直接内存访问，本质是将传输数据从一个内存空间搬运至另一个内存空间，可以用来提供外设和内存，内存和外设之间的高速数据传输&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;HAL&lt;/code&gt;库中直接使用的&lt;code&gt;HAL_UART_Transmit_DMA&lt;/code&gt;，&lt;code&gt;HAL_UART_Receive_DMA&lt;/code&gt;，&lt;code&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/code&gt;等都有中断的参与，需要在&lt;code&gt;Cube&lt;/code&gt;中开启中断&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32CubeMXDMA%E4%BD%BF%E7%94%A8%E4%B8%8E%E7%A9%BA%E9%97%B2%E4%B8%AD%E6%96%AD-%E4%B8%AD%E6%96%AD%E5%BC%80%E5%90%AF.png&#34;
	width=&#34;696&#34;
	height=&#34;118&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32CubeMXDMA%E4%BD%BF%E7%94%A8%E4%B8%8E%E7%A9%BA%E9%97%B2%E4%B8%AD%E6%96%AD-%E4%B8%AD%E6%96%AD%E5%BC%80%E5%90%AF_hu2603047621200826920.png 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/STM32CubeMXDMA%E4%BD%BF%E7%94%A8%E4%B8%8E%E7%A9%BA%E9%97%B2%E4%B8%AD%E6%96%AD-%E4%B8%AD%E6%96%AD%E5%BC%80%E5%90%AF_hu106925818943637117.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;589&#34;
		data-flex-basis=&#34;1415px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;对具体底层原理和DMA模式实现底层与中断模式底层实现区别感兴趣可参考以下博客
&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/m0_47010960/article/details/128000029&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;（stm32之HAL库）UART工作在DMA模式要打开串口中断吗？_hal uart dma-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;usart发送&#34;&gt;USART发送
&lt;/h3&gt;
&lt;p&gt;轮询/中断下的发送机制前文已讲，这里只保留 DMA 发送新增的关键点。&lt;/p&gt;
&lt;h4 id=&#34;usart的dma发送&#34;&gt;USART的DMA发送
&lt;/h4&gt;
&lt;p&gt;没有DMA的话，CPU会作为数据发送的中转站，而使用DMA的话，整个数据传输过程不需要CPU的参与，由DMA代理执行，DMA负责将内存数据搬运至外设的传输寄存器&lt;/p&gt;
&lt;p&gt;在整个数据发送过半时会触发一个传输过半中断，所有数据传输完成后会调用传输完成中断回调函数（&lt;code&gt;HAL_UART_TxCpltCallback&lt;/code&gt;）&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;HAL_UART_Transmit_DMA&lt;/code&gt;的传输完成中断回调函数&lt;code&gt;HAL_UART_TxCpltCallback&lt;/code&gt;以及传输过半中断回调函数&lt;code&gt;HAL_UART_TxHalfCpltCallback&lt;/code&gt;（这两个回调函数在&lt;code&gt;HAL_UART_Transmit_IT&lt;/code&gt;中同样有）&lt;/p&gt;
&lt;h4 id=&#34;dma发送注意事项&#34;&gt;DMA发送注意事项
&lt;/h4&gt;
&lt;p&gt;在传输的过程中，当传输一半的数据后，半传输标志(HTIF)被置1，当设置了允许半传输中断位(HTIE)时，将产生一个中断请求。在数据传输结束后，传输完成标志(TCIF)被置1，当设置了允许传输完成中断位 (TCIE)时，将产生一个中断请求&lt;/p&gt;
&lt;p&gt;会触发的三个中断，传输完成中断，传输过半中断，错误中断
在&lt;code&gt;stm32f1xx_hal_uart.c&lt;/code&gt;的&lt;code&gt;HAL_UART_Transmit_DMA&lt;/code&gt;函数中可以查看到&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	  &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	  &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	  &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* Set the UART DMA transfer complete callback */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmatx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XferCpltCallback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_DMATransmitCplt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* Set the UART DMA Half transfer complete callback */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmatx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XferHalfCpltCallback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_DMATxHalfCplt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* Set the DMA error callback */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmatx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XferErrorCallback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_DMAError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	  &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	  &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	  &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;usart接收&#34;&gt;USART接收
&lt;/h3&gt;
&lt;p&gt;轮询/中断下的接收机制前文已讲，这里只保留 DMA 接收新增的关键点。&lt;/p&gt;
&lt;h4 id=&#34;usart的dma接收&#34;&gt;USART的DMA接收
&lt;/h4&gt;
&lt;p&gt;没有DMA的话，CPU会作为数据转运的中转站，而使用DMA的话，整个数据转运过程不需要CPU的参与，由DMA代理执行&lt;/p&gt;
&lt;p&gt;在整个数据接收过半时会触发一个传输过半中断，所有数据接收完成后会调用传输完成中断回调函数（&lt;code&gt;HAL_UART_RxCpltCallback&lt;/code&gt;）&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UART_Receive_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;HAL_UART_Receive_DMA&lt;/code&gt;的接收完成中断回调函数&lt;code&gt;HAL_UART_RxCpltCallback&lt;/code&gt;以及接收过半中断回调函数&lt;code&gt;HAL_UART_RxHalfCpltCallback&lt;/code&gt;（这两个回调函数在&lt;code&gt;HAL_UART_Receive_IT&lt;/code&gt;中同样有）&lt;/p&gt;
&lt;h4 id=&#34;dma接收注意事项&#34;&gt;DMA接收注意事项
&lt;/h4&gt;
&lt;p&gt;同DMA发送，类比即可&lt;/p&gt;
&lt;h2 id=&#34;hal库usart使用dma补充&#34;&gt;HAL库USART使用DMA（补充）
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;说明：本节聚焦 HAL API 视角，示例与上文综合章节可交叉阅读。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果&lt;code&gt;USART&lt;/code&gt;串口的DMA出现错误，会调用&lt;code&gt;HAL_UART_ErrorCallback&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;dma发送&#34;&gt;DMA发送
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;会触发中断，对应回调函数为&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;HAL_UART_TxCpltCallback&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HAL_UART_TxHalfCpltCallback&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;dma接收&#34;&gt;DMA接收
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UART_Receive_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;会触发的中断，对应的回调函数为&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;HAL_UART_RxCpltCallback&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HAL_UART_RxHalfCpltCallback&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;dma模式-2&#34;&gt;DMA模式
&lt;/h3&gt;
&lt;h4 id=&#34;normal模式&#34;&gt;normal模式
&lt;/h4&gt;
&lt;p&gt;以接收为例
单次接收，接收至数据上限，完成整个固定数据接收后停止，再次接收需要再次开启&lt;code&gt;HAL_UART_Receive_DMA&lt;/code&gt;
，需要软件显式重启，触发接收过半和接收完成中断&lt;/p&gt;
&lt;p&gt;总结：单次传输，完成后停止，需要软件显式重启，接收过半和接收完成中断&lt;/p&gt;
&lt;h4 id=&#34;circular模式&#34;&gt;circular模式
&lt;/h4&gt;
&lt;p&gt;以接收为例
无限循环，接收至数据上限一半，触发接收过半中断，接受至数据上限，触发接收完成中断，同时会硬件自动重启，接收完成中断会调用对应的接收完成中断回调函数&lt;/p&gt;
&lt;p&gt;总结：无限循环，硬件自动重启，接收过半和接收完成中断&lt;/p&gt;
&lt;h2 id=&#34;空闲中断&#34;&gt;空闲中断
&lt;/h2&gt;
&lt;h3 id=&#34;空闲中断定义&#34;&gt;空闲中断定义
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;空闲中断（IDLE Interrupt）&lt;/strong&gt; 是UART通信中的一种特殊中断类型，它在检测到UART接收线路&lt;strong&gt;连续空闲超过1个字节传输时间&lt;/strong&gt;时触发的中断。&amp;ldquo;空闲&amp;quot;指线路保持&lt;strong&gt;逻辑1状态&lt;/strong&gt;（高电平），线上无数据传输&lt;/p&gt;
&lt;h3 id=&#34;hal库自带的空闲中断实现&#34;&gt;HAL库自带的空闲中断实现
&lt;/h3&gt;
&lt;p&gt;使用的是&lt;code&gt;HAL&lt;/code&gt;库提供的拓展函数，同时都需要在&lt;code&gt;Cube&lt;/code&gt;中开启中断&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//在阻塞模式下接收一定数量的数据，直到接收到预期数量的数据或发生空闲事件。 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_ReceiveToIdle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//在中断模式下接收一定数量的数据，直到接收到预期数量的数据或发生空闲事件。 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_ReceiveToIdle_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//在DMA模式下接收一定数量的数据，直到接收到预期数量的数据或发生空闲事件。 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//使用空闲中断时的接收回调函数 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_RxEventCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在触发空闲中断，接收完成中断都会调用&lt;code&gt;HAL_UARTEx_RxEventCallback&lt;/code&gt;回调函数，需要注意的是在&lt;code&gt;F103c8t6&lt;/code&gt;单片机以及其他&lt;code&gt;st&lt;/code&gt;系列单片机上，使用&lt;code&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/code&gt;时，接收过半中断也会去调用该回调函数&lt;/p&gt;
&lt;h4 id=&#34;接收过半中断的处理&#34;&gt;接收过半中断的处理
&lt;/h4&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.iotword.com/25305.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;STM32CubeIDE HAL库DMA与UART不定长数据接收实现：空闲中断详解-物联沃-IOTWORD物联网&lt;/a&gt;
&lt;code&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/code&gt;会调用&lt;code&gt;UART_Start_Receive_DMA(huart, pData, Size)&lt;/code&gt;函数，该函数会把DMA中断传输完成，半传输，传输错误全部开启&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_DMA_ENABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DMA_IT_TC&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_IT_HC&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_IT_TE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;UART_Start_Receive_DMA(huart, pData, Size)&lt;/code&gt; 设置接收数组缓存到达数组一半时会执行下面的回调函数&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;/* Set the UART DMA Half transfer complete callback */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XferHalfCpltCallback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_DMARxHalfCplt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在&lt;code&gt;DMA&lt;/code&gt;的中断处理函数中，会调用&lt;code&gt;huart-&amp;gt;hdmarx-&amp;gt;XferHalfCpltCallback&lt;/code&gt;，此处即&lt;code&gt;UART_DMARxHalfCplt&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_DMA_IRQHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;flag_it&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DmaBaseAddress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ISR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;source_it&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Instance&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CCR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Half Transfer Complete Interrupt management ******************************/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flag_it&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DMA_FLAG_HT1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ChannelIndex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RESET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;source_it&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_IT_HT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RESET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;......&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XferHalfCpltCallback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;cm&#34;&gt;/* Half transfer callback */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;XferHalfCpltCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;......&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;......&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;而&lt;code&gt;UART_DMARxHalfCplt&lt;/code&gt;会调用&lt;code&gt;HAL_UARTEx_RxEventCallback&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;UART_DMARxHalfCplt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Parent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Initialize type of RxEvent that correspond to RxEvent callback execution;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     In this case, Rx Event type is Half Transfer */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxEventType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_UART_RXEVENT_HT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Check current reception Mode :  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     If Reception till IDLE event has been selected : use Rx Event callback */&lt;/span&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReceptionType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_UART_RECEPTION_TOIDLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;cm&#34;&gt;/*Call registered Rx Event callback*/&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;RxEventCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxXferSize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2U&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#else  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;cm&#34;&gt;/*Call legacy weak Rx Event callback*/&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_RxEventCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxXferSize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2U&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#endif &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* USE_HAL_UART_REGISTER_CALLBACKS */&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* In other cases : use Rx Half Complete callback */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;cm&#34;&gt;/*Call registered Rx Half complete callback*/&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;RxHalfCpltCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#else  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;cm&#34;&gt;/*Call legacy weak Rx Half complete callback*/&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;HAL_UART_RxHalfCpltCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#endif &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* USE_HAL_UART_REGISTER_CALLBACKS */&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;为了避免接收过半中断的调用，需要使用下面的语句&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DMA_IT_HT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭dma接收半满中断函数，这样我们在接收一组数据时就不会触发半满中断，dma就可以正常接收一组数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;另外在&lt;code&gt;UART_DMAReceiveCplt&lt;/code&gt;函数中也调用了&lt;code&gt;HAL_UARTEx_RxEventCallback&lt;/code&gt;函数&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;UART_DMAReceiveCplt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;dma空闲中断的实现接收不定长数据&#34;&gt;DMA+空闲中断的实现接收不定长数据
&lt;/h2&gt;
&lt;h3 id=&#34;方式1-1&#34;&gt;方式1
&lt;/h3&gt;
&lt;p&gt;自定义DMA+空闲中断&lt;/p&gt;
&lt;h4 id=&#34;前置内容&#34;&gt;前置内容
&lt;/h4&gt;
&lt;p&gt;需要自己写的宏定义&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define __HAL_DMA_SET_COUNTERT(__HANDLE__,__COUNTER__)  ((__HANDLE__)-&amp;gt;Instance-&amp;gt;CNDTR = (uint16_t)(__COUNTER__))
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//重新设定计数值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//用法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_DMA_SET_COUNTERT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;用到的宏定义&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_DMA_GET_COUNTER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//获取剩余未传输的计数值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;用到的关于中断的操作&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭DMA
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_DMA_ENABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//开启DMA
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//清除空闲标志位
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_UART_CLEAR_IDLEFLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//开启空闲中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_UART_ENABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_IT_IDLE&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//关闭空闲中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_UART_DISABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_IT_IDLE&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;代码实现-5&#34;&gt;代码实现
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define rxBufferLen 10
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;UART_InitDMAReceive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;__HAL_UART_CLEAR_IDLEFLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//清除空闲中断标志位
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nf&#34;&gt;__HAL_UART_ENABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_IT_IDLE&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//使能空闲中断  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nf&#34;&gt;HAL_UART_Receive_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//开启DMA接收
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;需要关闭DMA才能重设DMA的COUNTER&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//自定义的DMA空闲中断回调函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;UART_DMAIdleCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//失能DMA
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datalen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_GET_COUNTER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datalen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;z&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;32&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datalen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_SET_COUNTERT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//重置DMA计数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_ENABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//使能DMA 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;USART1_IRQHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN USART1_IRQn 0 */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END USART1_IRQn 0 */&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;HAL_UART_IRQHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE BEGIN USART1_IRQn 1 */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;//触发空闲中断后，会进入中断请求处理函数 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_UART_GET_FLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_FLAG_IDLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RESET&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//在此判断是否为空闲中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_UART_CLEAR_IDLEFLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//清除空闲中断标志位
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_UART_DISABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_IT_IDLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//失能空闲中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nf&#34;&gt;UART_DMAIdleCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//调用自定义中断回调函数 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_UART_ENABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_IT_IDLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//使能空闲中断  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* USER CODE END USART1_IRQn 1 */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;关于normal和circular在方式1的空闲中断实现的区别&#34;&gt;关于normal和circular在方式1的空闲中断实现的区别
&lt;/h4&gt;
&lt;h4 id=&#34;normal模式-1&#34;&gt;normal模式
&lt;/h4&gt;
&lt;p&gt;在上述空闲中断实现中，如果使用&lt;code&gt;normal&lt;/code&gt;模式，需要注意接收的数据一定不能超过&lt;code&gt;rxBufferLen&lt;/code&gt;，一旦超过，&lt;code&gt;DMA&lt;/code&gt;接收就会终止&lt;/p&gt;
&lt;p&gt;执行流程是，触发空闲中断，进入&lt;code&gt;USART1_IRQHandler&lt;/code&gt;，再进入自定义空闲中断，在里面重新设置了&lt;code&gt;DMA&lt;/code&gt;的计数值（指针也会重新设置，重新指向&lt;code&gt;rxBuffer[0]&lt;/code&gt;），最开始开启的&lt;code&gt;HAL_UART_Receive_DMA&lt;/code&gt;始终没有接收完 完整的数据，就不会关闭，一直接收&lt;/p&gt;
&lt;p&gt;但如果接收的数据超过&lt;code&gt;rxBufferLen&lt;/code&gt;，会触发接收过半和接收完成中断（对应回调函数没使用，约等于空函数），同时&lt;code&gt;HAL_UART_Receive_DMA&lt;/code&gt;会结束，需要软件显式重启&lt;/p&gt;
&lt;p&gt;例如：&lt;code&gt;rxBufferlen=10&lt;/code&gt;，发送&lt;code&gt;12345678910&lt;/code&gt;，会回复&lt;code&gt;1234567891&lt;/code&gt;，随后&lt;code&gt;DMA&lt;/code&gt;终止，再发送数据无回复&lt;/p&gt;
&lt;h4 id=&#34;circular模式-1&#34;&gt;circular模式
&lt;/h4&gt;
&lt;p&gt;在上述空闲中断实现中，如果使用&lt;code&gt;circular&lt;/code&gt;模式，则接收的数据可以超过&lt;code&gt;rxBufferLen&lt;/code&gt;，超过后，&lt;code&gt;DMA&lt;/code&gt;接收会自动重启&lt;/p&gt;
&lt;p&gt;执行流程是，触发空闲中断，进入&lt;code&gt;USART1_IRQHandler&lt;/code&gt;，再进入自定义空闲中断，在里面重新设置了&lt;code&gt;DMA&lt;/code&gt;的计数值（指针也会重新设置，重新指向&lt;code&gt;rxBuffer[0]&lt;/code&gt;），就算接收数据超过&lt;code&gt;rxBufferLen&lt;/code&gt;，&lt;code&gt;HAL_UART_Receive_DMA&lt;/code&gt;也会重新启动&lt;/p&gt;
&lt;p&gt;但是需要注意，如果达到&lt;code&gt;rxBufferLen&lt;/code&gt;,会触发接收过半和接收完成中断，然后硬件重启，重新回到&lt;code&gt;rxBufferLen[0]&lt;/code&gt;的位置读数据，直至发生空闲中断&lt;/p&gt;
&lt;p&gt;例如：&lt;code&gt;rxBufferlen=10&lt;/code&gt;，发送&lt;code&gt;12345678910&lt;/code&gt;，会回复&lt;code&gt;0&lt;/code&gt;，随后&lt;code&gt;DMA&lt;/code&gt;仍然正常工作&lt;/p&gt;
&lt;h3 id=&#34;方式2-1&#34;&gt;方式2
&lt;/h3&gt;
&lt;p&gt;使用&lt;code&gt;HAL&lt;/code&gt;库提供的拓展空闲中断，使用&lt;code&gt;normal&lt;/code&gt;模式&lt;/p&gt;
&lt;p&gt;该方式下的空闲中断回调函数为&lt;code&gt;HAL_UARTEx_RxEventCallback&lt;/code&gt;
，需要注意接收过半中断也会调用&lt;code&gt;HAL_UARTEx_RxEventCallback&lt;/code&gt;的问题，在每次开启&lt;code&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/code&gt;后都需要关闭接收过半中断&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DMA_IT_HT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭dma接收半满中断函数，这样我们在接收一组数据时就不会触发半满中断，dma就可以正常接收一组数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;注意需要添加&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hdma_usart1_tx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;当接收数据超过&lt;code&gt;rxBufferLen&lt;/code&gt;时，接收完成中断函数会调用&lt;code&gt;HAL_UARTEx_RxEventCallback&lt;/code&gt;回调函数，然后重新开启接收&lt;/p&gt;
&lt;p&gt;例如：&lt;code&gt;rxBufferLen=10&lt;/code&gt;，接收&lt;code&gt;12345678910&lt;/code&gt;，发送&lt;code&gt;1234567891&lt;/code&gt;（就是因为接收完成中断导致），后面&lt;code&gt;DMA&lt;/code&gt;空闲中断接收正常开启&lt;/p&gt;
&lt;h4 id=&#34;代码实现-6&#34;&gt;代码实现
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hdma_usart1_tx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define rxBufferLen 512
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;Init_IdleDMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//初始化，开启DMA空闲中断接收
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_IT_HT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭f103板子DMA的接收过半中断  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_RxEventCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//接收完成和接收过半，空闲中断都会调用该中断回调函数  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;memcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//normal模式，接受一次后需要重新开启  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_IT_HT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭f103板子DMA的接收过半中断  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;//Init_IdleDMA();
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;关于normal和circular在方式2下的空闲中断实现的区别&#34;&gt;关于normal和circular在方式2下的空闲中断实现的区别
&lt;/h4&gt;
&lt;h4 id=&#34;normal模式-2&#34;&gt;normal模式
&lt;/h4&gt;
&lt;p&gt;方式2中，在数据接收过半，接收完成，空闲时会触发对应中断，最后调用&lt;code&gt;HAL_UARTEx_RxEventCallback&lt;/code&gt;回调函数，在回调函数中软件显式重启&lt;code&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;circular模式-2&#34;&gt;circular模式
&lt;/h4&gt;
&lt;p&gt;方式2中，若使用&lt;code&gt;circular&lt;/code&gt;模式，则数据会一直积累，到达&lt;code&gt;rxBufferLen&lt;/code&gt;时，会硬件重启，同时也会有数据接收过半，接收完成，空闲时会触发对应中断，最后调用&lt;code&gt;HAL_UARTEx_RxEventCallback&lt;/code&gt;回调函数&lt;/p&gt;
&lt;p&gt;例如：
(1)关闭接收过半中断
&lt;code&gt;rxBufferLen=10&lt;/code&gt;，接收&lt;code&gt;123&lt;/code&gt;，发送&lt;code&gt;123&lt;/code&gt;，
再接收&lt;code&gt;456&lt;/code&gt;，发送&lt;code&gt;123456&lt;/code&gt;，
再接收&lt;code&gt;78910&lt;/code&gt;，会先发送&lt;code&gt;1234567891&lt;/code&gt;（接收完成），再发送&lt;code&gt;0&lt;/code&gt;（空闲中断），
再接收&lt;code&gt;111213&lt;/code&gt;，发送&lt;code&gt;0111213&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;(2)未关闭接收过半中断
&lt;code&gt;rxBufferLen=10&lt;/code&gt;，接收&lt;code&gt;123&lt;/code&gt;，发送&lt;code&gt;123&lt;/code&gt;，
再接收&lt;code&gt;123&lt;/code&gt;，会先发送&lt;code&gt;12312&lt;/code&gt;（接收过半中断），再发送&lt;code&gt;123123&lt;/code&gt;空闲中断，
再接收&lt;code&gt;12345&lt;/code&gt;，会先发送&lt;code&gt;1231231234&lt;/code&gt;（接收完成中断），再发送&lt;code&gt;5&lt;/code&gt;空闲中断&lt;/p&gt;
&lt;h3 id=&#34;方式3&#34;&gt;方式3
&lt;/h3&gt;
&lt;p&gt;使用&lt;code&gt;HAL&lt;/code&gt;库提供的空闲中断，但是使用&lt;code&gt;circular&lt;/code&gt;模式实现&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;circuar&lt;/code&gt;要想实现一帧一帧不定长数据的接收主要需要考虑的就是如何实现在接收完一帧后让&lt;code&gt;DMA&lt;/code&gt;的计数值重置&lt;/p&gt;
&lt;h4 id=&#34;实现原理&#34;&gt;实现原理
&lt;/h4&gt;
&lt;h4 id=&#34;关闭&#34;&gt;关闭
&lt;/h4&gt;
&lt;p&gt;要实现&lt;code&gt;DMA&lt;/code&gt;计数值的重置，需要使用&lt;code&gt;HAL_UART_DMAStop(&amp;amp;huart1)&lt;/code&gt;函数将DMA关闭&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UART_DMAStop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dmarequest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x00U&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* The Lock is not implemented on this API to allow the user application  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():     when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated     and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()     */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Stop UART DMA Tx request if ongoing */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;dmarequest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_IS_BIT_SET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Instance&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CR3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;USART_CR3_DMAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gState&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_UART_STATE_BUSY_TX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dmarequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;ATOMIC_CLEAR_BIT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Instance&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CR3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;USART_CR3_DMAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* Abort the UART DMA Tx channel */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmatx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nf&#34;&gt;HAL_DMA_Abort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmatx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;UART_EndTxTransfer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Stop UART DMA Rx request if ongoing */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;dmarequest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_IS_BIT_SET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Instance&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CR3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;USART_CR3_DMAR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxState&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_UART_STATE_BUSY_RX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dmarequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;ATOMIC_CLEAR_BIT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Instance&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CR3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;USART_CR3_DMAR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* Abort the UART DMA Rx channel */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nf&#34;&gt;HAL_DMA_Abort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;UART_EndRxTransfer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中会调用&lt;code&gt;HAL_DMA_Abort(huart-&amp;gt;hdmatx)&lt;/code&gt;，但都不会重置DMA的计数值&lt;/p&gt;
&lt;h4 id=&#34;开启&#34;&gt;开启
&lt;/h4&gt;
&lt;p&gt;在关闭&lt;code&gt;DMA&lt;/code&gt;后，需要&lt;code&gt;HAL_UARTEx_ReceiveToIdle_DMA(&amp;amp;huart1, (uint8_t*)rxBuffer, rxBufferLen)&lt;/code&gt;重新开启&lt;code&gt;DMA&lt;/code&gt;以及空闲中断&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/code&gt;中，会进行判断&lt;code&gt;if (huart-&amp;gt;RxState == HAL_UART_STATE_READY) &lt;/code&gt;，判断&lt;code&gt;RxState&lt;/code&gt;是否为&lt;code&gt;HAL_UART_STATE_READY&lt;/code&gt;，如果是，则说明&lt;code&gt;uart&lt;/code&gt;没有开启，但是是在预备状态，随后会去调用&lt;code&gt;UART_Start_Receive_DMA(huart, pData, Size)&lt;/code&gt;开启&lt;code&gt;uart&lt;/code&gt;以及&lt;code&gt;DMA&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* Check that a Rx process is not already ongoing */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxState&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_UART_STATE_READY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0U&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_ERROR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* Set Reception type to reception till IDLE Event*/&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReceptionType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_UART_RECEPTION_TOIDLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxEventType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_UART_RXEVENT_TC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;UART_Start_Receive_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* Check Rx process has been successfully started */&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReceptionType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_UART_RECEPTION_TOIDLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nf&#34;&gt;__HAL_UART_CLEAR_IDLEFLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nf&#34;&gt;ATOMIC_SET_BIT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Instance&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CR1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;USART_CR1_IDLEIE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;cm&#34;&gt;/* In case of errors already pending when reception is started,  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;         Interrupts may have already been raised and lead to reception abortion.         (Overrun error for instance).         In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */&lt;/span&gt;      &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_ERROR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_BUSY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在&lt;code&gt;UART_Start_Receive_DMA&lt;/code&gt;中会将&lt;code&gt;uart&lt;/code&gt;的&lt;code&gt;RxState&lt;/code&gt;设置为&lt;code&gt;HAL_UART_STATE_BUSY_RX&lt;/code&gt;，中间还会去调用&lt;code&gt;HAL_DMA_Start_IT&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;UART_Start_Receive_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tmp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pRxBuffPtr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxXferSize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorCode&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_UART_ERROR_NONE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RxState&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HAL_UART_STATE_BUSY_RX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;......&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;HAL_DMA_Start_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Instance&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tmp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;......&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在&lt;code&gt;HAL_DMA_Start_IT&lt;/code&gt;会调用&lt;code&gt;DMA_SetConfig&lt;/code&gt;去对&lt;code&gt;DMA&lt;/code&gt;计数值等进行重置&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;HAL_StatusTypeDef&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_DMA_Start_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SrcAddress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DstAddress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DataLength&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;......&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;cm&#34;&gt;/* Configure the source, destination address and the data length &amp;amp; clear flags*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nf&#34;&gt;DMA_SetConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SrcAddress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DstAddress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DataLength&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;......&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;原理总结&#34;&gt;原理总结
&lt;/h4&gt;
&lt;p&gt;1.&lt;code&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/code&gt;如果判断出&lt;code&gt;huart-&amp;gt;RxState == HAL_UART_STATE_READY&lt;/code&gt;会调用&lt;code&gt;UART_Start_Receive_DMA&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;2.&lt;code&gt;UART_Start_Receive_DMA&lt;/code&gt;会调用&lt;code&gt;HAL_DMA_Start_IT&lt;/code&gt;，同时会将&lt;code&gt;RxState&lt;/code&gt;修改为&lt;code&gt;BUSY&lt;/code&gt;
&lt;code&gt;huart-&amp;gt;RxState = HAL_UART_STATE_BUSY_RX&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;3.&lt;code&gt;HAL_DMA_Start_IT&lt;/code&gt;会调用&lt;code&gt;DMA_SetConfig&lt;/code&gt;进行&lt;code&gt;DMA&lt;/code&gt;计数值等的重置&lt;/p&gt;
&lt;p&gt;而使用&lt;code&gt;HAL_UART_DMAStop&lt;/code&gt;可以保证在回调函数处理数据时停止&lt;code&gt;DMA&lt;/code&gt;接收，保证数据不会被覆盖，同时可以将&lt;code&gt;huart-&amp;gt;RxState&lt;/code&gt;状态设置为&lt;code&gt;HAL_UART_STATE_READY&lt;/code&gt;，随后再次开启&lt;code&gt;DMA&lt;/code&gt;空闲中断接收就能重置&lt;code&gt;DMA&lt;/code&gt;计数值&lt;/p&gt;
&lt;p&gt;从而实现非定长数据的接收&lt;/p&gt;
&lt;h4 id=&#34;代码实现-7&#34;&gt;代码实现
&lt;/h4&gt;
&lt;p&gt;同样注意，需要关闭接收过半中断&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hdma_usart1_tx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define rxBufferLen 512
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//初始化
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;Init_IdleDMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_IT_HT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭DMA的接收过半中断  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//回调函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_RxEventCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//接收完成和接收过半，空闲中断都会调用该中断回调函数  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;HAL_UART_DMAStop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//不会改变DMA的计数值 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nf&#34;&gt;memcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;memset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//如果是normal模式，接受一次后需要重新开启，如果关闭了DMA，也需要重新启动  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_IT_HT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭f103板子DMA的接收过半中断  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;实验检验&#34;&gt;实验检验
&lt;/h4&gt;
&lt;p&gt;我们设置&lt;code&gt;cnt_i&lt;/code&gt;去记录&lt;code&gt;HAL_UART_DMAStop(&amp;amp;huart1)&lt;/code&gt;前后以及&lt;code&gt;HAL_UARTEx_ReceiveToIdle_DMA(&amp;amp;huart1, (uint8_t*)rxBuffer, rxBufferLen)&lt;/code&gt;前后的&lt;code&gt;DMA&lt;/code&gt;计数值变化&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define rxBufferLen 512
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;Init_IdleDMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_IT_HT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭DMA的接收过半中断  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_RxEventCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//接收完成和接收过半，空闲中断都会调用该中断回调函数  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cnt_1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_GET_COUNTER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;HAL_UART_DMAStop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//不会改变DMA的计数值  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cnt_2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_GET_COUNTER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;memcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;memset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//如果是normal模式，接受一次后需要重新开启，如果关闭了DMA，也需要重新启动  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_IT_HT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭f103板子DMA的接收过半中断  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kt&#34;&gt;uint32_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cnt_3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_GET_COUNTER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;sprintf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cnt_1=%d cnt_2=%d cnt_3=%d&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cnt_1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cnt_2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cnt_3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;实验结果&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;输入：123456789101112131415161718192021
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;输出：123456789101112131415161718192021  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cnt_1=479 cnt_2=479 cnt_3=512
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;证明我们在重启&lt;code&gt;DMA&lt;/code&gt;空闲中断时实现了&lt;code&gt;DMA&lt;/code&gt;计数值重置&lt;/p&gt;
&lt;h3 id=&#34;方式4&#34;&gt;方式4
&lt;/h3&gt;
&lt;p&gt;再仔细想一想，在&lt;code&gt;circuar&lt;/code&gt;要想实现一帧一帧不定长数据的接收主要需要考虑的就是如何实现在接收完一帧后让&lt;code&gt;DMA&lt;/code&gt;的计数值重置，也就是说没有必要为此使用&lt;code&gt;HAL_UART_DMAStop&lt;/code&gt;再重启&lt;code&gt;DMA&lt;/code&gt;空闲中断接收&lt;/p&gt;
&lt;p&gt;如何优化呢，结合方式1的实现就可以得到答案&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//需要关闭DMA才能重设DMA的COUNTER  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_DMA_SET_COUNTERT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;__HAL_DMA_ENABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//需要关闭DMA才能重设DMA的COUNTER
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;代码实现-8&#34;&gt;代码实现
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define __HAL_DMA_SET_COUNTERT(__HANDLE__,__COUNTER__)  ((__HANDLE__)-&amp;gt;Instance-&amp;gt;CNDTR = (uint16_t)(__COUNTER__))  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//重新设定计数值  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hdma_usart1_tx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define rxBufferLen 512
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;Init_IdleDMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_ReceiveToIdle_DMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE_IT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdma_usart1_rx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DMA_IT_HT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//关闭DMA的接收过半中断  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;HAL_UARTEx_RxEventCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint16_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_DISABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//需要关闭DMA才能重设DMA的COUNTER  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_SET_COUNTERT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rxBufferLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;memcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rxBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txBuffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;__HAL_DMA_ENABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;huart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hdmarx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//需要关闭DMA才能重设DMA的COUNTER  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;常见问题汇总&#34;&gt;常见问题汇总
&lt;/h2&gt;
&lt;h3 id=&#34;uart传输&#34;&gt;UART传输
&lt;/h3&gt;
&lt;p&gt;![](Pasted image 20240904161021.png)
易错点，发送数据也需要花费时间，如果没有延时，可能造成rxBuffer先清空，再发送&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;外设的速度是远远小于单片机代码的执行速度，核心要等待外设执行完动作&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;stm32f103c8t6-特殊引脚&#34;&gt;STM32F103C8T6 特殊引脚
&lt;/h3&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/weixin_51462579/article/details/130033153&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://blog.csdn.net/weixin_51462579/article/details/130033153&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;字符串拼接&#34;&gt;字符串拼接
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;sprintf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;counter: %d&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;counter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;按键消抖-1&#34;&gt;按键消抖
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E6%8C%89%E9%94%AE%E6%8A%96%E5%8A%A8%E7%9A%84%E5%8E%BB%E9%99%A4.jpg&#34;
	width=&#34;1880&#34;
	height=&#34;1057&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E6%8C%89%E9%94%AE%E6%8A%96%E5%8A%A8%E7%9A%84%E5%8E%BB%E9%99%A4_hu1920332323901543496.jpg 480w, https://NomadJoeviolet.github.io/p/%E5%9F%BA%E4%BA%8Ecubemx%E7%9A%84stm32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E6%8C%89%E9%94%AE%E6%8A%96%E5%8A%A8%E7%9A%84%E5%8E%BB%E9%99%A4_hu618690599907585652.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;177&#34;
		data-flex-basis=&#34;426px&#34;
	
&gt;
此处是检测下降沿，使用的是上拉电平&lt;/p&gt;
&lt;p&gt;检测上升沿，下拉电平
检测下降沿，上拉电平&lt;/p&gt;
&lt;h3 id=&#34;fdcan通信消息队列fifo已满&#34;&gt;FDCAN通信消息队列Fifo已满
&lt;/h3&gt;
&lt;p&gt;硬件速度远远低于单片机执行程序的速度&lt;/p&gt;
&lt;h3 id=&#34;关于cubemx的stm32项目创建&#34;&gt;关于CubeMX的STM32项目创建
&lt;/h3&gt;
&lt;p&gt;在选定创建的文件路径时，一定要保证&lt;strong&gt;路径没有中文和空格&lt;/strong&gt;
尤其注意不要有空格&lt;/p&gt;
&lt;h3 id=&#34;关于stm32cubemx更新&#34;&gt;关于STM32CubeMX更新
&lt;/h3&gt;
&lt;p&gt;在软件内&lt;code&gt;check for updates&lt;/code&gt;无法勾选最新版进行更新&lt;/p&gt;
&lt;p&gt;解决方法：
需要以管理员模式运行&lt;/p&gt;
</description>
        </item>
        <item>
        <title>电控成长指南</title>
        <link>https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/</link>
        <pubDate>Wed, 17 Sep 2025 23:37:07 +0800</pubDate>
        
        <guid>https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/</guid>
        <description>&lt;p&gt;violet
感其生，历其境&lt;/p&gt;
&lt;p&gt;初步入门嵌入式开发后（假定已经会使用Keil和CubeMX进行开发），需要回头补充的基础以及提升，本指南只起到抛砖引玉的作用，对所需知识仅作精简的概述，主要在于帮助构建知识框架&lt;/p&gt;
&lt;h2 id=&#34;step1---keilcubemx工具链使用hal库使用基本外设基本开发常识&#34;&gt;Step1   Keil+CubeMX工具链使用，HAL库使用，基本外设，基本开发常识
&lt;/h2&gt;
&lt;h3 id=&#34;开发常识&#34;&gt;开发常识
&lt;/h3&gt;
&lt;p&gt;该部分内容摘自队内文档部分内容&lt;/p&gt;
&lt;h4 id=&#34;开发环境&#34;&gt;开发环境
&lt;/h4&gt;
&lt;p&gt;开发环境是软件开发过程中使用的软件和硬件的组合。通常情况下包括&lt;strong&gt;代码编辑器、编译器、调试工具和其他工具&lt;/strong&gt;。开发环境帮助程序员编写、测试和调试代码的环境。&lt;/p&gt;
&lt;h4 id=&#34;ide集成开发环境&#34;&gt;IDE集成开发环境
&lt;/h4&gt;
&lt;p&gt;集成开发环境是一种包含&lt;strong&gt;代码编辑器、编译器和调试器的综合性软件应用程序&lt;/strong&gt;。IDE提供了方便编写、测试和调试程序的一体化界面。例如Keil，Clion，RTT Studio，CubeIDE等，本文中主要介绍Keil和Clion&lt;/p&gt;
&lt;h4 id=&#34;代码编辑器&#34;&gt;代码编辑器
&lt;/h4&gt;
&lt;p&gt;代码编辑器是用于编写和修改代码的工具。它提供了基本的文本编辑功能，通常还包括语法高亮、代码格式化和错误检查等特性。比如我们所使用的VScode。一般来讲，对于一个项目，代码编辑器的选择通常是无所谓的&lt;/p&gt;
&lt;h3 id=&#34;关于单片机&#34;&gt;关于单片机
&lt;/h3&gt;
&lt;p&gt;单片机是一种微型计算机&lt;/p&gt;
&lt;p&gt;单片机（Microcontroller Unit，简称MCU）是一种将微处理器、存储器（包括程序存储器和数据存储器）、输入/输出接口和其他必要的功能模块集成在单个芯片上的微型计算机。它通常用于控制应用，可以在没有外部支持芯片的情况下独立运行。&lt;/p&gt;
&lt;p&gt;可以理解为&lt;code&gt;单片机=微处理器+存储器+片上外设&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;微处理器主要负责运算与控制逻辑的执行&lt;/li&gt;
&lt;li&gt;存储器用于存储代码与数据&lt;/li&gt;
&lt;li&gt;外设用于实现单片机的各种功能，例如定时器的定时，输入捕获功能，USART的串口通信功能&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;外设&#34;&gt;外设
&lt;/h3&gt;
&lt;p&gt;单片机外设是指用于扩展单片机功能的辅助电路，包括内部外设和外部外设，能够与单片机协同工作，实现各种控制和处理任务&lt;/p&gt;
&lt;p&gt;例如定时器TIM和USART就是两个常见的单片机的片上外设
定时器可以用来实现定时，PWM调制，输入捕获等复杂功能
USART可以用来实现同步/异步的串口通信&lt;/p&gt;
&lt;h3 id=&#34;关于cubemx&#34;&gt;关于CubeMX
&lt;/h3&gt;
&lt;p&gt;CubeMX本质是代码生成器，&lt;strong&gt;图形化嵌入式开发辅助工具&lt;/strong&gt;，用于快速配置STM32硬件资源并生成初始化代码框架，降低底层开发门槛，通过图形化界面，自动配置好用户所需的外设资源&lt;/p&gt;
&lt;p&gt;CubeMX生成的代码与HAL库强绑定&lt;/p&gt;
&lt;h3 id=&#34;关于hal库&#34;&gt;关于HAL库
&lt;/h3&gt;
&lt;p&gt;HAL库（Hardware Abstraction Layer，硬件抽象层）是ST公司为STM32微控制器设计的&lt;strong&gt;标准化硬件驱动库&lt;/strong&gt;。作为嵌入式开发的关键基础设施，其实质是在硬件寄存器与用户应用之间构建了一个&lt;strong&gt;抽象接口层&lt;/strong&gt;，彻底改变了传统嵌入式开发模式&lt;/p&gt;
&lt;p&gt;用户只需要关注HAL库提供的抽象层，而不用去关注抽象层之下的外设寄存器操作（这类设计思想很值得借鉴）&lt;/p&gt;
&lt;p&gt;HAL库提供统一的接口函数，例如&lt;code&gt;HAL_xxxx_Transmit&lt;/code&gt;发送执行函数，&lt;code&gt;xxxxCallback&lt;/code&gt;回调函数等&lt;/p&gt;
&lt;p&gt;开发范式变为： 应用层-&amp;gt;HAL库的抽象层-&amp;gt;具体硬件平台&lt;/p&gt;
&lt;p&gt;下面讨论HAL库，CMSIS协议，以及两者关系&lt;/p&gt;
&lt;h4 id=&#34;hal库hardware-abstraction-layer-硬件抽象层库&#34;&gt;HAL库（Hardware Abstraction Layer 硬件抽象层库）
&lt;/h4&gt;
&lt;p&gt;HAL 库是 &lt;strong&gt;STMicroelectronics（意法半导体）&lt;/strong&gt; 为自家 &lt;strong&gt;STM32 系列微控制器（MCU）&lt;/strong&gt; 量身打造的底层软件库，是 STM32 生态中核心的开发工具之一，基于 ARM 的 CMSIS 标准构建。&lt;/p&gt;
&lt;h4 id=&#34;cmsiscortex-microcontroller-software-interface-standard&#34;&gt;CMSIS（Cortex Microcontroller Software Interface Standard）
&lt;/h4&gt;
&lt;p&gt;CMSIS 是 &lt;strong&gt;ARM 公司&lt;/strong&gt; 制定的 &lt;strong&gt;行业统一软件接口标准&lt;/strong&gt;（注意：不是具体的软件库，而是 “规范 / 协议”），面向所有基于 ARM Cortex-M 内核（M0/M0+/M3/M4/M7 等）的微控制器，所有主流 MCU 厂商（ST、NXP、Microchip、TI、瑞萨等）均需遵循该标准。&lt;/p&gt;
&lt;h4 id=&#34;hal-库与-cmsis-的关系&#34;&gt;HAL 库与 CMSIS 的关系
&lt;/h4&gt;
&lt;p&gt;层级关系：CMSIS 是 &lt;strong&gt;底层标准&lt;/strong&gt;，HAL 库是 &lt;strong&gt;基于 CMSIS 标准的具体实现&lt;/strong&gt;——HAL 库的内核操作（如中断配置、Systick 定时器、时钟初始化）完全遵循 CMSIS-Core 规范，外设驱动接口也兼容 CMSIS-Driver 模板。&lt;/p&gt;
&lt;p&gt;简单总结：&lt;strong&gt;CMSIS 是 “通用接口规则”，HAL 库是 ST 按规则为 STM32 定制的 “工具包”&lt;/strong&gt;，两者结合既保证了跨平台兼容性，又提升了 STM32 的开发效率。&lt;/p&gt;
&lt;h2 id=&#34;step2---工具链的基础认知构建与工具链换新&#34;&gt;Step2   工具链的基础认知构建与工具链换新
&lt;/h2&gt;
&lt;p&gt;对于整个工具链的理解，需要建立在对单片机（微型计算机）的基本工作方式有一定认知的基础上&lt;/p&gt;
&lt;p&gt;计算机的运行都是基于机器语言，我们编写的C语言程序，最后经过编译得到汇编代码，再经过汇编，得到二进制代码（已经是机器语言，但不可运行），最后经过链接，得到一个能运行于单片机上的可执行程序&lt;/p&gt;
&lt;p&gt;同时，还需要提一下的是，在一种计算机环境中运行的编译程序，能编译出在另外一种环境下运行的代码，这个编译过程就叫交叉编译。简单地说，就是在一个平台上生成另一个平台上的可执行代码，嵌入式开发的程序编译就是典型的交叉编译，用到的编译器用被称作交叉编译器&lt;/p&gt;
&lt;p&gt;目前队内的开发工具链是&lt;code&gt;VScode/Clion&lt;/code&gt;+&lt;code&gt;arm-none-eabi/armclag&lt;/code&gt;+&lt;code&gt;CMake&lt;/code&gt;+&lt;code&gt;Ninja&lt;/code&gt;+&lt;code&gt;Ozone&lt;/code&gt;+&lt;code&gt;clangd/intellisence/Clion_LSP&lt;/code&gt;（编辑器+编译器+项目构建工具+项目构建的执行工具+烧录器+语法服务支持LSP），个人认为还是相当现代化且高度自定义的
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/%E6%96%B0%E5%B7%A5%E5%85%B7%E9%93%BE.png&#34;
	width=&#34;1662&#34;
	height=&#34;1065&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/%E6%96%B0%E5%B7%A5%E5%85%B7%E9%93%BE_hu11427774341996634186.png 480w, https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/%E6%96%B0%E5%B7%A5%E5%85%B7%E9%93%BE_hu4232838292584919944.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;156&#34;
		data-flex-basis=&#34;374px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;下面简单讲解C语言到机器语言的定义以及编译过程&lt;/p&gt;
&lt;h3 id=&#34;从c语言到机器语言&#34;&gt;从C语言到机器语言
&lt;/h3&gt;
&lt;h4 id=&#34;机器语言&#34;&gt;机器语言
&lt;/h4&gt;
&lt;p&gt;计算机（包括单片机）是不能直接识别我们所编写的C语言程序。它只能识别机器语言，而机器语言是用二进制代码表示的&lt;strong&gt;计算机能直接识别和执行的一种机器指指令系统令的集合&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;汇编语言&#34;&gt;汇编语言
&lt;/h4&gt;
&lt;p&gt;汇编语言是一种用于微处理器、微控制器或其他可编程器件的低级语言。 在不同的设备中，汇编语言对应着不同的机器语言指令集。 一种汇编语言专用于某种计算机系统结构，而不像许多高级语言，可以在不同系统平台之间移植。汇编语言的主体是汇编指令，汇编语言是二进制指令的文本形式，与指令是一一对应的关系。比如，有一些架构的汇编指令中的加法指令&lt;code&gt;00000011&lt;/code&gt;写成汇编语言就是 &lt;code&gt;Add&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;通俗的理解，汇编语言与对应计算机的架构相关，x86和arm结构的计算机分别有一套对应的汇编指令，而汇编语言是机器语言的文本化表达，例如 某一汇编指令中&lt;code&gt;00000011&lt;/code&gt;可以简记为&lt;code&gt;Add&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;高级语言ccjava等到机器语言&#34;&gt;高级语言（C&amp;amp;C++&amp;amp;Java等）到机器语言
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;高级语言到汇编语言需要经过&lt;strong&gt;编译&lt;/strong&gt;，例如 .c文件经过编译后，会生成 .s文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;汇编语言到机器语言需要经过&lt;strong&gt;汇编&lt;/strong&gt;，例如 .s文件经过汇编后，会生成 .o文件&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;需要注意的是，高级语言具有迁移性，在不同架构的计算机上高级语言是不变的，但是汇编语言对于不同的架构会有不同的指令，
这就需要我们选择对应的编译器，例如&lt;code&gt;stm32&lt;/code&gt;是&lt;code&gt;arm&lt;/code&gt;架构的芯片，在C编译器的选择上需要 选择将C语言编译为&lt;code&gt;arm&lt;/code&gt;架构汇编语言的编译器，例如&lt;code&gt;armcc&lt;/code&gt;，&lt;code&gt;armclang&lt;/code&gt;，&lt;code&gt;arm-none-eabi&lt;/code&gt;等编译器&lt;/p&gt;
&lt;p&gt;所以在嵌入式开发中，需要根据单片机的架构选择对应的编译器&lt;/p&gt;
&lt;h3 id=&#34;编译原理&#34;&gt;编译原理
&lt;/h3&gt;
&lt;p&gt;C语言编译原理涉及将C语言代码转换为机器语言的过程。这个过程包括预处理、编译、汇编和链接。编译器在这个过程中对源代码进行优化和转换，生成可执行文件，主要包括以下几个阶段：&lt;/p&gt;
&lt;h5 id=&#34;1预处理preprocessing&#34;&gt;1.  预处理（Preprocessing）
&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：处理源代码文件中的预处理指令，如#include和#define
&lt;strong&gt;过程&lt;/strong&gt;：替换宏定义，处理条件编译指令，包含头文件内容
&lt;strong&gt;工具&lt;/strong&gt;：预处理器，如cpp、armclang&lt;/p&gt;
&lt;h5 id=&#34;2编译compilation&#34;&gt;2.编译（Compilation）
&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：将预处理后的源代码转换成汇编语言
&lt;strong&gt;过程&lt;/strong&gt;：进行语法分析和语义分析，生成汇编代码
&lt;strong&gt;工具&lt;/strong&gt;：编译器，如GCC、armclang&lt;/p&gt;
&lt;h5 id=&#34;3汇编assembly&#34;&gt;3.汇编（Assembly）
&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：将汇编语言转换成机器语言，即目标代码（Object Code）
&lt;strong&gt;过程&lt;/strong&gt;：汇编器将汇编指令转换为机器码
&lt;strong&gt;工具&lt;/strong&gt;：汇编器，如as、armasm&lt;/p&gt;
&lt;h5 id=&#34;4链接linking&#34;&gt;4.链接（Linking）
&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：将多个目标代码文件和库文件合并成一个单独的可执行文件&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;过程&lt;/strong&gt;：
解决外部符号引用，如函数和全局变量
合并不同模块中的相同段（如.text，.data）
生成最终的可执行文件或库文件
&lt;strong&gt;工具&lt;/strong&gt;：链接器，如ld、armlink&lt;/p&gt;
&lt;h4 id=&#34;编译器与链接器&#34;&gt;编译器与链接器
&lt;/h4&gt;
&lt;p&gt;在整个编译过程中，编译器和链接器是核心组件，一般的环境配置也主要针对这二者展开：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;编译器（Compiler）&lt;/strong&gt;：负责将源代码转换成汇编代码或直接生成目标代码。编译器的高级优化包括循环优化、常数传播、死码删除等
&lt;strong&gt;链接器（Linker）&lt;/strong&gt;：负责将多个目标代码文件整合为一个可执行文件。链接器处理符号解析、重定位等任务&lt;/p&gt;
&lt;h3 id=&#34;多文件编程&#34;&gt;多文件编程
&lt;/h3&gt;
&lt;p&gt;简单来说就是头文件提供声明（就是给编译器说有某一个函数），源文件里面有函数的具体定义/实现&lt;/p&gt;
&lt;p&gt;多文件编译时会生成多个二进制文件，链接器会实现重定位后生成唯一的可执行文件（也就是最后实现 main.c能使用usart.c里面的函数）&lt;/p&gt;
&lt;h4 id=&#34;核心原理分离式编译与链接&#34;&gt;核心原理：分离式编译与链接
&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;编译链接过程&lt;/strong&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/%E7%94%B5%E6%8E%A7%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97-%E5%A4%9A%E6%96%87%E4%BB%B6%E7%BC%96%E7%A8%8B%E8%BF%87%E7%A8%8B.png&#34;
	width=&#34;2478&#34;
	height=&#34;834&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/%E7%94%B5%E6%8E%A7%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97-%E5%A4%9A%E6%96%87%E4%BB%B6%E7%BC%96%E7%A8%8B%E8%BF%87%E7%A8%8B_hu1549188601157836830.png 480w, https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/%E7%94%B5%E6%8E%A7%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97-%E5%A4%9A%E6%96%87%E4%BB%B6%E7%BC%96%E7%A8%8B%E8%BF%87%E7%A8%8B_hu7353814610565968913.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;297&#34;
		data-flex-basis=&#34;713px&#34;
	
&gt;
&lt;strong&gt;关键步骤&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;预处理阶段&lt;/strong&gt;：处理&lt;code&gt;#include&lt;/code&gt;指令，将头文件内容复制到源文件中&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;编译阶段&lt;/strong&gt;：将每个.c文件独立编译为目标文件(.o)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;链接阶段&lt;/strong&gt;：合并所有目标文件，解析符号引用，生成可执行文件&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;作用域与链接属性&#34;&gt;作用域与链接属性
&lt;/h4&gt;
&lt;h5 id=&#34;1-存储类说明符&#34;&gt;1. 存储类说明符
&lt;/h5&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;关键字&lt;/th&gt;
          &lt;th&gt;文件内作用&lt;/th&gt;
          &lt;th&gt;文件间作用&lt;/th&gt;
          &lt;th&gt;典型用途&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;static&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;私有&lt;/td&gt;
          &lt;td&gt;不可访问&lt;/td&gt;
          &lt;td&gt;内部辅助函数&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;extern&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;声明&lt;/td&gt;
          &lt;td&gt;可访问&lt;/td&gt;
          &lt;td&gt;全局变量声明&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;(默认)&lt;/td&gt;
          &lt;td&gt;定义&lt;/td&gt;
          &lt;td&gt;可访问&lt;/td&gt;
          &lt;td&gt;公共函数&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h5 id=&#34;2-作用域控制示例&#34;&gt;2. 作用域控制示例
&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// module.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;internal_counter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 文件内私有变量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//只有在该文件内的函数才可以访问
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;public_function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;internal_counter&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// header.h
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;global_variable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 声明全局变量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//注意，声明不等于定义
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// main.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;global_variable&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 定义全局变量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;符号解析与重定位&#34;&gt;符号解析与重定位
&lt;/h4&gt;
&lt;h5 id=&#34;链接器核心任务&#34;&gt;链接器核心任务
&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;符号解析&lt;/strong&gt;：将符号引用与符号定义关联&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重定位&lt;/strong&gt;：合并目标文件，调整地址引用&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&#34;符号类型&#34;&gt;符号类型
&lt;/h5&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;符号类型&lt;/th&gt;
          &lt;th&gt;定义位置&lt;/th&gt;
          &lt;th&gt;引用位置&lt;/th&gt;
          &lt;th&gt;链接器处理&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;强符号&lt;/td&gt;
          &lt;td&gt;.text/.data&lt;/td&gt;
          &lt;td&gt;其他文件&lt;/td&gt;
          &lt;td&gt;必须唯一&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;弱符号&lt;/td&gt;
          &lt;td&gt;未初始化全局变量&lt;/td&gt;
          &lt;td&gt;其他文件&lt;/td&gt;
          &lt;td&gt;可覆盖&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;外部引用&lt;/td&gt;
          &lt;td&gt;未定义&lt;/td&gt;
          &lt;td&gt;当前文件&lt;/td&gt;
          &lt;td&gt;需在其它文件找到定义&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h5 id=&#34;符号解析示例&#34;&gt;符号解析示例
&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// module.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//需要#include &amp;#34;helper.h&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;helper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 外部引用（未定义）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;public_func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;helper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// helper.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;helper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 强符号定义
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;cm&#34;&gt;/* 实现 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// main.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;public_func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 外部引用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;public_func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 链接器解析到module.c中的定义
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;链接器符号表处理&#34;&gt;链接器符号表处理
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;扫描所有目标文件，收集符号定义&lt;/li&gt;
&lt;li&gt;构建全局符号表：
&lt;ul&gt;
&lt;li&gt;强符号：记录地址&lt;/li&gt;
&lt;li&gt;弱符号：标记为可选（weak关键字）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;解析引用：
&lt;ul&gt;
&lt;li&gt;找到匹配的强符号&lt;/li&gt;
&lt;li&gt;或使用弱符号（如果存在）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;报告未解析引用错误&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;总结&#34;&gt;总结
&lt;/h3&gt;
&lt;p&gt;在上述内容的基础上，我们可以知道，无论是&lt;code&gt;Clion&lt;/code&gt;还是&lt;code&gt;VScode&lt;/code&gt;，其本质都还是代码编辑器（虽然Clion内置了编译器），配环境实际上配的都还是对应的编译器（现代的编译器包含了编译器，汇编器，链接器等），如&lt;code&gt;arm-none-eabi&lt;/code&gt;的&lt;code&gt;gcc/g++&lt;/code&gt;或者是 &lt;code&gt;arm-clang&lt;/code&gt;和&lt;code&gt;arm-cc&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;step3-cc混合编程cmakemakeninja&#34;&gt;Step3 C&amp;amp;C++混合编程，CMake&amp;amp;Make&amp;amp;Ninja
&lt;/h2&gt;
&lt;h3 id=&#34;cc混合编程&#34;&gt;C&amp;amp;C++混合编程
&lt;/h3&gt;
&lt;p&gt;核心原理 在于C与C++的符号修饰，如何利用&lt;code&gt;extern &amp;quot;C&amp;quot;&lt;/code&gt;命令实现&lt;code&gt;C call C++&lt;/code&gt;以及&lt;code&gt;C++ call C&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【关于C和C++混合编程中编译和链接的问题】https://www.bilibili.com/video/BV1Zm4y1E7nm?vd_source=5a0790755035f26a67935abfbfcdfd5b&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.cnblogs.com/ArsenalfanInECNU/p/18499811&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;extern &amp;ldquo;c&amp;quot;的用法：c与c++的互相调用 - 青山牧云人 - 博客园&lt;/a&gt;
&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/it_is_me_a/article/details/81979537&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;C++&amp;ndash;名字修饰_c++的函数名修饰是在哪个阶段进行的-CSDN博客&lt;/a&gt;
&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/helena1993/article/details/124149052&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;C/C++ 函数签名与名字修饰（符号修饰）-CSDN博客&lt;/a&gt;
&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/m0_46606290/article/details/119973574&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;C/C++中的 extern 和extern“C“关键字的理解和使用（对比两者的异同）_c extern c-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;符号修饰&#34;&gt;符号修饰
&lt;/h4&gt;
&lt;p&gt;在C/C++中，一个程序要运行起来，需要经历以下几个阶段：预处理、编译、汇编、链接。&lt;/p&gt;
&lt;p&gt;名字修饰（Name Mangling）是一种在&lt;code&gt;编译&lt;/code&gt;过程中，将函数、变量的名称重新改编的机制，简单来说就是编译器为了区分各个函数，将函数通过一定算法，重新修饰为一个全局唯一的名称。&lt;/p&gt;
&lt;p&gt;由于C++和C的名字修饰规则不同（&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/helena1993/article/details/124149052&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;不同操作系统下的编译器的名字修饰方式也会不同&lt;/a&gt;），导致C++可以支持函数重载，而C不支持函数重载&lt;/p&gt;
&lt;p&gt;可以简单理解为，c++中支持函数重载，c语言不支持函数重载，这造成了c++和c语言的函数名解析不同（名字修饰/符号修饰）。c语言函数名就是函数名，c++的函数名是函数名+参数组合起来的。&lt;/p&gt;
&lt;h4 id=&#34;c与c符号修饰的实例&#34;&gt;C与C++符号修饰的实例
&lt;/h4&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.cnblogs.com/ArsenalfanInECNU/p/18499811&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;extern &amp;ldquo;c&amp;quot;的用法：c与c++的互相调用 - 青山牧云人 - 博客园&lt;/a&gt;
（直接copy自该博客）&lt;/p&gt;
&lt;p&gt;比如，函数&lt;code&gt;void func(double a)&lt;/code&gt; 在&lt;code&gt;C&lt;/code&gt;和&lt;code&gt;C++&lt;/code&gt;中的编译阶段函数名称会被解析成什么呢？&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;C&lt;/code&gt;语言中，由于没有名称修饰，所以在编译时函数名称仍然是&lt;code&gt;func&lt;/code&gt;，不会因为参数类型或数量而改变。&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;C++&lt;/code&gt;中，由于名称修饰的存在，函数名称在编译阶段会被编译器转换成一个包含函数原型信息的唯一标识符。通常会涉及函数返回类型、参数类型以及参数数量。以&lt;code&gt;GCC(GNU Compiler Collection)&lt;/code&gt;为例，&lt;code&gt;func(double a)&lt;/code&gt;会被转换成&lt;code&gt;_Z4funcd&lt;/code&gt; ，这里：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_Z&lt;/code&gt;：是&lt;code&gt;GCC&lt;/code&gt;用来表示修饰名称的前缀&lt;/li&gt;
&lt;li&gt;&lt;code&gt;4&lt;/code&gt;：表示函数名称&lt;code&gt;func&lt;/code&gt;的的字符数&lt;/li&gt;
&lt;li&gt;&lt;code&gt;d&lt;/code&gt;：是double类型的编码&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，&lt;strong&gt;用c++的方式去寻找c语言的符号是无法寻找到的&lt;/strong&gt;。&lt;code&gt;extern &amp;quot;C&amp;quot;&lt;/code&gt;为何可以做到？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;extern &amp;quot;C&amp;quot;&lt;/code&gt;的作用就是修改了符号表的生成方式，将c++符号的生成方式换成了c的生成方式。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;即c库中生成的符号是c编译器的符号， 因此c语言可以直接链接。而c++程序需要使用&lt;code&gt;extern &amp;quot;C&amp;quot;&lt;/code&gt;让编译器使用c的符号命名方式去进行链接，这样才能找到对应的符号。&lt;/p&gt;
&lt;h4 id=&#34;extern-c&#34;&gt;extern &amp;ldquo;C&amp;rdquo;
&lt;/h4&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/m0_46606290/article/details/119973574&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;C/C++中的 extern 和extern“C“关键字的理解和使用（对比两者的异同）_c extern c-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;看这一篇就够了
看实例&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;cpp调用c，cpp编译时会有C++的符号修饰，导致链接C库的函数找不到，需要用extern &amp;ldquo;C&amp;quot;告诉g++编译器以C语言的风格进行编译&lt;/li&gt;
&lt;li&gt;c调用cpp（不涉及C++的类和成员函数），设计一个C的接口，接口的实现在cpp中，接口函数内部去使用C++的特性&lt;/li&gt;
&lt;li&gt;c中调用c++成员函数，需要一个接口函数&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;cmake这一块&#34;&gt;CMake这一块
&lt;/h3&gt;
&lt;p&gt;CMake是一个C/C++项目构建工具
根据CMakeLists.txt来构建makefile/ninja文件，再根据makefile/ninja文件来编译C和C++文件并生成可执行文件&lt;/p&gt;
&lt;p&gt;只需要理解
在命令行使用g++ 进行多文件编译时，每次输入都需要输入一大堆的文件，非常麻烦
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/CMake%E7%AE%80%E5%8C%96%E7%BC%96%E8%AF%91%E5%91%BD%E4%BB%A4.png&#34;
	width=&#34;1531&#34;
	height=&#34;622&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/CMake%E7%AE%80%E5%8C%96%E7%BC%96%E8%AF%91%E5%91%BD%E4%BB%A4_hu13196005942084954256.png 480w, https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/CMake%E7%AE%80%E5%8C%96%E7%BC%96%E8%AF%91%E5%91%BD%E4%BB%A4_hu12639865504616744492.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;246&#34;
		data-flex-basis=&#34;590px&#34;
	
&gt;
使用CMake+make/ninja进行简化操作即可（个人认为的CMake的一个核心思想（极简化理解））&lt;/p&gt;
&lt;p&gt;层级关系&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;开发者层&lt;/strong&gt;：编写CMakeLists.txt定义构建规则&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成器层&lt;/strong&gt;：CMake解析配置，生成底层构建文件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行器层&lt;/strong&gt;：Make/Ninja执行具体构建命令&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具链层&lt;/strong&gt;：编译器(如gcc)、链接器等实际执行编译&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&#34;cmake&#34;&gt;cmake
&lt;/h5&gt;
&lt;p&gt;cmake是一个生成 .ninja 和 .makefile 的工具。cmake只需要用户通过对源码文件的简单描述（就是CMakeLists.txt文件），就能自动生成一个project的makefile文件或者ninja文件，然后就可以通过ninja或者make进行启动编译了，很多IDE都在用cmake作为项目管理工具。&lt;/p&gt;
&lt;h5 id=&#34;make与ninja&#34;&gt;make与ninja
&lt;/h5&gt;
&lt;p&gt;make功能强大，可以给人看，ninja启动速度快，项目构建速度快，但不是给人看的&lt;br&gt;
可以认为两者同级。&lt;/p&gt;
&lt;h2 id=&#34;step4-c提升设计模式&#34;&gt;Step4 C++提升&amp;amp;设计模式
&lt;/h2&gt;
&lt;p&gt;这一节也是本人极其欠缺的，目前正在恶补&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C++&lt;/code&gt;的提升推荐&lt;a class=&#34;link&#34; href=&#34;https://nomadjoeviolet.github.io/p/cc-%E7%B3%BB%E7%BB%9F%E5%AD%A6%E4%B9%A0/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;C&amp;amp;C++ 系统学习&lt;/a&gt;（自荐这一块儿）&lt;/p&gt;
&lt;p&gt;设计模式推荐：暂无&lt;/p&gt;
&lt;h3 id=&#34;c提升&#34;&gt;C++提升
&lt;/h3&gt;
&lt;h4 id=&#34;内存对齐&#34;&gt;内存对齐
&lt;/h4&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/140063999&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;一文轻松理解内存对齐 - 知乎&lt;/a&gt;
这里仅以结构体的内存对齐为例，不提供具体例子，具体例子详见上面的博客&lt;/p&gt;
&lt;h5 id=&#34;结构体struct对齐&#34;&gt; &lt;strong&gt;结构体（struct）对齐&lt;/strong&gt;
&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;规则 1&lt;/strong&gt;：成员地址 = &lt;code&gt;min(自身对齐值, 有效对齐值)&lt;/code&gt; 的倍数&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;规则 2&lt;/strong&gt;：结构体总大小 = 最大成员对齐值的整数倍&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;规则 3&lt;/strong&gt;：成员排列顺序影响最终大小&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#pragma pack(1)&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//设置默认对齐数为1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;S1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;c1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;c2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#pragma pack()&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//取消设置的默认对齐数，还原为默认
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;c1&#34;&gt;//输出的结果是什么？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;nf&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%d&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;S1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#pragma pack(push, 1)&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//设置默认对齐数为1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MyStruct&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#pragma pack(pop)&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//取消设置的默认对齐数，还原为默认
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MyStruct&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;__attribute__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;packed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;深拷贝与浅拷贝&#34;&gt;深拷贝与浅拷贝
&lt;/h4&gt;
&lt;h5 id=&#34;1-浅拷贝shallow-copy&#34;&gt;1. 浅拷贝（Shallow Copy）
&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;原理&lt;/strong&gt;：仅复制对象的成员值（包括指针的值），&lt;strong&gt;不复制指针指向的实际资源&lt;/strong&gt;。&lt;br&gt;
&lt;strong&gt;结果&lt;/strong&gt;：原对象和拷贝对象的指针成员指向&lt;strong&gt;同一块内存地址&lt;/strong&gt;。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Shallow&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Shallow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 分配堆内存
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 编译器生成的默认拷贝构造函数（浅拷贝）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;Shallow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Shallow&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;other&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;other&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;~&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Shallow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;delete&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 使用示例
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Shallow&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;obj1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Shallow&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;obj2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;obj1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 浅拷贝：obj2.data 指向 obj1.data 的内存
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;obj1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;      &lt;span class=&#34;c1&#34;&gt;// 修改 obj1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;obj2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;// 输出 20（obj2 也被修改）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// main结束时：obj2 和 obj1 会先后调用析构函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 导致同一内存被 delete 两次 → 程序崩溃！
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h6 id=&#34;浅拷贝的核心问题&#34;&gt;浅拷贝的核心问题：
&lt;/h6&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;悬空指针&lt;/strong&gt;：一个对象释放资源后，另一个对象的指针失效&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重复释放&lt;/strong&gt;：多个对象尝试释放同一块内存 → &lt;strong&gt;崩溃&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据篡改&lt;/strong&gt;：通过一个对象修改数据会影响其他对象&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h5 id=&#34;2-深拷贝deep-copy&#34;&gt;2. 深拷贝（Deep Copy）
&lt;/h5&gt;
&lt;p&gt;主要用于拷贝构造函数，赋值运算符
&lt;strong&gt;原理&lt;/strong&gt;：不仅复制对象成员，还&lt;strong&gt;复制指针指向的资源&lt;/strong&gt;。&lt;br&gt;
&lt;strong&gt;结果&lt;/strong&gt;：原对象和拷贝对象拥有&lt;strong&gt;完全独立的资源副本&lt;/strong&gt;。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Deep&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Deep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 自定义拷贝构造函数（深拷贝）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;Deep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Deep&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;other&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;other&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 关键：分配新内存并复制值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 深拷贝赋值运算符
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;Deep&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;operator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Deep&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;other&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;other&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 防止自赋值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            &lt;span class=&#34;k&#34;&gt;delete&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;              &lt;span class=&#34;c1&#34;&gt;// 释放原有资源
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;other&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 创建新副本
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;~&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Deep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;delete&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 使用示例
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Deep&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;obj1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Deep&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;obj2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;obj1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 深拷贝：obj2 拥有独立的内存副本
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;obj1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;// 修改 obj1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;obj2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 输出 10（obj2 不受影响）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 析构时各自释放独立内存 → 安全
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h6 id=&#34;深拷贝的核心优势&#34;&gt;深拷贝的核心优势：
&lt;/h6&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;资源独立&lt;/strong&gt;：每个对象拥有自己的资源副本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全析构&lt;/strong&gt;：不会发生重复释放&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据隔离&lt;/strong&gt;：修改一个对象不影响其他对象&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;构造函数拷贝构造函数赋值运算符&#34;&gt;构造函数&amp;amp;拷贝构造函数&amp;amp;赋值运算符
&lt;/h4&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://mp.weixin.qq.com/s/uk12AxukYzxpROlw_bqgzA&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;大疆C++一面：C++什么时候生成默认拷贝构造函数？&lt;/a&gt;&lt;/p&gt;
&lt;h5 id=&#34;1构造函数&#34;&gt;1.构造函数
&lt;/h5&gt;
&lt;p&gt;用于初始化对象的特殊成员函数，与类同名，无返回值&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可重载，支持默认参数&lt;/li&gt;
&lt;li&gt;若未显式定义，编译器生成默认构造函数&lt;/li&gt;
&lt;li&gt;对象创建时自动调用&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;```&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cpp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Point&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 1. 默认构造函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;Point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 2. 带参数构造函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;Point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x_val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y_val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 使用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Point&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;           &lt;span class=&#34;c1&#34;&gt;// 调用默认构造函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Point&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;p2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;     &lt;span class=&#34;c1&#34;&gt;// 调用带参数构造函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h5 id=&#34;2拷贝构造函数&#34;&gt;2.拷贝构造函数
&lt;/h5&gt;
&lt;p&gt;用已有对象初始化新对象时调用的特殊构造函数，注意与赋值运算符区分&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;参数为同类对象的 const 引用&lt;/li&gt;
&lt;li&gt;若未显式定义，编译器生成默认拷贝构造函数（浅拷贝）&lt;/li&gt;
&lt;li&gt;涉及动态内存时必须显式定义（深拷贝）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 普通构造函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;strcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 拷贝构造函数（深拷贝）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;other&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	    &lt;span class=&#34;c1&#34;&gt;//不需要提前处理data，这是在构造是调用的
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;other&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;strcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;other&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 禁用拷贝构造函数（C++11）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;// String(const String&amp;amp;) = delete;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;~&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;delete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 使用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;s1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;s2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 调用拷贝构造函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;需要注意的是，不用再拷贝构造函数中先判断是否删除&lt;code&gt;data&lt;/code&gt;的动态内存，因为拷贝构造函数本质还是一个构造函数，初始化时调用&lt;/p&gt;
&lt;h5 id=&#34;3赋值运算符&#34;&gt;3.赋值运算符
&lt;/h5&gt;
&lt;p&gt;当类中包含指针或需要深拷贝的数据成员时，使用默认的赋值运算符可能会导致问题，如内存泄漏或重复释放内存。因此，在这些情况下，需要显式地重载赋值运算符。&lt;/p&gt;
&lt;p&gt;注意赋值运算符在内存管理上的细节&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;避免自赋值&lt;/li&gt;
&lt;li&gt;赋值前先回收，避免内存泄漏&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;namespace&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ClassA&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;ClassA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;ClassA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pszInputStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pszInputStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;n&#34;&gt;strncpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pszInputStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;strlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pszInputStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;virtual&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;~&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ClassA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;k&#34;&gt;delete&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;c1&#34;&gt;// 赋值运算符重载函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;	&lt;span class=&#34;n&#34;&gt;ClassA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;operator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ClassA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;c1&#34;&gt;// 避免自赋值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;		&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;c1&#34;&gt;// 避免内存泄露
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;			&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;				&lt;span class=&#34;k&#34;&gt;delete&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;				&lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;n&#34;&gt;strncpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;strlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;ClassA&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;obj1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;liitdar&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;ClassA&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;obj2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;obj2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;obj1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;obj2.pszTestStr is: &amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;obj2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pszTestStr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;endl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;模板函数模板类模板&#34;&gt;模板(函数模板&amp;amp;类模板)
&lt;/h4&gt;
&lt;p&gt;函数模板生成的实例化成为模板函数，类模板和模板类的定义同理&lt;/p&gt;
&lt;h5 id=&#34;函数模板&#34;&gt;函数模板
&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;定义&lt;/strong&gt;：通用函数定义，支持多种数据类型，编译器根据实际类型（隐式实例化）或者显式实例化生成具体函数
&lt;strong&gt;特点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用 template 关键字声明&lt;/li&gt;
&lt;li&gt;可显式或隐式实例化&lt;/li&gt;
&lt;li&gt;支持函数重载和特化
模板的定义（实现），还是模板的全特化，都建议放在头文件&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 1. 基本函数模板
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;typename&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 2. 函数模板特化（针对特定类型）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;strcmp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 使用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;                &lt;span class=&#34;c1&#34;&gt;// 隐式实例化int版本
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;apple&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;banana&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 调用特化版本
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h5 id=&#34;类模板&#34;&gt;类模板
&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;定义&lt;/strong&gt;：通用类定义，成员变量和函数可使用模板参数类型。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;特点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;类内成员函数可在&lt;strong&gt;类内定义（默认内联）&lt;/strong&gt; 或类外定义&lt;/li&gt;
&lt;li&gt;支持全特化和部分特化&lt;/li&gt;
&lt;li&gt;实例化时需指定具体类型&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 1. 基本类模板
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;typename&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Array&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;operator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[](&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;getSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 2. 类模板特化（针对bool类型优化）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 位压缩存储
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 使用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;intArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;        &lt;span class=&#34;c1&#34;&gt;// 实例化int类型数组
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;boolArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;     &lt;span class=&#34;c1&#34;&gt;// 使用特化版本
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;现代c相关待补充&#34;&gt;现代C++相关（待补充）
&lt;/h4&gt;
&lt;p&gt;自推导，lambda表达式，智能指针，RAII与RTTI的概念&lt;/p&gt;
&lt;h3 id=&#34;设计模式&#34;&gt;设计模式
&lt;/h3&gt;
&lt;p&gt;To be continued&lt;/p&gt;
&lt;h2 id=&#34;step5-arm-cortex-m学习启动文件与链接器脚本&#34;&gt;Step5 arm-cortex-M学习&amp;amp;启动文件与链接器脚本
&lt;/h2&gt;
&lt;p&gt;在对上面的抽象层级有一定了解后，还需要将上述偏软件的抽象层与具体的硬件相连接，建立软硬结合的认知需要有一定微机原理的知识&lt;/p&gt;
&lt;p&gt;自荐一下笔者的博客
&lt;a class=&#34;link&#34; href=&#34;https://nomadjoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;从CPU架构到操作系统实现&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;cortex-m&#34;&gt;cortex-M
&lt;/h3&gt;
&lt;h4 id=&#34;架构特性&#34;&gt;架构特性
&lt;/h4&gt;
&lt;p&gt;Cortex-M 系列作为微控制器内核，采用&lt;strong&gt;哈佛架构&lt;/strong&gt;（指令与数据独立存储但共享内存空间），具备低功耗、高性能、中断易用性强、代码密度高等优势，支持嵌入式操作系统运行。其内核演变包含 Cortex-M0/M3/M4 等多个型号，其中 M3/M4 集成 3 级流水线（取指 - 译码 - 执行），M4F 额外支持浮点运算单元&lt;/p&gt;
&lt;p&gt;核心组件包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NVIC（嵌套向量中断控制器）&lt;/strong&gt;：管理中断响应，支持多级中断优先级。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MPU（内存保护单元）&lt;/strong&gt;：实现内存访问权限控制，保障系统安全。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;调试接口&lt;/strong&gt;：支持 JTAG 或 Serial Wire 调试，搭配嵌入式跟踪模块（ETM）实现代码跟踪。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;指令集&lt;/strong&gt;：主要支持 Thumb/Thumb2 指令集（16 位 + 32 位混合），兼顾代码密度与执行效率，属于 RISC 架构（精简指令系统），每条指令仅完成单一操作，硬件实现简单高效。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;内存分布规则&#34;&gt;内存分布规则
&lt;/h4&gt;
&lt;p&gt;重点看Flash和RAM，以及对应的段分配规则&lt;/p&gt;
&lt;p&gt;Cortex-M 芯片内存分为 FLASH和 RAM两大区域，具体分布由硬件特性和链接脚本共同定义，以 STM32F103C8Tx（64K FLASH、20K RAM）为例：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;内存类型&lt;/th&gt;
          &lt;th&gt;起始地址&lt;/th&gt;
          &lt;th&gt;大小&lt;/th&gt;
          &lt;th&gt;权限&lt;/th&gt;
          &lt;th&gt;存储内容&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;FLASH&lt;/td&gt;
          &lt;td&gt;0x8000000&lt;/td&gt;
          &lt;td&gt;64K&lt;/td&gt;
          &lt;td&gt;可读可执行&lt;/td&gt;
          &lt;td&gt;中断向量表、.text 代码段、.rodata 只读常量段&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;RAM&lt;/td&gt;
          &lt;td&gt;0x20000000&lt;/td&gt;
          &lt;td&gt;20K&lt;/td&gt;
          &lt;td&gt;可读可写&lt;/td&gt;
          &lt;td&gt;.data 初始化数据段、.bss 未初始化数据段、堆、栈&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;内存段特性：&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;.isr_vector&lt;/strong&gt;：位于 FLASH 起始地址，存储栈顶地址和中断 / 异常处理函数地址，是复位后内核首个访问的区域。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.text&lt;/strong&gt;：存放可执行代码（函数实现），包括用户代码和启动文件逻辑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.rodata&lt;/strong&gt;：存储只读常量（如 const 变量、字符串字面量），节省 RAM 空间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.data&lt;/strong&gt;：存放已初始化的全局 / 静态变量，编译时初始值存于 FLASH，运行时复制到 RAM。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.bss&lt;/strong&gt;：存放未初始化的全局 / 静态变量，运行时由启动文件清零，无需占用 FLASH 空间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;堆 / 栈&lt;/strong&gt;：堆从低地址向上生长（供 malloc 使用），栈从高地址向下生长（供函数调用、局部变量使用），由链接脚本预留空间。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Flash 区：64 KiB，地址范围为 &lt;code&gt;[0x0800_0000, 0x0801_0000)&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;表中的结束地址均为区间上界，不包含在对应段内；各段之间可能因对齐要求产生填充。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;输出段或区域&lt;/th&gt;
          &lt;th&gt;起始地址&lt;/th&gt;
          &lt;th&gt;结束地址（不含）&lt;/th&gt;
          &lt;th&gt;内容&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.isr_vector&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;0x0800_0000&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ADDR(.isr_vector) + SIZEOF(.isr_vector)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;中断向量表&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.text&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;前一段结束后按 4 字节对齐&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_etext&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;程序代码以及 &lt;code&gt;.init&lt;/code&gt;、&lt;code&gt;.fini&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.rodata&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;前一段结束后按 4 字节对齐&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ADDR(.rodata) + SIZEOF(.rodata)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;只读常量和字符串&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.ARM.extab&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;前一段结束后按 4 字节对齐&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ADDR(.ARM.extab) + SIZEOF(.ARM.extab)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;ARM 栈展开信息&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.ARM&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__exidx_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__exidx_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;包含 &lt;code&gt;.ARM.exidx*&lt;/code&gt; 的栈展开索引&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.preinit_array&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__preinit_array_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__preinit_array_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;在普通初始化函数之前执行的预初始化函数数组&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.init_array&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__init_array_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__init_array_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;初始化函数数组，包含 C++ 全局对象和文件作用域静态对象的构造函数入口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.fini_array&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__fini_array_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__fini_array_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;结束函数数组，包含 C++ 全局对象和文件作用域静态对象的析构函数调用入口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.data&lt;/code&gt; 初值镜像（LMA）&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sidata = LOADADDR(.data)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sidata + SIZEOF(.data)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;已初始化变量及 &lt;code&gt;.RamFunc&lt;/code&gt; 的加载镜像，复位后复制到 RAM&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;.init_array&lt;/code&gt; 在 &lt;code&gt;main&lt;/code&gt; 执行前参与 C++ 对象构造；&lt;code&gt;.fini_array&lt;/code&gt; 在程序正常退出阶段参与对象析构。裸机程序通常不会从 &lt;code&gt;main&lt;/code&gt; 返回，其析构流程是否执行取决于运行库和退出路径。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RAM 区：20 KiB，地址范围为 &lt;code&gt;[0x2000_0000, 0x2000_5000)&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;0x2000_5000&lt;/code&gt; 位于 RAM 最后一个有效地址之后，也是该链接脚本中 &lt;code&gt;_estack&lt;/code&gt; 的初始值。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;项目&lt;/th&gt;
          &lt;th&gt;地址或范围&lt;/th&gt;
          &lt;th&gt;内容与作用&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.data&lt;/code&gt;（VMA）&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sdata&lt;/code&gt; 到 &lt;code&gt;_edata&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;已初始化的全局变量、静态变量及在 RAM 中运行的 &lt;code&gt;.RamFunc&lt;/code&gt;；复位时从 Flash 的 &lt;code&gt;_sidata&lt;/code&gt; 复制&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.bss&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sbss&lt;/code&gt; 到 &lt;code&gt;_ebss&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;未初始化或初始化为零的全局变量和静态变量；复位时由启动代码清零&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;.bss&lt;/code&gt; 结束后按 8 字节对齐的位置&lt;/td&gt;
          &lt;td&gt;静态分配区域的结束标记，常作为 C 运行库堆的起点&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;._user_heap_stack&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;从 &lt;code&gt;_end&lt;/code&gt; 开始，增加 &lt;code&gt;_Min_Heap_Size&lt;/code&gt; 和 &lt;code&gt;_Min_Stack_Size&lt;/code&gt; 后按 8 字节对齐&lt;/td&gt;
          &lt;td&gt;用于链接期容量检查，不表示运行时堆和栈的固定分界&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;C 运行库堆&lt;/td&gt;
          &lt;td&gt;通常从 &lt;code&gt;_end&lt;/code&gt; 向高地址增长&lt;/td&gt;
          &lt;td&gt;供 &lt;code&gt;malloc&lt;/code&gt;、&lt;code&gt;free&lt;/code&gt; 等接口使用，实际边界由运行库实现决定&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;主栈&lt;/td&gt;
          &lt;td&gt;从 &lt;code&gt;_estack = 0x2000_5000&lt;/code&gt; 向低地址增长&lt;/td&gt;
          &lt;td&gt;MSP 的初始位置，用于函数调用、局部变量和中断现场保存&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;堆栈间可用空间&lt;/td&gt;
          &lt;td&gt;当前堆末端与当前栈指针之间&lt;/td&gt;
          &lt;td&gt;大小随程序运行动态变化；堆和栈相遇时会发生内存冲突&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;_Min_Heap_Size&lt;/code&gt; 和 &lt;code&gt;_Min_Stack_Size&lt;/code&gt; 只用于验证最小容量能否装入 RAM，并不会在运行时建立固定的堆栈边界。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-RAM%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83.png&#34;
	width=&#34;1269&#34;
	height=&#34;674&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-RAM%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83_hu13448359514406145975.png 480w, https://NomadJoeviolet.github.io/p/%E7%94%B5%E6%8E%A7%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-RAM%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83_hu250755568266859443.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;188&#34;
		data-flex-basis=&#34;451px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;启动文件与启动原理&#34;&gt;启动文件与启动原理
&lt;/h3&gt;
&lt;h4 id=&#34;启动原理&#34;&gt;启动原理
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;硬件复位&lt;/strong&gt;：内核读取 FLASH 起始地址的中断向量表，初始化 MSP（栈顶地址），将 PC 指向&lt;code&gt;Reset_Handler&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行 Reset_Handler&lt;/strong&gt;：完成时钟配置、内存段初始化（.data 复制、.bss 清零）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;进入用户代码&lt;/strong&gt;：跳转至&lt;code&gt;main&lt;/code&gt;函数，启动流程结束，正式运行应用逻辑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中断响应&lt;/strong&gt;：运行中触发中断时，内核从向量表查找对应处理函数地址，执行后返回断点。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;启动模式&#34;&gt;启动模式
&lt;/h4&gt;
&lt;p&gt;STM32F103 支持 3 种启动模式，由 BOOT0 和 BOOT1 引脚电平决定：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;BOOT0=0&lt;/strong&gt;：主 FLASH 启动（默认模式），从用户代码区启动。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BOOT0=1、BOOT1=0&lt;/strong&gt;：系统内存启动，从芯片出厂固化的 Bootloader 启动。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BOOT0=1、BOOT1=1&lt;/strong&gt;：嵌入式 SRAM 启动，从 RAM 加载代码（用于调试）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;启动文件&#34;&gt;启动文件
&lt;/h4&gt;
&lt;p&gt;启动文件（如&lt;code&gt;startup_stm32f103xb.s&lt;/code&gt;）是汇编语言编写的底层程序，作为 &amp;ldquo;硬件到软件的桥梁&amp;rdquo;，负责衔接硬件复位与用户&lt;code&gt;main&lt;/code&gt;函数，核心功能包括硬件初始化、内存初始化、中断系统准备和引导用户代码&lt;/p&gt;
&lt;h4 id=&#34;启动文件结构拆解&#34;&gt;启动文件结构拆解
&lt;/h4&gt;
&lt;h5 id=&#34;1汇编环境配置&#34;&gt;（1）汇编环境配置
&lt;/h5&gt;
&lt;p&gt;指定处理器架构、指令集和浮点模式，确保汇编代码与硬件兼容，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;.syntax&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;unified&lt;/span&gt;          &lt;span class=&#34;c1&#34;&gt;; 兼容ARM与Thumb指令集
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.cpu&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;cortex-m3&lt;/span&gt;           &lt;span class=&#34;c1&#34;&gt;; 目标内核为Cortex-M3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.fpu&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;softvfp&lt;/span&gt;             &lt;span class=&#34;c1&#34;&gt;; 软件模拟浮点运算（无硬件FPU）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.thumb&lt;/span&gt;                   &lt;span class=&#34;c1&#34;&gt;; 启用Thumb指令集
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h5 id=&#34;2关键符号声明&#34;&gt;（2）关键符号声明
&lt;/h5&gt;
&lt;p&gt;引用链接器脚本定义的内存地址符号，建立启动文件与内存布局的关联，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_sidata&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; .data段在FLASH的加载地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_sdata&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;; .data段在RAM的运行起始地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_edata&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;; .data段在RAM的运行结束地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_sbss&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;; .bss段在RAM的起始地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_ebss&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;; .bss段在RAM的结束地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h5 id=&#34;3复位处理函数reset_handler&#34;&gt;（3）复位处理函数（Reset_Handler）
&lt;/h5&gt;
&lt;p&gt;复位后执行的核心逻辑，是启动流程的入口，分为 5 个关键步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;系统时钟初始化&lt;/strong&gt;：调用&lt;code&gt;SystemInit&lt;/code&gt;函数配置 HSE/PLL，将时钟从 8MHz HSI 提升至 72MHz&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.data 段复制&lt;/strong&gt;：从 FLASH 的&lt;code&gt;_sidata&lt;/code&gt;地址复制初始值到 RAM 的&lt;code&gt;_sdata&lt;/code&gt;至&lt;code&gt;_edata&lt;/code&gt;区域&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.bss 段清零&lt;/strong&gt;：将 RAM 中&lt;code&gt;_sbss&lt;/code&gt;至&lt;code&gt;_ebss&lt;/code&gt;区域全部置 0，符合 C 语言标准&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C++ 静态构造函数初始化&lt;/strong&gt;：调用&lt;code&gt;__libc_init_array&lt;/code&gt;，执行全局对象构造（兼容 C++ 项目）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跳转至 main 函数&lt;/strong&gt;：完成底层初始化后，将程序控制权交给用户代码&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&#34;4中断向量表g_pfnvectors&#34;&gt;（4）中断向量表（g_pfnVectors）
&lt;/h5&gt;
&lt;p&gt;存储所有异常 / 中断的处理函数地址，位于 FLASH 起始地址，核心特性包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第 0 个元素为栈顶地址（&lt;code&gt;_estack&lt;/code&gt;），用于初始化主栈指针（MSP）&lt;/li&gt;
&lt;li&gt;第 1 个元素为&lt;code&gt;Reset_Handler&lt;/code&gt;地址，是复位后程序计数器（PC）的初始指向&lt;/li&gt;
&lt;li&gt;向量表顺序隐含中断优先级，靠前元素对应优先级更高（如硬 fault 优先级高于 SysTick）&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;5默认中断处理函数default_handler&#34;&gt;（5）默认中断处理函数（Default_Handler）
&lt;/h5&gt;
&lt;p&gt;为未自定义的中断提供 &amp;ldquo;兜底&amp;rdquo; 逻辑，通过无限循环防止程序跑飞，同时支持弱别名机制（&lt;code&gt;.weak&lt;/code&gt;），允许用户在 C 代码中重定义中断函数覆盖默认逻辑&lt;/p&gt;
&lt;h3 id=&#34;链接器脚本&#34;&gt;链接器脚本
&lt;/h3&gt;
&lt;p&gt;链接脚本（.ld）是链接器的配置文件，本质是告知链接器芯片内存布局、代码 / 数据的段分配规则、全局符号定义和内存合法性检查，是生成可执行文件（.elf/.hex）的关键，没有它链接器无法确定 &amp;ldquo;代码放哪里、变量放哪里&amp;rdquo;&lt;/p&gt;
&lt;h4 id=&#34;1入口点与栈顶定义&#34;&gt;（1）入口点与栈顶定义
&lt;/h4&gt;
&lt;p&gt;指定程序入口和栈堆大小，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ENTRY(Reset_Handler)        ; 程序入口为Reset_Handler
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;_estack = ORIGIN(RAM) + LENGTH(RAM); 栈顶地址=RAM起始+RAM大小
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;_Min_Heap_Size = 0x200;     最小堆大小（512字节）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;_Min_Stack_Size = 0xF00;    最小栈大小（3840字节）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;2内存区域定义memory-块&#34;&gt;（2）内存区域定义（MEMORY 块）
&lt;/h4&gt;
&lt;p&gt;描述 FLASH 和 RAM 的物理属性，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MEMORY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K  ; RAM：可读可写可执行
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K  ; FLASH：可读可执行
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;3段分配规则sections-块&#34;&gt;（3）段分配规则（SECTIONS 块）
&lt;/h4&gt;
&lt;p&gt;定义编译生成的段与物理内存的映射关系，核心段包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;.isr_vector&lt;/strong&gt;：分配到 FLASH 起始地址，用&lt;code&gt;KEEP&lt;/code&gt;关键字防止被优化删除。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.text&lt;/strong&gt;：存放代码段，定义&lt;code&gt;_etext&lt;/code&gt;标记结束地址。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.rodata&lt;/strong&gt;：存放只读常量，分配到 FLASH。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.data&lt;/strong&gt;：运行地址在 RAM，加载地址在 FLASH，定义&lt;code&gt;_sidata&lt;/code&gt;（加载地址）、&lt;code&gt;_sdata&lt;/code&gt;（运行起始）、&lt;code&gt;_edata&lt;/code&gt;（运行结束）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.bss&lt;/strong&gt;：分配到 RAM，定义&lt;code&gt;_sbss&lt;/code&gt;（起始）、&lt;code&gt;_ebss&lt;/code&gt;（结束）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;._user_heap_stack&lt;/strong&gt;：预留堆和栈空间，检查 RAM 容量是否充足。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;/DISCARD/&lt;/strong&gt;：丢弃无用段（如标准库冗余代码），减小文件大小。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;链接脚本与启动文件的协同关系&#34;&gt;链接脚本与启动文件的协同关系
&lt;/h3&gt;
&lt;p&gt;启动文件与链接脚本通过全局符号和段分配紧密耦合，二者协作关系如下：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;协作维度&lt;/th&gt;
          &lt;th&gt;启动文件角色&lt;/th&gt;
          &lt;th&gt;链接脚本角色&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;内存地址提供&lt;/td&gt;
          &lt;td&gt;引用&lt;code&gt;_sdata&lt;/code&gt;、&lt;code&gt;_ebss&lt;/code&gt;等符号&lt;/td&gt;
          &lt;td&gt;计算并定义内存地址符号&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;段分配依据&lt;/td&gt;
          &lt;td&gt;将代码 / 数据放入指定段（如.text）&lt;/td&gt;
          &lt;td&gt;规定段的存储位置（如 FLASH/RAM）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;程序入口指定&lt;/td&gt;
          &lt;td&gt;实现&lt;code&gt;Reset_Handler&lt;/code&gt;函数&lt;/td&gt;
          &lt;td&gt;通过&lt;code&gt;ENTRY&lt;/code&gt;指定入口为&lt;code&gt;Reset_Handler&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;内存合法性检查&lt;/td&gt;
          &lt;td&gt;依赖符号确保内存访问不越界&lt;/td&gt;
          &lt;td&gt;检查堆 / 栈 / 数据段总大小是否超过 RAM 容量&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;架构→内存→链接脚本&lt;/strong&gt;：Cortex-M 的哈佛架构决定内存分为 FLASH 和 RAM，链接脚本根据硬件内存参数（起始地址、大小）定义存储规则。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;链接脚本→启动文件&lt;/strong&gt;：链接脚本提供内存地址符号（如&lt;code&gt;_sdata&lt;/code&gt;），启动文件依赖这些符号完成.data 复制、.bss 清零等初始化操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;启动文件→架构&lt;/strong&gt;：启动文件根据 Cortex-M 内核特性（如向量表位置、栈初始化要求）实现底层逻辑，最终引导程序进入用户代码。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;待续&#34;&gt;待续
&lt;/h2&gt;
</description>
        </item>
        <item>
        <title>从CPU架构到操作系统实现</title>
        <link>https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/</link>
        <pubDate>Thu, 04 Sep 2025 00:36:07 +0800</pubDate>
        
        <guid>https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/</guid>
        <description>&lt;p&gt;跟着下面的视频，系统梳理复习过往的嵌入式知识，同时也算是 电控成长指南 的一个 部分 实现，能有效且快速的建立一个嵌入式系统和工具链的整体认知&lt;/p&gt;
&lt;p&gt;&lt;code&gt;【《从CPU架构到操作系统实现》系列课程 - Git 开源】https://www.bilibili.com/video/BV1ksNCzXEny?vd_source=5a0790755035f26a67935abfbfcdfd5b&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;视频中详细且硬核的实例不会出现在此笔记中&lt;/p&gt;
&lt;h2 id=&#34;概述&#34;&gt;概述
&lt;/h2&gt;
&lt;h3 id=&#34;关于arm架构&#34;&gt;关于ARM架构
&lt;/h3&gt;
&lt;p&gt;目前&lt;code&gt;arm&lt;/code&gt;内核主要演变分为&lt;code&gt;Cortex-X&lt;/code&gt;，&lt;code&gt;Cortex-A&lt;/code&gt;，&lt;code&gt;Cortex-R&lt;/code&gt;，&lt;code&gt;Cortex-M&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Cortex-A&lt;/code&gt;：应用处理器，设计用来处理复杂应用（例如高端嵌入操作系统&lt;code&gt;Linux&lt;/code&gt;，&lt;code&gt;iOS&lt;/code&gt;，&lt;code&gt;Android&lt;/code&gt;，&lt;code&gt;Windows&lt;/code&gt;），对标PC和手机处理器的性能&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Cortex-X&lt;/code&gt;：比&lt;code&gt;Cortex-M&lt;/code&gt;更高的性能&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Cortex-R&lt;/code&gt;：&lt;code&gt;Real-time&lt;/code&gt;，主要用于实时系统&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Cortex-M&lt;/code&gt;：&lt;code&gt;Microcontrol&lt;/code&gt;，微处理器&lt;/p&gt;
&lt;h4 id=&#34;cortex-m优点&#34;&gt;Cortex-M优点
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;低功耗&lt;/li&gt;
&lt;li&gt;高性能&lt;/li&gt;
&lt;li&gt;中断易用&lt;/li&gt;
&lt;li&gt;代码密度高（原因在于指令集）&lt;/li&gt;
&lt;li&gt;可调式&lt;/li&gt;
&lt;li&gt;支持操作系统
哈佛架构，指令与数据在同一内存
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-Cortex-M%E7%9A%84%E5%86%85%E6%A0%B8%E6%A1%86%E5%9B%BE.png&#34;
	width=&#34;790&#34;
	height=&#34;457&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-Cortex-M%E7%9A%84%E5%86%85%E6%A0%B8%E6%A1%86%E5%9B%BE_hu2536946228529719192.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-Cortex-M%E7%9A%84%E5%86%85%E6%A0%B8%E6%A1%86%E5%9B%BE_hu15969040657550120430.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;172&#34;
		data-flex-basis=&#34;414px&#34;
	
&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;指令集&#34;&gt;指令集
&lt;/h3&gt;
&lt;p&gt;多套指令集用于处理不同的场景&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-ARM%E6%8C%87%E4%BB%A4%E9%9B%86%E6%BC%94%E5%8F%98.png&#34;
	width=&#34;542&#34;
	height=&#34;294&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-ARM%E6%8C%87%E4%BB%A4%E9%9B%86%E6%BC%94%E5%8F%98_hu6983626606541064714.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-ARM%E6%8C%87%E4%BB%A4%E9%9B%86%E6%BC%94%E5%8F%98_hu6407889164870681698.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;184&#34;
		data-flex-basis=&#34;442px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;1cisccomplex-instruction-set-computer&#34;&gt;1.CISC（Complex Instruction Set Computer）
&lt;/h4&gt;
&lt;p&gt;复杂指令系统计算机，&lt;code&gt;CISC&lt;/code&gt;指令集包含大量复杂的指令，每条指令可以完成多个操作，这种设计使得编程简单，但硬件实现复杂，执行效率低&lt;/p&gt;
&lt;p&gt;&lt;code&gt;x86&lt;/code&gt;架构（&lt;code&gt;Intel&lt;/code&gt;的8086，8088，80286，80386）&lt;/p&gt;
&lt;h4 id=&#34;2riscreduced-instruction-set-computer&#34;&gt;2.RISC（Reduced Instruction Set Computer）
&lt;/h4&gt;
&lt;p&gt;精简指令系统计算机，&lt;code&gt;RISC&lt;/code&gt;指令集包含较少的简单指令，每条指令只完成一个操作，使得硬件实现更简单，执行效率更高，但编程更复杂&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ARM&lt;/code&gt;架构，&lt;code&gt;RISC-V&lt;/code&gt;架构，&lt;code&gt;MIPS&lt;/code&gt;架构&lt;/p&gt;
&lt;h3 id=&#34;开发环境dev&#34;&gt;开发环境（DEV）
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;GUN-GCC&lt;/code&gt;编译器，&lt;code&gt;CMake&lt;/code&gt;-&amp;gt;&lt;code&gt;makefile&lt;/code&gt;
&lt;code&gt;STM32F103C8（C8T6）&lt;/code&gt;经典控制器（&lt;code&gt;Cortex-M3&lt;/code&gt;）&lt;/p&gt;
&lt;h2 id=&#34;编译&#34;&gt;编译
&lt;/h2&gt;
&lt;h3 id=&#34;编译链工具&#34;&gt;编译链工具
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ARM-Cortex-M&lt;/code&gt;处理器的编译器很多，常用的是&lt;code&gt;MDK-ARM&lt;/code&gt;(&lt;code&gt;ARM&lt;/code&gt;公司自研的)(&lt;code&gt;Keil&lt;/code&gt;)，以及&lt;code&gt;GCC&lt;/code&gt;(&lt;code&gt;GNU-Compiler-Collection&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;编译器之间的最大区别在于汇编伪代码，链接语法，还有使用参数
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%BC%96%E8%AF%91%E9%93%BE%E5%B7%A5%E5%85%B7.png&#34;
	width=&#34;504&#34;
	height=&#34;210&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%BC%96%E8%AF%91%E9%93%BE%E5%B7%A5%E5%85%B7_hu6975328528861761610.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%BC%96%E8%AF%91%E9%93%BE%E5%B7%A5%E5%85%B7_hu7913020072329710182.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;240&#34;
		data-flex-basis=&#34;576px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;arm-none-eabi&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;arm&lt;/code&gt;是指&lt;code&gt;arm&lt;/code&gt;架构，&lt;code&gt;none&lt;/code&gt;是指编译出的可执行文件是运行在硬件上，而不是操作系统上，&lt;code&gt;eabi(The Embedded-Application Binary Interface)&lt;/code&gt;嵌入式应用二进制接口&lt;/p&gt;
&lt;p&gt;&lt;code&gt;arm-none-eabi-objcopy&lt;/code&gt;是一个二进制生成工具&lt;/p&gt;
&lt;h3 id=&#34;嵌入式编译烧录流程&#34;&gt;嵌入式编译烧录流程
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%BC%96%E8%AF%91%E7%83%A7%E5%BD%95%E5%85%A8%E6%B5%81%E7%A8%8B.png&#34;
	width=&#34;1641&#34;
	height=&#34;820&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%BC%96%E8%AF%91%E7%83%A7%E5%BD%95%E5%85%A8%E6%B5%81%E7%A8%8B_hu18309702811978085822.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%BC%96%E8%AF%91%E7%83%A7%E5%BD%95%E5%85%A8%E6%B5%81%E7%A8%8B_hu7323167174626790360.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;200&#34;
		data-flex-basis=&#34;480px&#34;
	
&gt;
个人更喜欢将编译过程拆解为 预编译，编译，汇编，链接&lt;/p&gt;
&lt;p&gt;转换这里是将&lt;code&gt;.elf&lt;/code&gt;文件转换为&lt;code&gt;.bin&lt;/code&gt;文件
&lt;code&gt;.bin&lt;/code&gt;文件是代码的纯机器码&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/671327144&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;一文看懂hex文件、bin文件、axf文件的区别 - 知乎&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;预编译&#34;&gt;预编译
&lt;/h4&gt;
&lt;p&gt;将所有头文件和宏展开，同时去掉注释，生成&lt;code&gt;.i&lt;/code&gt;文件（&lt;code&gt;c&lt;/code&gt;中间文件）&lt;/p&gt;
&lt;h4 id=&#34;编译-1&#34;&gt;编译
&lt;/h4&gt;
&lt;p&gt;将&lt;code&gt;.i&lt;/code&gt;文件编译为&lt;code&gt;.s&lt;/code&gt;汇编文件，编译优化发生在此处&lt;/p&gt;
&lt;h4 id=&#34;汇编&#34;&gt;汇编
&lt;/h4&gt;
&lt;p&gt;将&lt;code&gt;.s&lt;/code&gt;文件汇编为&lt;code&gt;.o&lt;/code&gt;二进制文件（机器码）
二进制文件中还包含很多的其他信息&lt;/p&gt;
&lt;p&gt;在汇编时，可以指定汇编器的参数来选择指令集&lt;/p&gt;
&lt;h4 id=&#34;链接&#34;&gt;链接
&lt;/h4&gt;
&lt;p&gt;链接是将各个二进制文件里面的机器码所在的各个段拼接起来，以形成可执行文件&lt;code&gt;.elf&lt;/code&gt;（带有调试信息）&lt;/p&gt;
&lt;p&gt;在链接这个阶段才能检测出有不有重复定义和未定义的错误&lt;/p&gt;
&lt;p&gt;对于&lt;code&gt;GNU&lt;/code&gt;来说，可以编写&lt;code&gt;.ld&lt;/code&gt;链接脚本来编排代码的分区地址&lt;/p&gt;
&lt;h4 id=&#34;转换&#34;&gt;转换
&lt;/h4&gt;
&lt;p&gt;通过转换器能将&lt;code&gt;.elf&lt;/code&gt;文件转换为&lt;code&gt;.hex&lt;/code&gt;和&lt;code&gt;.bin&lt;/code&gt;文件，主要用于提取信息&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.bin&lt;/code&gt;文件只包含二进制机器码
&lt;code&gt;.hex&lt;/code&gt;文件是&lt;code&gt;Intel&lt;/code&gt;定义的包含地址和二进制数值的&lt;code&gt;ASC&lt;/code&gt;码文本文件&lt;/p&gt;
&lt;h4 id=&#34;烧录&#34;&gt;烧录
&lt;/h4&gt;
&lt;p&gt;烧录的过程是将编译好的机器码写到&lt;code&gt;CPU&lt;/code&gt;存储器中&lt;/p&gt;
&lt;h3 id=&#34;反汇编&#34;&gt;反汇编
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;GCC&lt;/code&gt;中的反汇编工具&lt;code&gt;Disassembler&lt;/code&gt;是&lt;code&gt;arm-none-eabi-objdump&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;启动&#34;&gt;启动
&lt;/h2&gt;
&lt;p&gt;主要是讲解&lt;code&gt;STM32&lt;/code&gt;的启动流程&lt;/p&gt;
&lt;h3 id=&#34;中断向量表&#34;&gt;中断向量表
&lt;/h3&gt;
&lt;p&gt;中断向量表的构建，根据不同的编译工具，有不同的方式构建&lt;/p&gt;
&lt;p&gt;中断向量表的前两项（.woed，4字节）是最关键的
第一项是堆栈指针的值
第二项是&lt;code&gt;Reset_Handler&lt;/code&gt;函数入口&lt;/p&gt;
&lt;p&gt;在启动时，需要先设置堆栈指针，否则无法进行压栈的操作，从宏观上说，意味着&lt;code&gt;C&lt;/code&gt;语言函数体不能调用子函数&lt;/p&gt;
&lt;p&gt;VTOR寄存器，中断向量表偏移寄存器&lt;/p&gt;
&lt;h3 id=&#34;启动原理&#34;&gt;启动原理
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-stm32%E5%90%AF%E5%8A%A8%E5%8E%9F%E7%90%86.png&#34;
	width=&#34;692&#34;
	height=&#34;193&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-stm32%E5%90%AF%E5%8A%A8%E5%8E%9F%E7%90%86_hu7308303685142515106.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-stm32%E5%90%AF%E5%8A%A8%E5%8E%9F%E7%90%86_hu3601764468401878811.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;358&#34;
		data-flex-basis=&#34;860px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;启动后，从零地址（零地址是经过映射的）处读取堆栈指针和程序计数器的值（此时程序计数器的值指向&lt;code&gt;Reset_Handler&lt;/code&gt;），此外每个芯片的&lt;code&gt;Boot code&lt;/code&gt;是定制化的，需要参考手册&lt;/p&gt;
&lt;p&gt;最后&lt;code&gt;Reset_Handler&lt;/code&gt;会指向&lt;code&gt;main&lt;/code&gt;函数&lt;/p&gt;
&lt;p&gt;以&lt;code&gt;STM32F103&lt;/code&gt;为例
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-STM32F103%E7%9A%84%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE.png&#34;
	width=&#34;702&#34;
	height=&#34;183&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-STM32F103%E7%9A%84%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE_hu9096615423115854028.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-STM32F103%E7%9A%84%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE_hu17858520829407483512.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;383&#34;
		data-flex-basis=&#34;920px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;这里有三种启动模式，根据启动时&lt;code&gt;BOOT1&lt;/code&gt;和&lt;code&gt;BOOT0&lt;/code&gt;的电平来选择不同的启动地址（即 将该不同的地址映射为零地址）&lt;/p&gt;
&lt;p&gt;三种启动模式分别是 从 flash 引导启动，从 system memory 引导启动 和 从 SRAM 引导启动（即 将该不同的地址映射为零地址）&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;从主 Flash 启动：将主 Flash 地址 0x0800 0000 映射到 0x0000 0000，代码启动后相当于从 0x0800 0000 开始运行，使用 JTAG 或者 SWD 模式下载程序时会下载到 Flash 并从中启动&lt;/li&gt;
&lt;li&gt;从系统存储器启动：将系统存储器地址 0x1FFF F000 映射到 0x0000 0000，系统存储器是芯片内部的 ROM 区域，芯片出厂时在其中预置了 Bootloader，称为 ISP 程序。Bootloader 由厂家设置，一般无法修改&lt;/li&gt;
&lt;li&gt;从内置 SRAM 启动：将 SRAM 地址 0x2000 0000 映射到 0x0000 0000，代码启动后相当于从 0x2000 0000 开始运行。由于 SRAM 是易失性存储器，因此这个模式一般仅用于程序调试
（以&lt;code&gt;STM32F103&lt;/code&gt;为例）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;存储分布&#34;&gt;存储分布
&lt;/h3&gt;
&lt;p&gt;以stm32f103c8t6为例&lt;/p&gt;
&lt;h4 id=&#34;flash区&#34;&gt;Flash区
&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Flash 区：64 KiB，地址范围为 &lt;code&gt;[0x0800_0000, 0x0801_0000)&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;表中的结束地址均为区间上界，不包含在对应段内；各段之间可能因对齐要求产生填充。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;输出段或区域&lt;/th&gt;
          &lt;th&gt;起始地址&lt;/th&gt;
          &lt;th&gt;结束地址（不含）&lt;/th&gt;
          &lt;th&gt;内容&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.isr_vector&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;0x0800_0000&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ADDR(.isr_vector) + SIZEOF(.isr_vector)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;中断向量表&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.text&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;前一段结束后按 4 字节对齐&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_etext&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;程序代码以及 &lt;code&gt;.init&lt;/code&gt;、&lt;code&gt;.fini&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.rodata&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;前一段结束后按 4 字节对齐&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ADDR(.rodata) + SIZEOF(.rodata)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;只读常量和字符串&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.ARM.extab&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;前一段结束后按 4 字节对齐&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ADDR(.ARM.extab) + SIZEOF(.ARM.extab)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;ARM 栈展开信息&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.ARM&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__exidx_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__exidx_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;包含 &lt;code&gt;.ARM.exidx*&lt;/code&gt; 的栈展开索引&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.preinit_array&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__preinit_array_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__preinit_array_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;在普通初始化函数之前执行的预初始化函数数组&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.init_array&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__init_array_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__init_array_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;初始化函数数组，包含 C++ 全局对象和文件作用域静态对象的构造函数入口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.fini_array&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__fini_array_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__fini_array_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;结束函数数组，包含 C++ 全局对象和文件作用域静态对象的析构函数调用入口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.data&lt;/code&gt; 初值镜像（LMA）&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sidata = LOADADDR(.data)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sidata + SIZEOF(.data)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;已初始化变量及 &lt;code&gt;.RamFunc&lt;/code&gt; 的加载镜像，复位后复制到 RAM&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;.init_array&lt;/code&gt; 在 &lt;code&gt;main&lt;/code&gt; 执行前参与 C++ 对象构造；&lt;code&gt;.fini_array&lt;/code&gt; 在程序正常退出阶段参与对象析构。裸机程序通常不会从 &lt;code&gt;main&lt;/code&gt; 返回，其析构流程是否执行取决于运行库和退出路径。&lt;/p&gt;
&lt;h4 id=&#34;ram区&#34;&gt;RAM区
&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;RAM 区：20 KiB，地址范围为 &lt;code&gt;[0x2000_0000, 0x2000_5000)&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;0x2000_5000&lt;/code&gt; 位于 RAM 最后一个有效地址之后，也是该链接脚本中 &lt;code&gt;_estack&lt;/code&gt; 的初始值。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;项目&lt;/th&gt;
          &lt;th&gt;地址或范围&lt;/th&gt;
          &lt;th&gt;内容与作用&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.data&lt;/code&gt;（VMA）&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sdata&lt;/code&gt; 到 &lt;code&gt;_edata&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;已初始化的全局变量、静态变量及在 RAM 中运行的 &lt;code&gt;.RamFunc&lt;/code&gt;；复位时从 Flash 的 &lt;code&gt;_sidata&lt;/code&gt; 复制&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.bss&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sbss&lt;/code&gt; 到 &lt;code&gt;_ebss&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;未初始化或初始化为零的全局变量和静态变量；复位时由启动代码清零&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;.bss&lt;/code&gt; 结束后按 8 字节对齐的位置&lt;/td&gt;
          &lt;td&gt;静态分配区域的结束标记，常作为 C 运行库堆的起点&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;._user_heap_stack&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;从 &lt;code&gt;_end&lt;/code&gt; 开始，增加 &lt;code&gt;_Min_Heap_Size&lt;/code&gt; 和 &lt;code&gt;_Min_Stack_Size&lt;/code&gt; 后按 8 字节对齐&lt;/td&gt;
          &lt;td&gt;用于链接期容量检查，不表示运行时堆和栈的固定分界&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;C 运行库堆&lt;/td&gt;
          &lt;td&gt;通常从 &lt;code&gt;_end&lt;/code&gt; 向高地址增长&lt;/td&gt;
          &lt;td&gt;供 &lt;code&gt;malloc&lt;/code&gt;、&lt;code&gt;free&lt;/code&gt; 等接口使用，实际边界由运行库实现决定&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;主栈&lt;/td&gt;
          &lt;td&gt;从 &lt;code&gt;_estack = 0x2000_5000&lt;/code&gt; 向低地址增长&lt;/td&gt;
          &lt;td&gt;MSP 的初始位置，用于函数调用、局部变量和中断现场保存&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;堆栈间可用空间&lt;/td&gt;
          &lt;td&gt;当前堆末端与当前栈指针之间&lt;/td&gt;
          &lt;td&gt;大小随程序运行动态变化；堆和栈相遇时会发生内存冲突&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;_Min_Heap_Size&lt;/code&gt; 和 &lt;code&gt;_Min_Stack_Size&lt;/code&gt; 只用于验证最小容量能否装入 RAM，并不会在运行时建立固定的堆栈边界。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-RAM%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83.png&#34;
	width=&#34;1269&#34;
	height=&#34;674&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-RAM%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83_hu13448359514406145975.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-RAM%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83_hu250755568266859443.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;188&#34;
		data-flex-basis=&#34;451px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;如果使用了FreeRTOS的话，FreeRTOS的内存布局如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-FreeRTOS%E7%9A%84%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80.png&#34;
	width=&#34;1038&#34;
	height=&#34;695&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-FreeRTOS%E7%9A%84%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80_hu6082313860412554675.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-FreeRTOS%E7%9A%84%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80_hu14391524076225901871.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;149&#34;
		data-flex-basis=&#34;358px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;内存分配规则&#34;&gt;内存分配规则
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;全局变量、局部静态变量&lt;/strong&gt;：根据是否初始化决定分配在.data段或.bss段&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用const关键字声明的常量&lt;/strong&gt;：分配在Flash中&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用C标准的malloc申请的内存&lt;/strong&gt;：分配在系统堆中&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不在任务中定义的临时变量&lt;/strong&gt;：分配在系统栈中&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用&lt;code&gt;pvPortMalloc&lt;/code&gt;开辟的内存或调用FreeRTOS标准API自动分配的内存：分配在FreeRTOS堆中&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在任务中定义的临时变量&lt;/strong&gt;：分配在对应任务的任务栈中&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在中断中使用&lt;/strong&gt;*&lt;code&gt;pvPortMallocFromISR&lt;/code&gt;&lt;strong&gt;分配的内存&lt;/strong&gt;：分配在FreeRTOS堆中&lt;/li&gt;
&lt;li&gt;在中断中禁止使用C标准的malloc和free&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中断中定义的临时变量&lt;/strong&gt;：分配在系统&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;启动文件详解&#34;&gt;启动文件详解
&lt;/h3&gt;
&lt;h4 id=&#34;一stm32f103-启动文件startup_stm32f103xbs核心定位&#34;&gt;一、STM32F103 启动文件（startup_stm32f103xb.s）核心定位
&lt;/h4&gt;
&lt;p&gt;STM32 的启动文件（如&lt;code&gt;startup_stm32f103xb.s&lt;/code&gt;）是&lt;strong&gt;汇编语言编写的底层程序&lt;/strong&gt;，是硬件复位后执行的第一段代码，负责衔接 “硬件初始化” 与 “用户 C 代码（&lt;code&gt;main&lt;/code&gt;函数）”。其核心功能包括：设置栈指针、构建中断向量表、初始化数据段（&lt;code&gt;.data&lt;/code&gt;）、清零未初始化数据段（&lt;code&gt;.bss&lt;/code&gt;）、配置系统时钟，最终引导程序进入&lt;code&gt;main&lt;/code&gt;函数，是 STM32 程序运行的 “底层基石”。&lt;/p&gt;
&lt;h4 id=&#34;二启动文件整体结构拆解&#34;&gt;二、启动文件整体结构拆解
&lt;/h4&gt;
&lt;p&gt;该启动文件按功能可划分为 5 个核心模块，各模块职责明确且环环相扣：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;汇编环境配置&lt;/strong&gt;：指定处理器架构、指令集、浮点模式，确保汇编代码与硬件兼容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键符号声明&lt;/strong&gt;：引用链接器脚本（&lt;code&gt;.ld&lt;/code&gt;）中定义的内存地址符号，建立启动文件与内存布局的关联。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;复位处理函数（&lt;code&gt;Reset_Handler&lt;/code&gt;）&lt;/strong&gt;：复位后执行的核心逻辑，完成初始化并跳转到&lt;code&gt;main&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中断向量表（&lt;code&gt;g_pfnVectors&lt;/code&gt;）&lt;/strong&gt;：存储所有异常 / 中断的处理函数地址，供内核响应中断时调用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;默认中断处理函数（&lt;code&gt;Default_Handler&lt;/code&gt;）&lt;/strong&gt;：未自定义的中断会默认进入此处，避免系统崩溃。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;三逐段解析启动文件代码&#34;&gt;三、逐段解析启动文件代码
&lt;/h4&gt;
&lt;h5 id=&#34;1-汇编环境配置开头基础设置&#34;&gt;1. 汇编环境配置（开头基础设置）
&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;.syntax&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;unified&lt;/span&gt;       &lt;span class=&#34;c1&#34;&gt;; 使用统一汇编语法（兼容ARM与Thumb指令集）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.cpu&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;cortex-m3&lt;/span&gt;        &lt;span class=&#34;c1&#34;&gt;; 目标处理器为Cortex-M3（STM32F103内核型号）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.fpu&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;softvfp&lt;/span&gt;          &lt;span class=&#34;c1&#34;&gt;; 浮点模式：软件模拟（STM32F103无硬件FPU）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.thumb&lt;/span&gt;                &lt;span class=&#34;c1&#34;&gt;; 启用Thumb指令集（Cortex-M3仅支持Thumb/Thumb2指令）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：告诉汇编器（如&lt;code&gt;arm-none-eabi-as&lt;/code&gt;）“如何编译这段代码”，确保生成的指令能被 STM32F103 正确执行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键细节&lt;/strong&gt;：&lt;code&gt;softvfp&lt;/code&gt;对应 STM32F103 的硬件特性 —— 该型号无硬件浮点处理单元（FPU），需通过软件模拟浮点运算，与之前解析的&lt;code&gt;.ld&lt;/code&gt;文件中未配置 FPU 参数完全匹配。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;2-关键符号声明与链接器脚本联动&#34;&gt;2. 关键符号声明（与链接器脚本联动）
&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;.global&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;g_pfnVectors&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;; 全局符号：中断向量表（供链接器识别并分配地址）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.global&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;Default_Handler&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; 全局符号：默认中断处理函数（供中断向量表引用）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;/* 引用链接器脚本（.ld）中定义的内存地址符号 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_sidata&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; .data段在FLASH中的加载地址（LMA，初始值存放位置）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_sdata&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;; .data段在RAM中的运行起始地址（VMA，变量实际存储位置）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_edata&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;; .data段在RAM中的运行结束地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_sbss&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;; .bss段在RAM中的起始地址（未初始化变量存储区）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_ebss&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;; .bss段在RAM中的结束地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;.equ&lt;/span&gt;  &lt;span class=&#34;no&#34;&gt;BootRAM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0xF108F85F&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 定义RAM启动模式的特殊地址（仅用于特定boot配置）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;核心意义&lt;/strong&gt;：通过&lt;code&gt;.word&lt;/code&gt;指令声明的符号，直接引用&lt;code&gt;.ld&lt;/code&gt;文件中根据硬件内存布局（64K FLASH、20K RAM）计算出的地址。例如：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_sdata&lt;/code&gt;和&lt;code&gt;_edata&lt;/code&gt;确定了&lt;code&gt;.data&lt;/code&gt;段在 RAM 中的范围，&lt;code&gt;_sidata&lt;/code&gt;确定了其初始值在 FLASH 中的位置，为后续 “数据段复制” 提供地址依据。&lt;/li&gt;
&lt;li&gt;若缺少这些符号，启动文件无法知道 “数据该从哪里复制到哪里”，内存初始化会彻底失败。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;3-复位处理函数reset_handler启动核心逻辑&#34;&gt;3. 复位处理函数（&lt;code&gt;Reset_Handler&lt;/code&gt;：启动核心逻辑）
&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;Reset_Handler&lt;/code&gt;是复位后执行的第一个函数（由中断向量表指定），对应 STM32 启动流程中的 “软件初始化” 阶段，代码逻辑可分为 5 步：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;.section&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;.text.Reset_Handler&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 将函数放入.text段（代码段，.ld中分配到FLASH）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.weak&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;Reset_Handler&lt;/span&gt;           &lt;span class=&#34;c1&#34;&gt;; 弱定义：允许用户代码重定义该函数（覆盖默认逻辑）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.type&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;Reset_Handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;%function&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; 标记为函数类型（汇编器识别函数边界）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;Reset_Handler:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* 步骤1：初始化系统时钟 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;bl&lt;/span&gt;  &lt;span class=&#34;no&#34;&gt;SystemInit&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 跳转到STM32库函数SystemInit（配置HSE/PLL，将时钟从8MHz HSI切换到72MHz）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* 步骤2：复制.data段（从FLASH到RAM） */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;ldr&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;_sdata&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;; r0 = .data段在RAM的起始地址（VMA）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;ldr&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;_edata&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;; r1 = .data段在RAM的结束地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;ldr&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;_sidata&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; r2 = .data段在FLASH的加载地址（LMA）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;movs&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;#0       ; r3 = 偏移量（初始为0，每次复制4字节后递增）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;LoopCopyDataInit&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; 跳转到循环复制入口
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nl&#34;&gt;CopyDataInit:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;ldr&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;r2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 从FLASH读取数据：r4 = *(r2 + r3)（源地址=加载地址+偏移量）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;r0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 写入RAM：*(r0 + r3) = r4（目标地址=运行地址+偏移量）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;adds&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;#4   ; 偏移量+4（32位数据，每次复制1个word）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nl&#34;&gt;LoopCopyDataInit:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;adds&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r3&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;; r4 = 当前复制位置（运行地址+偏移量）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;cmp&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r1&lt;/span&gt;        &lt;span class=&#34;c1&#34;&gt;; 比较当前位置与结束地址：是否复制完成？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;bcc&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;CopyDataInit&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 若未完成（r4 &amp;lt; r1），继续循环复制
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* 步骤3：清零.bss段（未初始化变量区） */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;ldr&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;_sbss&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;; r2 = .bss段在RAM的起始地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;ldr&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;_ebss&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;; r4 = .bss段在RAM的结束地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;movs&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;#0       ; r3 = 0（用于清零）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;LoopFillZerobss&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; 跳转到循环清零入口
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nl&#34;&gt;FillZerobss:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;str&lt;/span&gt;  &lt;span class=&#34;no&#34;&gt;r3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;r2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;     &lt;span class=&#34;c1&#34;&gt;; 将0写入当前地址：*r2 = 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;adds&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;#4   ; 地址+4（每次清零1个word）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nl&#34;&gt;LoopFillZerobss:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;cmp&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;r4&lt;/span&gt;        &lt;span class=&#34;c1&#34;&gt;; 比较当前地址与结束地址：是否清零完成？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;bcc&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;FillZerobss&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;; 若未完成（r2 &amp;lt; r4），继续循环清零
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* 步骤4：初始化C++静态构造函数（兼容C++项目） */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;bl&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;__libc_init_array&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 调用C库函数，执行全局对象构造（纯C项目可忽略，不影响运行）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cm&#34;&gt;/* 步骤5：跳转到用户main函数 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;bl&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;main&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;; 跳转到用户C代码的main函数（启动流程结束，交权给用户）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nf&#34;&gt;bx&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;lr&lt;/span&gt;     &lt;span class=&#34;c1&#34;&gt;; 若main函数返回（实际中main通常是死循环），跳回当前位置（无实际意义）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.size&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;Reset_Handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;.-Reset_Handler&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 定义函数大小（.表示当前地址，计算函数长度）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h5 id=&#34;关键步骤解读&#34;&gt;关键步骤解读：
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;系统时钟初始化（&lt;code&gt;SystemInit&lt;/code&gt;）&lt;/strong&gt;：STM32 复位后默认使用 8MHz 的内部高速时钟（HSI），&lt;code&gt;SystemInit&lt;/code&gt;函数会配置外部高速时钟（HSE）和锁相环（PLL），将系统时钟提升到 72MHz（F103 的常用工作频率），确保外设和 CPU 高效运行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.data 段复制&lt;/strong&gt;：&lt;code&gt;.data&lt;/code&gt;段存储 “已初始化的全局 / 静态变量”（如&lt;code&gt;int a = 10;&lt;/code&gt;），这些变量需要读写权限，因此运行时必须在 RAM 中；但编译时其初始值会存放在 FLASH（节省 RAM），需通过此步骤复制到 RAM。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.bss 段清零&lt;/strong&gt;：&lt;code&gt;.bss&lt;/code&gt;段存储 “未初始化的全局 / 静态变量”（如&lt;code&gt;int b;&lt;/code&gt;），C 语言标准要求其初始值为 0，因此无需在 FLASH 中存储初始值，直接将 RAM 对应区域清零即可。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跳转到&lt;code&gt;main&lt;/code&gt;&lt;/strong&gt;：这是启动文件的 “最终目标”—— 完成所有底层初始化后，将程序控制权交给用户代码，正式进入应用逻辑。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;4-中断向量表g_pfnvectors中断响应的-地址簿&#34;&gt;4. 中断向量表（&lt;code&gt;g_pfnVectors&lt;/code&gt;：中断响应的 “地址簿”）
&lt;/h5&gt;
&lt;p&gt;中断向量表是&lt;strong&gt;Cortex-M3 内核复位后访问的第一个数据结构&lt;/strong&gt;，存储了所有异常（如复位、硬 fault）和外设中断（如串口、定时器）的处理函数地址。当发生中断 / 异常时，内核会从向量表中找到对应地址，跳转到处理函数执行。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;.section&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;.isr_vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;%progbits&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 将向量表放入.isr_vector段（.ld中分配到FLASH起始地址0x8000000）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.type&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;g_pfnVectors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;%object&lt;/span&gt;         &lt;span class=&#34;c1&#34;&gt;; 标记为数据对象（而非函数）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.size&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;g_pfnVectors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;.-g_pfnVectors&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 定义向量表大小（计算表的总字节数）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nl&#34;&gt;g_pfnVectors:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_estack&lt;/span&gt;                       &lt;span class=&#34;c1&#34;&gt;; 第0个元素：栈顶地址（MSP初始值，来自.ld文件）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;Reset_Handler&lt;/span&gt;                 &lt;span class=&#34;c1&#34;&gt;; 第1个元素：复位处理函数地址（复位后PC指向这里）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;NMI_Handler&lt;/span&gt;                   &lt;span class=&#34;c1&#34;&gt;; 第2个元素：不可屏蔽中断（NMI）处理函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;HardFault_Handler&lt;/span&gt;             &lt;span class=&#34;c1&#34;&gt;; 第3个元素：硬fault异常处理函数（严重错误，如内存访问越界）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;MemManage_Handler&lt;/span&gt;             &lt;span class=&#34;c1&#34;&gt;; 第4个元素：内存管理异常处理函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;BusFault_Handler&lt;/span&gt;              &lt;span class=&#34;c1&#34;&gt;; 第5个元素：总线fault异常处理函数（如访问不存在的外设地址）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;UsageFault_Handler&lt;/span&gt;            &lt;span class=&#34;c1&#34;&gt;; 第6个元素：用法fault异常处理函数（如指令错误）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;                             &lt;span class=&#34;c1&#34;&gt;; 第7-10个元素：保留（未使用）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;SVC_Handler&lt;/span&gt;                   &lt;span class=&#34;c1&#34;&gt;; 第11个元素：系统服务调用（SVC）处理函数（OS常用）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;DebugMon_Handler&lt;/span&gt;              &lt;span class=&#34;c1&#34;&gt;; 第12个元素：调试监控处理函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;                             &lt;span class=&#34;c1&#34;&gt;; 第13个元素：保留
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;PendSV_Handler&lt;/span&gt;                &lt;span class=&#34;c1&#34;&gt;; 第14个元素：PendSV异常处理函数（任务切换常用）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;SysTick_Handler&lt;/span&gt;               &lt;span class=&#34;c1&#34;&gt;; 第15个元素：系统滴答定时器（SysTick）处理函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;cm&#34;&gt;/* 以下为外设中断向量（第16个元素开始） */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;WWDG_IRQHandler&lt;/span&gt;               &lt;span class=&#34;c1&#34;&gt;; 窗口看门狗中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;PVD_IRQHandler&lt;/span&gt;                &lt;span class=&#34;c1&#34;&gt;; 电源电压检测中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;TAMPER_IRQHandler&lt;/span&gt;             &lt;span class=&#34;c1&#34;&gt;; 篡改检测中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;RTC_IRQHandler&lt;/span&gt;                &lt;span class=&#34;c1&#34;&gt;; RTC时钟中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;FLASH_IRQHandler&lt;/span&gt;              &lt;span class=&#34;c1&#34;&gt;; FLASH操作中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;RCC_IRQHandler&lt;/span&gt;                &lt;span class=&#34;c1&#34;&gt;; RCC时钟控制中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;EXTI0_IRQHandler&lt;/span&gt;              &lt;span class=&#34;c1&#34;&gt;; 外部中断0（如PA0）中断
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;（省略其余外设中断，共&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;60&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;+个，对应&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;F103所有外设&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;）&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;.word&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;BootRAM&lt;/span&gt;                       &lt;span class=&#34;c1&#34;&gt;; RAM启动模式的特殊地址（仅用于从RAM启动，默认从FLASH启动时无用）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h5 id=&#34;核心特性&#34;&gt;核心特性：
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;位置固定&lt;/strong&gt;：在&lt;code&gt;.ld&lt;/code&gt;文件中，&lt;code&gt;.isr_vector&lt;/code&gt;段被强制分配到 FLASH 起始地址（&lt;code&gt;0x8000000&lt;/code&gt;），这是 Cortex-M3 内核的硬件规定 —— 复位后内核会自动从&lt;code&gt;0x8000000&lt;/code&gt;读取向量表。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 0 个元素必为栈顶&lt;/strong&gt;：内核复位后做的第一件事是 “初始化栈指针（MSP）”，因此向量表第 0 个元素必须是栈顶地址（&lt;code&gt;_estack&lt;/code&gt;，来自.ld 文件），否则后续函数调用、局部变量存储会因栈地址错误崩溃。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中断优先级隐含&lt;/strong&gt;：向量表中元素的顺序对应中断 / 异常的优先级（靠前的优先级更高），例如 “硬 fault”（第 3 个元素）优先级高于 “SysTick”（第 15 个元素）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;5-默认中断处理函数default_handler中断-兜底-逻辑&#34;&gt;5. 默认中断处理函数（&lt;code&gt;Default_Handler&lt;/code&gt;：中断 “兜底” 逻辑）
&lt;/h5&gt;
&lt;p&gt;当用户未为某个中断定义处理函数时，中断向量表会将该中断的地址指向&lt;code&gt;Default_Handler&lt;/code&gt;，避免系统因 “找不到中断处理函数” 而进入未知状态。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;.section&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;.text.Default_Handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;ax&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;%progbits&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 放入.text段，属性为可执行（ax）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;Default_Handler:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nl&#34;&gt;Infinite_Loop:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;Infinite_Loop&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 无限循环（死循环），防止程序跑飞
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.size&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;Default_Handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;.-Default_Handler&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 定义函数大小
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h5 id=&#34;弱别名机制用户可重定义中断函数&#34;&gt;弱别名机制（用户可重定义中断函数）
&lt;/h5&gt;
&lt;p&gt;启动文件通过 “弱别名（&lt;code&gt;.weak&lt;/code&gt;）” 允许用户在 C 代码中重定义中断处理函数，具体逻辑如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;.weak&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;NMI_Handler&lt;/span&gt;                  &lt;span class=&#34;c1&#34;&gt;; 弱定义：NMI_Handler可被用户代码覆盖
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;.thumb_set&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;NMI_Handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Default_Handler&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; 若用户未定义，NMI_Handler默认指向Default_Handler
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;工作原理&lt;/strong&gt;：
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;.weak&lt;/code&gt;标记表示 “该符号是弱定义的，若用户定义了同名符号，优先使用用户定义的版本”。&lt;/li&gt;
&lt;li&gt;用户只需在 C 代码中编写&lt;code&gt;void USART1_IRQHandler(void) { ... }&lt;/code&gt;，链接时会自动覆盖启动文件中的弱定义，使串口 1 中断触发时执行用户代码。&lt;/li&gt;
&lt;li&gt;若用户未定义，则使用默认的&lt;code&gt;Default_Handler&lt;/code&gt;（无限循环）。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;四启动文件与链接器脚本ld的配合关系&#34;&gt;四、启动文件与链接器脚本（.ld）的配合关系
&lt;/h4&gt;
&lt;p&gt;启动文件与&lt;code&gt;.ld&lt;/code&gt;文件是&lt;strong&gt;紧密耦合的 “搭档”&lt;/strong&gt;，二者通过 “全局符号” 和 “段分配” 协同工作，缺一不可：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;协作维度&lt;/th&gt;
          &lt;th&gt;启动文件角色&lt;/th&gt;
          &lt;th&gt;链接器脚本（.ld）角色&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;内存地址提供&lt;/td&gt;
          &lt;td&gt;引用&lt;code&gt;.ld&lt;/code&gt;定义的&lt;code&gt;_sdata&lt;/code&gt;、&lt;code&gt;_ebss&lt;/code&gt;、&lt;code&gt;_estack&lt;/code&gt;等符号&lt;/td&gt;
          &lt;td&gt;根据硬件内存布局（64K FLASH、20K RAM）计算并定义这些符号&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;段分配依据&lt;/td&gt;
          &lt;td&gt;将&lt;code&gt;Reset_Handler&lt;/code&gt;放入&lt;code&gt;.text&lt;/code&gt;段、向量表放入&lt;code&gt;.isr_vector&lt;/code&gt;段&lt;/td&gt;
          &lt;td&gt;规定&lt;code&gt;.text&lt;/code&gt;、&lt;code&gt;.isr_vector&lt;/code&gt;等段的存储位置（如&lt;code&gt;.isr_vector&lt;/code&gt;分配到 FLASH 起始地址）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;程序入口指定&lt;/td&gt;
          &lt;td&gt;实现&lt;code&gt;Reset_Handler&lt;/code&gt;函数（入口逻辑）&lt;/td&gt;
          &lt;td&gt;通过&lt;code&gt;ENTRY(Reset_Handler)&lt;/code&gt;指定程序入口为该函数&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;内存合法性检查&lt;/td&gt;
          &lt;td&gt;依赖&lt;code&gt;.ld&lt;/code&gt;确保&lt;code&gt;_sdata&lt;/code&gt;、&lt;code&gt;_ebss&lt;/code&gt;不超出 RAM 范围&lt;/td&gt;
          &lt;td&gt;检查堆、栈、数据段总大小是否超过 RAM/FLASH 容量，溢出则报错&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;五总结启动文件的核心价值&#34;&gt;五、总结：启动文件的核心价值
&lt;/h4&gt;
&lt;p&gt;STM32 启动文件是 “从硬件到软件的桥梁”，其核心作用可概括为 3 点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;硬件初始化&lt;/strong&gt;：完成栈指针设置、系统时钟配置，为程序运行提供基础硬件环境。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内存初始化&lt;/strong&gt;：通过复制&lt;code&gt;.data&lt;/code&gt;段、清零&lt;code&gt;.bss&lt;/code&gt;段，确保全局 / 静态变量符合 C 语言标准要求。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中断系统准备&lt;/strong&gt;：构建中断向量表，提供默认中断处理逻辑，支持用户自定义中断函数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;引导用户代码&lt;/strong&gt;：最终跳转到&lt;code&gt;main&lt;/code&gt;函数，将程序控制权交给用户，完成 “底层初始化→应用逻辑” 的过渡。
简言之：没有启动文件，STM32 复位后无法完成任何初始化，更无法进入&lt;code&gt;main&lt;/code&gt;函数 —— 它是 STM32 程序运行的 “第一块拼图”。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;stm32-启动流程ld-文件作用及示例解析&#34;&gt;STM32 启动流程、.ld 文件作用及示例解析
&lt;/h3&gt;
&lt;p&gt;要理解 STM32 的启动流程、&lt;code&gt;.ld&lt;/code&gt;文件（链接器脚本）的作用，以及你提供的具体&lt;code&gt;.ld&lt;/code&gt;文件内容，我们需要从&lt;strong&gt;宏观启动逻辑&lt;/strong&gt;到&lt;strong&gt;链接器脚本细节&lt;/strong&gt;逐步拆解，最终建立两者的关联。&lt;/p&gt;
&lt;h4 id=&#34;一stm32-的启动流程从复位到main函数&#34;&gt;一、STM32 的启动流程（从复位到&lt;code&gt;main&lt;/code&gt;函数）
&lt;/h4&gt;
&lt;p&gt;STM32 的启动流程是&lt;strong&gt;硬件复位→内核初始化→软件初始化→进入&lt;code&gt;main&lt;/code&gt;&lt;/strong&gt; 的过程，核心依赖「中断向量表」和「启动文件」，而&lt;code&gt;.ld&lt;/code&gt;文件为这个流程提供了&lt;strong&gt;内存地址映射&lt;/strong&gt;和&lt;strong&gt;段分配规则&lt;/strong&gt;。&lt;/p&gt;
&lt;h5 id=&#34;1-硬件复位pc-指针的初始指向&#34;&gt;1. 硬件复位：PC 指针的初始指向
&lt;/h5&gt;
&lt;p&gt;当 STM32 上电或复位时，Cortex-M 内核会自动执行以下操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;读取&lt;strong&gt;中断向量表的第一个元素&lt;/strong&gt;（栈顶地址&lt;code&gt;_estack&lt;/code&gt;），初始化主栈指针（MSP）—— 这是内核执行的第一个动作，因为函数调用、局部变量都依赖栈。&lt;/li&gt;
&lt;li&gt;将程序计数器（PC）指向&lt;strong&gt;中断向量表的第二个元素&lt;/strong&gt;（&lt;code&gt;Reset_Handler&lt;/code&gt;的地址）—— 这是复位后的第一个执行函数（启动流程的入口）。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;关键：中断向量表的默认地址是&lt;code&gt;0x8000000&lt;/code&gt;（STM32 FLASH 的起始地址），这也是&lt;code&gt;.ld&lt;/code&gt;文件中&lt;code&gt;FLASH&lt;/code&gt;的&lt;code&gt;ORIGIN&lt;/code&gt;（起始地址）设置为&lt;code&gt;0x8000000&lt;/code&gt;的原因。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5 id=&#34;2-执行reset_handler启动文件核心逻辑&#34;&gt;2. 执行&lt;code&gt;Reset_Handler&lt;/code&gt;（启动文件核心逻辑）
&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;Reset_Handler&lt;/code&gt;是启动文件（如&lt;code&gt;startup_stm32f103c8tx.s&lt;/code&gt;）中的汇编函数，是软件初始化的核心，其逻辑完全依赖&lt;code&gt;.ld&lt;/code&gt;文件定义的&lt;strong&gt;全局符号&lt;/strong&gt;（如&lt;code&gt;_sdata&lt;/code&gt;、&lt;code&gt;_ebss&lt;/code&gt;），具体步骤如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;初始化数据段（.data）&lt;/strong&gt;：&lt;br&gt;
&lt;code&gt;.data&lt;/code&gt;段存放「初始化过的全局 / 静态变量」（如&lt;code&gt;int a = 10;&lt;/code&gt;），这些变量需要&lt;strong&gt;读写权限&lt;/strong&gt;，因此运行时必须在 RAM 中；但编译时会把它们的初始值存放在 FLASH 中（节省 RAM 空间）。&lt;br&gt;
&lt;code&gt;Reset_Handler&lt;/code&gt;会执行复制操作：从&lt;code&gt;.ld&lt;/code&gt;文件定义的&lt;code&gt;_sidata&lt;/code&gt;（.data 在 FLASH 的加载地址）复制到&lt;code&gt;_sdata&lt;/code&gt;（.data 在 RAM 的运行地址），直到&lt;code&gt;_edata&lt;/code&gt;（.data 的结束地址）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;清零未初始化数据段（.bss）&lt;/strong&gt;：&lt;br&gt;
&lt;code&gt;.bss&lt;/code&gt;段存放「未初始化的全局 / 静态变量」（如&lt;code&gt;int b;&lt;/code&gt;），C 语言标准要求它们初始化为 0。&lt;br&gt;
&lt;code&gt;Reset_Handler&lt;/code&gt;会将&lt;code&gt;_sbss&lt;/code&gt;（.bss 的起始地址）到&lt;code&gt;_ebss&lt;/code&gt;（.bss 的结束地址）的 RAM 区域全部清零。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;初始化系统时钟（SystemInit）&lt;/strong&gt;：&lt;br&gt;
调用&lt;code&gt;SystemInit&lt;/code&gt;函数（由 STM32 标准库 / LL 库提供），配置 HSE/PLL 等，将系统时钟从默认的 HSI（8MHz）切换到更高频率（如 72MHz）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;调用&lt;code&gt;main&lt;/code&gt;函数&lt;/strong&gt;：&lt;br&gt;
完成所有初始化后，跳转到 C 语言的&lt;code&gt;main&lt;/code&gt;函数，进入用户应用逻辑。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&#34;3-异常--中断的触发补充&#34;&gt;3. 异常 / 中断的触发（补充）
&lt;/h5&gt;
&lt;p&gt;若程序运行中触发中断（如定时器、串口），内核会再次读取「中断向量表」，根据中断号找到对应的中断服务函数（ISR）地址，跳转到 ISR 执行，执行完成后返回断点继续运行。&lt;/p&gt;
&lt;h4 id=&#34;二ld-文件链接器脚本的核心作用&#34;&gt;二、.ld 文件（链接器脚本）的核心作用
&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;.ld&lt;/code&gt;文件是&lt;strong&gt;链接器（ld）的配置文件&lt;/strong&gt;，其本质是告诉链接器：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;芯片的内存布局&lt;/strong&gt;：FLASH（只读、存代码 / 常量）和 RAM（可读写、存变量 / 栈 / 堆）的&lt;strong&gt;起始地址&lt;/strong&gt;和&lt;strong&gt;大小&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码 / 数据的段分配规则&lt;/strong&gt;：将编译生成的各个「段（Section）」（如&lt;code&gt;.text&lt;/code&gt;、&lt;code&gt;.data&lt;/code&gt;）分配到对应的内存区域（FLASH/RAM）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定义全局符号&lt;/strong&gt;：生成&lt;code&gt;_sdata&lt;/code&gt;、&lt;code&gt;_ebss&lt;/code&gt;、&lt;code&gt;_estack&lt;/code&gt;等符号，供启动文件和用户代码使用（如启动文件依赖这些符号初始化内存）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内存合法性检查&lt;/strong&gt;：确保堆、栈、数据段的总大小不超过 RAM/FLASH 的实际容量，避免内存溢出。
简单说：没有&lt;code&gt;.ld&lt;/code&gt;文件，链接器无法知道 “代码该放哪里、变量该放哪里”，无法生成可执行的&lt;code&gt;.elf&lt;/code&gt;/&lt;code&gt;.hex&lt;/code&gt;文件。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;三解析-stm32f103c8tx-的ld-文件&#34;&gt;三、解析 STM32F103C8Tx 的.ld 文件
&lt;/h4&gt;
&lt;p&gt;以下按文件结构逐段解析，结合 STM32F103C8Tx 的硬件参数（64K FLASH、20K RAM）说明每部分的作用。&lt;/p&gt;
&lt;h5 id=&#34;1-入口点与栈顶定义&#34;&gt;1. 入口点与栈顶定义
&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/* Entry Point */
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ENTRY(Reset_Handler)  // 定义程序的入口函数：Reset_Handler（与启动文件对应）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/* Highest address of the user mode stack */
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;_estack = ORIGIN(RAM) + LENGTH(RAM);  // 栈顶地址 = RAM起始地址 + RAM总大小
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/* Generate a link error if heap and stack don&amp;#39;t fit into RAM */
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;_Min_Heap_Size = 0x200;      // 最小堆大小（512字节，供malloc使用）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;_Min_Stack_Size = 0xF00;     // 最小栈大小（3840字节，供函数调用/局部变量使用）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;ENTRY(Reset_Handler)&lt;/code&gt;&lt;/strong&gt;：强制链接器将&lt;code&gt;Reset_Handler&lt;/code&gt;作为程序第一个执行的函数，与启动流程中 PC 指向&lt;code&gt;Reset_Handler&lt;/code&gt;完全对应。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_estack&lt;/code&gt;&lt;/strong&gt;：定义栈顶地址（STM32F103C8Tx 的 RAM 是&lt;code&gt;0x20000000~0x20004FFF&lt;/code&gt;，因此&lt;code&gt;_estack=0x20005000&lt;/code&gt;），启动文件会将这个地址加载到 MSP（主栈指针）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;堆 / 栈大小&lt;/strong&gt;：&lt;code&gt;_Min_Heap_Size&lt;/code&gt;和&lt;code&gt;_Min_Stack_Size&lt;/code&gt;是最小要求，若用户代码中堆 / 栈使用超过这个值，链接器会报错（防止 RAM 溢出），可根据需求调整（如栈不够时增大&lt;code&gt;_Min_Stack_Size&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;2-内存区域定义memory-块&#34;&gt;2. 内存区域定义（MEMORY 块）
&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/* Specify the memory areas */
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MEMORY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 20K  // RAM区域
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 64K   // FLASH区域
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这是&lt;code&gt;.ld&lt;/code&gt;文件的核心，定义了芯片的&lt;strong&gt;物理内存属性&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;RAM (xrw)&lt;/code&gt;&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;xrw&lt;/code&gt;：权限（&lt;code&gt;x&lt;/code&gt;= 可执行，&lt;code&gt;r&lt;/code&gt;= 可读，&lt;code&gt;w&lt;/code&gt;= 可写）——RAM 支持读写，理论上可执行（但通常不放代码）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ORIGIN = 0x20000000&lt;/code&gt;：STM32 所有 Cortex-M3 内核芯片的 RAM 起始地址（硬件规定）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LENGTH = 20K&lt;/code&gt;：STM32F103C8Tx 的 RAM 实际大小（20KB = 0x5000 字节，范围&lt;code&gt;0x20000000~0x20004FFF&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;FLASH (rx)&lt;/code&gt;&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rx&lt;/code&gt;：权限（&lt;code&gt;r&lt;/code&gt;= 可读，&lt;code&gt;x&lt;/code&gt;= 可执行，&lt;code&gt;w&lt;/code&gt;= 不可写）——FLASH 是只读存储器，只能存放代码和常量。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ORIGIN = 0x8000000&lt;/code&gt;：STM32 FLASH 的起始地址（硬件规定，复位后 PC 默认指向这里）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LENGTH = 64K&lt;/code&gt;：STM32F103C8Tx 的 FLASH 实际大小（64KB = 0x10000 字节，范围&lt;code&gt;0x8000000~0x800FFFF&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;3-段分配规则sections-块&#34;&gt;3. 段分配规则（SECTIONS 块）
&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;SECTIONS&lt;/code&gt;块是最复杂的部分，定义了「编译生成的段」如何映射到「MEMORY 块定义的物理内存」，每一个子段都对应特定的代码 / 数据类型。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flash 区：64 KiB，地址范围为 &lt;code&gt;[0x0800_0000, 0x0801_0000)&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;表中的结束地址均为区间上界，不包含在对应段内；各段之间可能因对齐要求产生填充。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;输出段或区域&lt;/th&gt;
          &lt;th&gt;起始地址&lt;/th&gt;
          &lt;th&gt;结束地址（不含）&lt;/th&gt;
          &lt;th&gt;内容&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.isr_vector&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;0x0800_0000&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ADDR(.isr_vector) + SIZEOF(.isr_vector)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;中断向量表&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.text&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;前一段结束后按 4 字节对齐&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_etext&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;程序代码以及 &lt;code&gt;.init&lt;/code&gt;、&lt;code&gt;.fini&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.rodata&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;前一段结束后按 4 字节对齐&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ADDR(.rodata) + SIZEOF(.rodata)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;只读常量和字符串&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.ARM.extab&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;前一段结束后按 4 字节对齐&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ADDR(.ARM.extab) + SIZEOF(.ARM.extab)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;ARM 栈展开信息&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.ARM&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__exidx_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__exidx_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;包含 &lt;code&gt;.ARM.exidx*&lt;/code&gt; 的栈展开索引&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.preinit_array&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__preinit_array_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__preinit_array_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;在普通初始化函数之前执行的预初始化函数数组&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.init_array&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__init_array_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__init_array_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;初始化函数数组，包含 C++ 全局对象和文件作用域静态对象的构造函数入口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.fini_array&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__fini_array_start&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;__fini_array_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;结束函数数组，包含 C++ 全局对象和文件作用域静态对象的析构函数调用入口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.data&lt;/code&gt; 初值镜像（LMA）&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sidata = LOADADDR(.data)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sidata + SIZEOF(.data)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;已初始化变量及 &lt;code&gt;.RamFunc&lt;/code&gt; 的加载镜像，复位后复制到 RAM&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;.init_array&lt;/code&gt; 在 &lt;code&gt;main&lt;/code&gt; 执行前参与 C++ 对象构造；&lt;code&gt;.fini_array&lt;/code&gt; 在程序正常退出阶段参与对象析构。裸机程序通常不会从 &lt;code&gt;main&lt;/code&gt; 返回，其析构流程是否执行取决于运行库和退出路径。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RAM 区：20 KiB，地址范围为 &lt;code&gt;[0x2000_0000, 0x2000_5000)&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;0x2000_5000&lt;/code&gt; 位于 RAM 最后一个有效地址之后，也是该链接脚本中 &lt;code&gt;_estack&lt;/code&gt; 的初始值。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;项目&lt;/th&gt;
          &lt;th&gt;地址或范围&lt;/th&gt;
          &lt;th&gt;内容与作用&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.data&lt;/code&gt;（VMA）&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sdata&lt;/code&gt; 到 &lt;code&gt;_edata&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;已初始化的全局变量、静态变量及在 RAM 中运行的 &lt;code&gt;.RamFunc&lt;/code&gt;；复位时从 Flash 的 &lt;code&gt;_sidata&lt;/code&gt; 复制&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;.bss&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;_sbss&lt;/code&gt; 到 &lt;code&gt;_ebss&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;未初始化或初始化为零的全局变量和静态变量；复位时由启动代码清零&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;_end&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;.bss&lt;/code&gt; 结束后按 8 字节对齐的位置&lt;/td&gt;
          &lt;td&gt;静态分配区域的结束标记，常作为 C 运行库堆的起点&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;._user_heap_stack&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;从 &lt;code&gt;_end&lt;/code&gt; 开始，增加 &lt;code&gt;_Min_Heap_Size&lt;/code&gt; 和 &lt;code&gt;_Min_Stack_Size&lt;/code&gt; 后按 8 字节对齐&lt;/td&gt;
          &lt;td&gt;用于链接期容量检查，不表示运行时堆和栈的固定分界&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;C 运行库堆&lt;/td&gt;
          &lt;td&gt;通常从 &lt;code&gt;_end&lt;/code&gt; 向高地址增长&lt;/td&gt;
          &lt;td&gt;供 &lt;code&gt;malloc&lt;/code&gt;、&lt;code&gt;free&lt;/code&gt; 等接口使用，实际边界由运行库实现决定&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;主栈&lt;/td&gt;
          &lt;td&gt;从 &lt;code&gt;_estack = 0x2000_5000&lt;/code&gt; 向低地址增长&lt;/td&gt;
          &lt;td&gt;MSP 的初始位置，用于函数调用、局部变量和中断现场保存&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;堆栈间可用空间&lt;/td&gt;
          &lt;td&gt;当前堆末端与当前栈指针之间&lt;/td&gt;
          &lt;td&gt;大小随程序运行动态变化；堆和栈相遇时会发生内存冲突&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;_Min_Heap_Size&lt;/code&gt; 和 &lt;code&gt;_Min_Stack_Size&lt;/code&gt; 只用于验证最小容量能否装入 RAM，并不会在运行时建立固定的堆栈边界。&lt;/p&gt;
&lt;h6 id=&#34;1isr_vector中断向量表放-flash&#34;&gt;（1）.isr_vector：中断向量表（放 FLASH）
&lt;/h6&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.isr_vector :
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);          // 地址4字节对齐（Cortex-M内核要求，否则触发硬 fault）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  KEEP(*(.isr_vector))   // 保留中断向量表，防止链接器优化删除（核心！）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;} &amp;gt;FLASH  // 分配到FLASH区域
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：存放 STM32 的中断向量表（如复位向量、定时器中断向量、串口中断向量等），是复位后内核第一个访问的段。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;KEEP(*(.isr_vector))&lt;/code&gt;&lt;/strong&gt;：中断向量表由启动文件定义（如&lt;code&gt;startup_stm32f103c8tx.s&lt;/code&gt;中的&lt;code&gt;g_pfnVectors&lt;/code&gt;数组），&lt;code&gt;KEEP&lt;/code&gt;关键字确保链接器不会因为 “看似未被调用” 而删除这个段 —— 如果删除，复位后内核找不到&lt;code&gt;Reset_Handler&lt;/code&gt;地址，程序会崩溃。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;&amp;gt;FLASH&lt;/code&gt;&lt;/strong&gt;：明确将该段分配到&lt;code&gt;MEMORY&lt;/code&gt;块定义的&lt;code&gt;FLASH&lt;/code&gt;区域（符合硬件要求，向量表默认在 FLASH 起始地址）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h6 id=&#34;2text代码段放-flash&#34;&gt;（2）.text：代码段（放 FLASH）
&lt;/h6&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.text :
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.text)           // 所有.c/.s文件的代码（如main函数、自定义函数）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.text*)          // 扩展代码段（如C++的成员函数）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.glue_7)         // ARM指令与Thumb指令的胶水代码（Cortex-M用Thumb指令，兼容用）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.glue_7t)        // 同上
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.eh_frame)       // C++异常处理相关（若用C可忽略）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  KEEP (*(.init))    // 程序初始化函数（如构造函数）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  KEEP (*(.fini))    // 程序结束函数（如析构函数）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  _etext = .;        // 定义符号：.text段的结束地址（供后续段定位）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;} &amp;gt;FLASH
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：存放所有&lt;strong&gt;可执行代码&lt;/strong&gt;（C 函数、汇编函数），是 FLASH 中占用空间最大的段。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;_etext = .&lt;/code&gt;&lt;/strong&gt;：&lt;code&gt;.&lt;/code&gt;代表当前地址，&lt;code&gt;_etext&lt;/code&gt;是全局符号，标记&lt;code&gt;.text&lt;/code&gt;段的结束地址 —— 后续的&lt;code&gt;.rodata&lt;/code&gt;段会从&lt;code&gt;_etext&lt;/code&gt;之后的地址开始分配，避免段重叠。&lt;/li&gt;
&lt;/ul&gt;
&lt;h6 id=&#34;3rodata只读常量段放-flash&#34;&gt;（3）.rodata：只读常量段（放 FLASH）
&lt;/h6&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rodata&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ALIGN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rodata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;         &lt;span class=&#34;o&#34;&gt;//&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;只读常量（如&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;、字符串常量&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rodata&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;//&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;扩展只读常量段&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ALIGN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FLASH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：存放&lt;strong&gt;只读数据&lt;/strong&gt;，因为这些数据不需要修改，放在 FLASH 中可节省 RAM 空间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;code&gt;const char str[] = &amp;quot;STM32&amp;quot;;&lt;/code&gt;会被编译到&lt;code&gt;.rodata&lt;/code&gt;段，运行时直接从 FLASH 读取，不会复制到 RAM。&lt;/li&gt;
&lt;/ul&gt;
&lt;h6 id=&#34;4armextabarmarm-架构兼容段放-flash&#34;&gt;（4）.ARM.extab/.ARM：ARM 架构兼容段（放 FLASH）
&lt;/h6&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.ARM.extab (READONLY) : 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.ARM.extab* .gnu.linkonce.armextab.*)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;} &amp;gt;FLASH
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.ARM (READONLY) : 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  __exidx_start = .;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.ARM.exidx*)     // ARM异常索引表（C++异常处理用）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  __exidx_end = .;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;} &amp;gt;FLASH
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：主要用于&lt;strong&gt;ARM 架构与 Thumb 架构的兼容&lt;/strong&gt;，以及 C++ 的异常处理（若项目用纯 C，这些段几乎为空，但保留可避免链接错误）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;READONLY&lt;/code&gt;&lt;/strong&gt;：标记为只读，与 FLASH 的权限匹配（GCC11 + 支持，低版本需删除）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h6 id=&#34;5preinit_arrayinit_arrayfini_array初始化--结束函数数组放-flash&#34;&gt;（5）.preinit_array/.init_array/.fini_array：初始化 / 结束函数数组（放 FLASH）
&lt;/h6&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.preinit_array (READONLY) : 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  PROVIDE_HIDDEN (__preinit_array_start = .);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  KEEP (*(.preinit_array*))  // 预初始化函数（如动态库预初始化）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  PROVIDE_HIDDEN (__preinit_array_end = .);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;} &amp;gt;FLASH
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.init_array (READONLY) : 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  PROVIDE_HIDDEN (__init_array_start = .);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  KEEP (*(SORT(.init_array.*)))  // 初始化函数（如C++全局对象的构造函数）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  KEEP (*(.init_array*))
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  PROVIDE_HIDDEN (__init_array_end = .);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;} &amp;gt;FLASH
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.fini_array (READONLY) : 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  PROVIDE_HIDDEN (__fini_array_start = .);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  KEEP (*(SORT(.fini_array.*)))  // 结束函数（如C++全局对象的析构函数）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  KEEP (*(.fini_array*))
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  PROVIDE_HIDDEN (__fini_array_end = .);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;} &amp;gt;FLASH
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：存放程序启动 / 退出时自动执行的函数数组（主要用于 C++），例如：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;init_array&lt;/code&gt;：&lt;code&gt;main&lt;/code&gt;函数执行前，会自动调用这里的函数（如全局对象&lt;code&gt;A a;&lt;/code&gt;的构造函数）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fini_array&lt;/code&gt;：&lt;code&gt;main&lt;/code&gt;函数退出后，会自动调用这里的函数（如全局对象的析构函数）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;PROVIDE_HIDDEN&lt;/code&gt;&lt;/strong&gt;：若用户代码未定义&lt;code&gt;__init_array_start&lt;/code&gt;等符号，链接器自动提供（隐藏符号，避免冲突）；&lt;code&gt;KEEP&lt;/code&gt;确保这些段不被优化删除。&lt;/li&gt;
&lt;/ul&gt;
&lt;h6 id=&#34;6data初始化数据段放-ram加载地址在-flash&#34;&gt;（6）.data：初始化数据段（放 RAM，加载地址在 FLASH）
&lt;/h6&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/* used by the startup to initialize data */
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;_sidata = LOADADDR(.data);  // 定义符号：.data在FLASH的加载地址（LMA）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.data :
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  _sdata = .;        // 定义符号：.data在RAM的运行地址（VMA）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.data)           // 初始化的全局/静态变量（如int a = 10;）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.data*)          // 扩展初始化数据段
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.RamFunc)        // 要放到RAM中执行的函数（如某些快速中断处理函数）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.RamFunc*)       // 同上
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  _edata = .;        // 定义符号：.data在RAM的结束地址
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;} &amp;gt;RAM AT&amp;gt; FLASH  // 运行地址（VMA）在RAM，加载地址（LMA）在FLASH
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;核心概念&lt;/strong&gt;：&lt;code&gt;VMA&lt;/code&gt;（虚拟 / 运行地址）和&lt;code&gt;LMA&lt;/code&gt;（加载地址）：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;gt;RAM&lt;/code&gt;：&lt;code&gt;.data&lt;/code&gt;段的&lt;strong&gt;运行地址（VMA）&lt;/strong&gt; 在 RAM（因为变量需要读写）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AT&amp;gt;FLASH&lt;/code&gt;：&lt;code&gt;.data&lt;/code&gt;段的&lt;strong&gt;加载地址（LMA）&lt;/strong&gt; 在 FLASH（编译时将变量初始值存到 FLASH，节省 RAM）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;与启动流程关联&lt;/strong&gt;：启动文件的&lt;code&gt;Reset_Handler&lt;/code&gt;会从&lt;code&gt;_sidata&lt;/code&gt;（FLASH 的 LMA）复制数据到&lt;code&gt;_sdata&lt;/code&gt;（RAM 的 VMA），直到&lt;code&gt;_edata&lt;/code&gt;—— 这就是 “初始化.data 段” 的具体实现。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;.RamFunc&lt;/code&gt;&lt;/strong&gt;：某些对执行速度要求高的函数（如高频中断服务函数），可通过&lt;code&gt;__attribute__((section(&amp;quot;.RamFunc&amp;quot;)))&lt;/code&gt;标记，链接时会放到 RAM 中执行（RAM 访问速度比 FLASH 快）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h6 id=&#34;7bss未初始化数据段放-ram&#34;&gt;（7）.bss：未初始化数据段（放 RAM）
&lt;/h6&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.bss :
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  _sbss = .;         // 定义符号：.bss在RAM的起始地址
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  __bss_start__ = _sbss;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.bss)            // 未初始化的全局/静态变量（如int b;）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(.bss*)           // 扩展未初始化数据段
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  *(COMMON)          // 未初始化的全局变量（如extern int c;）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(4);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  _ebss = .;         // 定义符号：.bss在RAM的结束地址
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  __bss_end__ = _ebss;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;} &amp;gt;RAM
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：存放&lt;strong&gt;未初始化的全局 / 静态变量&lt;/strong&gt;，C 语言标准要求这些变量初始化为 0，因此不需要在 FLASH 中存储初始值（节省 FLASH 空间）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;与启动流程关联&lt;/strong&gt;：启动文件的&lt;code&gt;Reset_Handler&lt;/code&gt;会将&lt;code&gt;_sbss&lt;/code&gt;到&lt;code&gt;_ebss&lt;/code&gt;的 RAM 区域清零 —— 这就是 “清零.bss 段” 的具体实现。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;COMMON&lt;/code&gt;&lt;/strong&gt;：对应未声明但外部引用的全局变量（如&lt;code&gt;extern int c;&lt;/code&gt;），链接时会分配到.bss 段。&lt;/li&gt;
&lt;/ul&gt;
&lt;h6 id=&#34;8_user_heap_stack堆和栈的占位段放-ram&#34;&gt;（8）._user_heap_stack：堆和栈的占位段（放 RAM）
&lt;/h6&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;._user_heap_stack :
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(8);      // 8字节对齐（堆/栈通常要求更高对齐，避免内存访问错误）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  PROVIDE ( end = . );    // 定义符号：RAM已分配区域的结束地址
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  PROVIDE ( _end = . );
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = . + _Min_Heap_Size; // 堆区域：从当前地址分配_Min_Heap_Size大小
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = . + _Min_Stack_Size;// 栈区域：在堆之后分配_Min_Stack_Size大小
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  . = ALIGN(8);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;} &amp;gt;RAM
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：为堆和栈预留空间，并检查 RAM 是否足够 —— 若堆 + 栈 + 已分配段（.data+.bss）的总大小超过 RAM 容量，链接器会报错。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;end&lt;/code&gt;/&lt;code&gt;_end&lt;/code&gt;&lt;/strong&gt;：标记 RAM 中 “已分配段（.data+.bss）” 的结束地址，堆从&lt;code&gt;end&lt;/code&gt;开始向上生长，栈从&lt;code&gt;_estack&lt;/code&gt;（栈顶）开始向下生长。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;堆 / 栈生长方向&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;堆：从&lt;code&gt;end&lt;/code&gt;向上（地址增大方向）生长，供&lt;code&gt;malloc&lt;/code&gt;/&lt;code&gt;free&lt;/code&gt;使用。&lt;/li&gt;
&lt;li&gt;栈：从&lt;code&gt;_estack&lt;/code&gt;向下（地址减小方向）生长，供函数调用、局部变量使用。&lt;/li&gt;
&lt;li&gt;若堆和栈生长时重叠，会导致内存溢出（硬 fault），因此需合理设置&lt;code&gt;_Min_Heap_Size&lt;/code&gt;和&lt;code&gt;_Min_Stack_Size&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-RAM%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83-1.png&#34;
	width=&#34;1269&#34;
	height=&#34;674&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-RAM%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83-1_hu13448359514406145975.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-RAM%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83-1_hu250755568266859443.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;188&#34;
		data-flex-basis=&#34;451px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;如果使用了FreeRTOS的话，FreeRTOS的内存布局如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-FreeRTOS%E7%9A%84%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80.png&#34;
	width=&#34;1038&#34;
	height=&#34;695&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-FreeRTOS%E7%9A%84%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80_hu6082313860412554675.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-FreeRTOS%E7%9A%84%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80_hu14391524076225901871.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;149&#34;
		data-flex-basis=&#34;358px&#34;
	
&gt;&lt;/p&gt;
&lt;h6 id=&#34;9discard丢弃无用段减小可执行文件大小&#34;&gt;（9）/DISCARD/：丢弃无用段（减小可执行文件大小）
&lt;/h6&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/DISCARD/ :
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  libc.a ( * )    // 丢弃标准C库的所有段
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  libm.a ( * )    // 丢弃标准数学库的所有段
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  libgcc.a ( * )  // 丢弃GCC编译器库的所有段
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：嵌入式系统通常不需要标准库的完整功能（如&lt;code&gt;printf&lt;/code&gt;的文件输出、&lt;code&gt;malloc&lt;/code&gt;的复杂内存管理），丢弃这些段可大幅减小&lt;code&gt;.elf&lt;/code&gt;/&lt;code&gt;.hex&lt;/code&gt;文件的大小。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注意&lt;/strong&gt;：若项目需要使用标准库功能（如&lt;code&gt;printf&lt;/code&gt;、&lt;code&gt;sqrt&lt;/code&gt;），需删除对应行，否则会出现 “未定义引用” 错误（需搭配&lt;code&gt;newlib-nano&lt;/code&gt;等嵌入式精简库）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;四总结启动流程与ld-文件的关联&#34;&gt;四、总结：启动流程与.ld 文件的关联
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;硬件复位&lt;/strong&gt; → 内核读取&lt;code&gt;FLASH&lt;/code&gt;起始地址（&lt;code&gt;0x8000000&lt;/code&gt;）的&lt;code&gt;.isr_vector&lt;/code&gt;段 → 找到&lt;code&gt;Reset_Handler&lt;/code&gt;地址。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行&lt;code&gt;Reset_Handler&lt;/code&gt;&lt;/strong&gt; → 利用&lt;code&gt;.ld&lt;/code&gt;定义的&lt;code&gt;_sdata&lt;/code&gt;/&lt;code&gt;_sidata&lt;/code&gt;/&lt;code&gt;_edata&lt;/code&gt;复制&lt;code&gt;.data&lt;/code&gt;段 → 利用&lt;code&gt;_sbss&lt;/code&gt;/&lt;code&gt;_ebss&lt;/code&gt;清零&lt;code&gt;.bss&lt;/code&gt;段。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;调用&lt;code&gt;main&lt;/code&gt;&lt;/strong&gt; → 用户代码中的变量（.data/.bss）已在 RAM 中初始化，函数（.text）在 FLASH 中执行，堆 / 栈在 RAM 中预留空间。
可以说：&lt;strong&gt;.ld 文件是 STM32 启动流程的 “地图”&lt;/strong&gt;，没有它，启动文件不知道如何初始化内存，链接器不知道如何分配代码和数据，程序无法正常运行。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;寄存器&#34;&gt;寄存器
&lt;/h2&gt;
&lt;p&gt;认识一个&lt;code&gt;CPU&lt;/code&gt;最直接的是去认识它的寄存器组
（Register bank）
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-Cortex-M%E7%9A%84%E5%86%85%E6%A0%B8%E6%A1%86%E5%9B%BE.png&#34;
	width=&#34;790&#34;
	height=&#34;457&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-Cortex-M%E7%9A%84%E5%86%85%E6%A0%B8%E6%A1%86%E5%9B%BE_hu2536946228529719192.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-Cortex-M%E7%9A%84%E5%86%85%E6%A0%B8%E6%A1%86%E5%9B%BE_hu15969040657550120430.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;172&#34;
		data-flex-basis=&#34;414px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;arm&lt;/code&gt;系统寄存器组&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-arm%E6%9E%B6%E6%9E%84%E5%AF%84%E5%AD%98%E5%99%A8.png&#34;
	width=&#34;532&#34;
	height=&#34;521&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-arm%E6%9E%B6%E6%9E%84%E5%AF%84%E5%AD%98%E5%99%A8_hu12295166982903513917.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-arm%E6%9E%B6%E6%9E%84%E5%AF%84%E5%AD%98%E5%99%A8_hu7556102674944354891.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;102&#34;
		data-flex-basis=&#34;245px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;还有5个特殊寄存器&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%89%B9%E6%AE%8A%E5%AF%84%E5%AD%98%E5%99%A8.png&#34;
	width=&#34;411&#34;
	height=&#34;382&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%89%B9%E6%AE%8A%E5%AF%84%E5%AD%98%E5%99%A8_hu2585720261492038434.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%89%B9%E6%AE%8A%E5%AF%84%E5%AD%98%E5%99%A8_hu16730692858137438873.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;107&#34;
		data-flex-basis=&#34;258px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;浮点数寄存器&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-arm%E6%B5%AE%E7%82%B9%E6%95%B0%E5%AF%84%E5%AD%98%E5%99%A8.png&#34;
	width=&#34;615&#34;
	height=&#34;752&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-arm%E6%B5%AE%E7%82%B9%E6%95%B0%E5%AF%84%E5%AD%98%E5%99%A8_hu3518435444834283096.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-arm%E6%B5%AE%E7%82%B9%E6%95%B0%E5%AF%84%E5%AD%98%E5%99%A8_hu8231920671927945409.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;81&#34;
		data-flex-basis=&#34;196px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;通用寄存器&#34;&gt;通用寄存器
&lt;/h3&gt;
&lt;p&gt;通用寄存器通用性强，常用于存储临时的数据
其中&lt;code&gt;R0-R7&lt;/code&gt;是低组寄存器，&lt;code&gt;R8-R12&lt;/code&gt;是高组寄存器，高组寄存器部分指令无法访问&lt;/p&gt;
&lt;h3 id=&#34;pc程序计数器程序如何跑起来&#34;&gt;PC程序计数器&amp;amp;程序如何跑起来
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;arm&lt;/code&gt;架构中的&lt;code&gt;R15&lt;/code&gt;寄存器，是程序计数器（program counter），该寄存器可读可写&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;arm cortex-M&lt;/code&gt;的&lt;code&gt;CPU&lt;/code&gt;内，每一次&lt;code&gt;PC&lt;/code&gt;自增4（即向下移动了4个字节），但是在使用&lt;code&gt;thumb&lt;/code&gt;指令集时，&lt;code&gt;thumb&lt;/code&gt;指令集的部分指令是2个字节，这与处理器的执行流水线&lt;code&gt;pipeline&lt;/code&gt;的特性有关，实际取址的时候是一次去4字节，也就是对于2字节的指令是一次取两条&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CPU&lt;/code&gt;在不断执行程序，本质就是程序计数器的不断更新，&lt;code&gt;PC&lt;/code&gt;指向的就是当前要执行的指令的地址&lt;/p&gt;
&lt;h3 id=&#34;堆栈指针双堆栈指针机制&#34;&gt;堆栈指针&amp;amp;双堆栈指针机制
&lt;/h3&gt;
&lt;p&gt;栈是高址向低址方向生长，堆是低址向高址方向生长&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E5%A0%86%E6%A0%88.png&#34;
	width=&#34;333&#34;
	height=&#34;305&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E5%A0%86%E6%A0%88_hu16187981557609348171.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E5%A0%86%E6%A0%88_hu16680403190437700509.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;109&#34;
		data-flex-basis=&#34;262px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;arm cortex-M&lt;/code&gt;架构中&lt;code&gt;R13&lt;/code&gt;是堆栈指针寄存器
在物理上该寄存器是两个不同的寄存器&lt;code&gt;MSP&lt;/code&gt;主堆栈指针和&lt;code&gt;PSP&lt;/code&gt;进程堆栈指针，在程序运行时选用哪一个寄存器会有&lt;code&gt;Control&lt;/code&gt;控制寄存器的值来决定&lt;/p&gt;
&lt;p&gt;默认启动时，处理器使用的是主堆栈指针，可以修改&lt;code&gt;Control&lt;/code&gt;控制寄存器的第一位的值来修改处理器使用的堆栈指针&lt;/p&gt;
&lt;p&gt;双堆栈指针-&lt;code&gt;MSP&lt;/code&gt;主堆栈指针，&lt;code&gt;PSP&lt;/code&gt;进程堆栈指针
可以用来实现隔离系统内核和应用程序任务&lt;/p&gt;
&lt;h3 id=&#34;lr链接寄存器函数调用的本质&#34;&gt;LR链接寄存器&amp;amp;函数调用的本质
&lt;/h3&gt;
&lt;p&gt;函数调用的本质是&lt;strong&gt;程序执行流的动态转移与上下文管理&lt;/strong&gt;，其核心在于通过 栈 来实现代码模块化执行和状态的保存与恢复&lt;/p&gt;
&lt;p&gt;&lt;code&gt;arm&lt;/code&gt;架构的&lt;code&gt;CPU&lt;/code&gt;有专门设立一个寄存器&lt;code&gt;R14(link register)&lt;/code&gt;，用于存放子函数的返回地址&lt;/p&gt;
&lt;p&gt;以&lt;code&gt;arm&lt;/code&gt;的&lt;code&gt;bl&lt;/code&gt;指令为例（用于函数调用）
&lt;code&gt;bl &amp;lt;label&amp;gt;&lt;/code&gt;是跳转到标签地址，同时将返回地址存入&lt;code&gt;LR&lt;/code&gt;寄存器&lt;/p&gt;
&lt;p&gt;需要注意的是，&lt;code&gt;arm cortex-M&lt;/code&gt;架构的处理器指令都是半字对齐（两字节对齐），所以其反汇编的地址都是偶数，存在&lt;code&gt;lr&lt;/code&gt;寄存器的返回地址也都是偶数，但是&lt;code&gt;lr&lt;/code&gt;寄存器的第0位必须设置为1来指示&lt;code&gt;thumb&lt;/code&gt;指令集的状态，所以&lt;code&gt;lr&lt;/code&gt;寄存器的值会是&lt;code&gt;返回地址+1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;在多级函数调用时，&lt;code&gt;lr&lt;/code&gt;寄存器的值会被压入栈中&lt;/p&gt;
&lt;p&gt;另外&lt;code&gt;lr&lt;/code&gt;寄存器还能记录异常返回值。当处理器进入中断时，链接寄存器会更新为异常返回值，用来实现异常返回机制，用来记录区分一些工作模式现场，这些信息是恢复中断上下文需要的&lt;/p&gt;
&lt;h2 id=&#34;地址分配&#34;&gt;地址分配
&lt;/h2&gt;
&lt;h3 id=&#34;存储器系统&#34;&gt;存储器系统
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;cortex-M&lt;/code&gt;处理器是32位地址，因此会有
4&lt;code&gt;GB&lt;/code&gt;的地址空间，所有的指令和数据通过这个地址访问&lt;/p&gt;
&lt;p&gt;硬件资源都是通过地址映射的方式访问
另外&lt;code&gt;cortex-M&lt;/code&gt;架构没有设置&lt;code&gt;MMU&lt;/code&gt;内存管理单元，所以没有&lt;code&gt;MMU&lt;/code&gt;内存管理单元，一般也不会搭载&lt;code&gt;Linux,Windows&lt;/code&gt;这种通用类型的系统&lt;/p&gt;
&lt;p&gt;&lt;code&gt;地址映射图&lt;/code&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84.png&#34;
	width=&#34;790&#34;
	height=&#34;567&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84_hu9295500705439601579.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84_hu7291421710444432392.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;139&#34;
		data-flex-basis=&#34;334px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;F103C8的地址映射图&lt;/code&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-f103c8%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84%E5%9B%BE.png&#34;
	width=&#34;798&#34;
	height=&#34;1104&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-f103c8%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84%E5%9B%BE_hu7833596306396871614.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-f103c8%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84%E5%9B%BE_hu16908648889634145177.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;72&#34;
		data-flex-basis=&#34;173px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;系统架构图&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-cortex-M3M4%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84.png&#34;
	width=&#34;650&#34;
	height=&#34;515&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-cortex-M3M4%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84_hu11818484246865093855.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-cortex-M3M4%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84_hu15492943948597689706.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;126&#34;
		data-flex-basis=&#34;302px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cortex-M3M4内核架构图&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-cortex-M3M4%E5%86%85%E6%A0%B8.png&#34;
	width=&#34;619&#34;
	height=&#34;381&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-cortex-M3M4%E5%86%85%E6%A0%B8_hu1376430579139473456.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-cortex-M3M4%E5%86%85%E6%A0%B8_hu9245358393590328398.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;162&#34;
		data-flex-basis=&#34;389px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;三级流水线外的设备属于&lt;code&gt;CPU&lt;/code&gt;的内核外设，例如&lt;code&gt;NVIC&lt;/code&gt;,&lt;code&gt;SysTick&lt;/code&gt;系统滴答定时器，&lt;code&gt;MPU&lt;/code&gt;等，用&lt;code&gt;0xE004 0000-0xE00F F000&lt;/code&gt;地址访问&lt;/p&gt;
&lt;p&gt;软件上就是通过读写外设地址空间来控制这些外设，对应的地址空间单元映射到外设寄存器&lt;/p&gt;
&lt;p&gt;嵌入式编程本质就是在操作存储器，每一段&lt;code&gt;CPU&lt;/code&gt;代码指令都是在读取某个地址空间的单元，高级编程语言就是不断向上封装抽象&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C&lt;/code&gt;语言每条语句追溯到汇编都是在读写存储器的地址空间单元
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%AE%80%E5%8C%96%E5%9B%BE.png&#34;
	width=&#34;920&#34;
	height=&#34;375&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%AE%80%E5%8C%96%E5%9B%BE_hu3667266801560343470.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E7%AE%80%E5%8C%96%E5%9B%BE_hu8319569534823074497.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;245&#34;
		data-flex-basis=&#34;588px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;关于内存和编译优化&#34;&gt;关于内存和编译优化
&lt;/h3&gt;
&lt;p&gt;指针是内存地址的容器
关于&lt;code&gt;i++&lt;/code&gt;与&lt;code&gt;++i&lt;/code&gt;执行效率的问题，在&lt;code&gt;O0&lt;/code&gt;优化的情况下，不同编译器的具体实现是不一样的，执行效率是不能直接比较的&lt;/p&gt;
&lt;p&gt;编译优化会使汇编的指令在执行速度上提高，例如会使用&lt;code&gt;mov&lt;/code&gt;去代替&lt;code&gt;ldr&lt;/code&gt;，或者将一些简单的函数改为内嵌，以减少函数调用带来的开销&lt;/p&gt;
&lt;h2 id=&#34;中断&#34;&gt;中断
&lt;/h2&gt;
&lt;p&gt;在微机原理中已有涉及，后面只做简单回顾用&lt;/p&gt;
&lt;h3 id=&#34;关于中断&#34;&gt;关于中断
&lt;/h3&gt;
&lt;p&gt;中断的事件一般由硬件触发（实际有硬中断和软中断），会改变程序执行流&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E4%B8%AD%E6%96%AD%E7%9A%84%E6%A1%86%E6%9E%B6.png&#34;
	width=&#34;604&#34;
	height=&#34;308&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E4%B8%AD%E6%96%AD%E7%9A%84%E6%A1%86%E6%9E%B6_hu10756980578003421082.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E4%B8%AD%E6%96%AD%E7%9A%84%E6%A1%86%E6%9E%B6_hu18416676295983188224.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;196&#34;
		data-flex-basis=&#34;470px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;NVIC&lt;/code&gt;属于内核外设，专门管理中断&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;cortex-M&lt;/code&gt;芯片中，前15项中断向量都一样&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E4%B8%AD%E6%96%AD%E5%90%91%E9%87%8F%E8%A1%A8.png&#34;
	width=&#34;386&#34;
	height=&#34;509&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E4%B8%AD%E6%96%AD%E5%90%91%E9%87%8F%E8%A1%A8_hu6449595849150010522.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E4%B8%AD%E6%96%AD%E5%90%91%E9%87%8F%E8%A1%A8_hu2482380903259567589.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;75&#34;
		data-flex-basis=&#34;182px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;处理器具有向量表重定位功能，通过向量表偏移寄存器(&lt;code&gt;VTOR&lt;/code&gt;)来获取向量表的起始地址&lt;/p&gt;
&lt;p&gt;中断触发时，处理器通过中断向量表去获取中断处理函数的入口地址&lt;/p&gt;
&lt;h3 id=&#34;中断返回中断上下文&#34;&gt;中断返回&amp;amp;中断上下文
&lt;/h3&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.bilibili.com/video/BV1PwpgzGEmV/?vd_source=5a0790755035f26a67935abfbfcdfd5b&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;电脑为什么能边玩游戏边聊天？CPU这个骚操作，99%的程序员都说不清！| CPU / 多任务 / 进程上下文 / 中断机制_哔哩哔哩_bilibili&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;该视频中最后讲解的就类似于&lt;code&gt;arm&lt;/code&gt;架构采用的方式&lt;/p&gt;
&lt;p&gt;在阅读中断的汇编时，会发现中断没有保存和恢复上下文的代码，实际上是硬件帮忙实现上述功能&lt;/p&gt;
&lt;p&gt;关于上下文，如程序上的函数调用需要保存上下文，在操作系统中需要处理线程上下文（任务上下文），其本质都在于保存和恢复若干寄存器的值&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-cortex-M3M4%E4%B8%AD%E6%96%AD%E4%BF%9D%E5%AD%98%E4%B8%8A%E4%B8%8B%E6%96%87.png&#34;
	width=&#34;622&#34;
	height=&#34;287&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-cortex-M3M4%E4%B8%AD%E6%96%AD%E4%BF%9D%E5%AD%98%E4%B8%8A%E4%B8%8B%E6%96%87_hu9991126449488417769.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-cortex-M3M4%E4%B8%AD%E6%96%AD%E4%BF%9D%E5%AD%98%E4%B8%8A%E4%B8%8B%E6%96%87_hu8903719563909650552.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;216&#34;
		data-flex-basis=&#34;520px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cortex-M3M4&lt;/code&gt;中断需要入栈保存上下文的8个寄存器
选择保存上述8个寄存器主要是根据&lt;code&gt;arm&lt;/code&gt;架构的过程调用标准，&lt;code&gt;C&lt;/code&gt;语言的函数实现会改动这些寄存器，为例能让&lt;code&gt;C&lt;/code&gt;函数能作为异常（中断）处理函数，中断（异常）机制需要能自动地保存这些寄存器，这些寄存器也被称之为调用者保存寄存器&lt;/p&gt;
&lt;p&gt;处理器恢复上下文，回到原执行流，需要&lt;code&gt;lr&lt;/code&gt;寄存器存储异常返回值来记录区分一些工作模式现场，这些信息是恢复中断上下文需要的&lt;/p&gt;
&lt;h2 id=&#34;错误处理&#34;&gt;错误处理
&lt;/h2&gt;
&lt;p&gt;介绍&lt;code&gt;arm cortex-M&lt;/code&gt;处理器架构如何捕获和记录错误故障&lt;/p&gt;
&lt;p&gt;有专门的寄存器去记录故障，通过查找其对应的地址查看寄存器的位来获取错误信息&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E6%95%85%E9%9A%9C%E8%AE%B0%E5%BD%95%E5%AF%84%E5%AD%98%E5%99%A8.png&#34;
	width=&#34;635&#34;
	height=&#34;382&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E6%95%85%E9%9A%9C%E8%AE%B0%E5%BD%95%E5%AF%84%E5%AD%98%E5%99%A8_hu18224593236508536412.png 480w, https://NomadJoeviolet.github.io/p/%E4%BB%8Ecpu%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0/%E4%BB%8ECPU%E6%9E%B6%E6%9E%84%E5%88%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E7%8E%B0-%E6%95%85%E9%9A%9C%E8%AE%B0%E5%BD%95%E5%AF%84%E5%AD%98%E5%99%A8_hu17222364446200839070.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;166&#34;
		data-flex-basis=&#34;398px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;在发生错误时，对应错误寄存器的对应位被置1，同时触发错误中断处理&lt;/p&gt;
&lt;p&gt;程序执行非法指令操作导致系统进入不可恢复的故障状态，系统软件就会介入终止程序执行流，其实现机制是中断&lt;/p&gt;
&lt;h2 id=&#34;待续&#34;&gt;待续
&lt;/h2&gt;
</description>
        </item>
        <item>
        <title>工具链的一些杂知识</title>
        <link>https://NomadJoeviolet.github.io/p/%E5%B7%A5%E5%85%B7%E9%93%BE%E7%9A%84%E4%B8%80%E4%BA%9B%E6%9D%82%E7%9F%A5%E8%AF%86/</link>
        <pubDate>Thu, 26 Jun 2025 15:21:07 +0800</pubDate>
        
        <guid>https://NomadJoeviolet.github.io/p/%E5%B7%A5%E5%85%B7%E9%93%BE%E7%9A%84%E4%B8%80%E4%BA%9B%E6%9D%82%E7%9F%A5%E8%AF%86/</guid>
        <description>&lt;h4 id=&#34;mdk介绍及其使用&#34;&gt;MDK介绍及其使用
&lt;/h4&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/yychuyu/article/details/134980173&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;一文教你使用MDK开发工具-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;MDK、KEIL、uVision 之间的区别&lt;/p&gt;
&lt;p&gt;MDK（ Microcontroller Development Kit ），也称 MDK-ARM 、KEIL MDK、KEIL For ARM，都是同一个东西。ARM 公司现在统一使用 MDK-ARM 的称呼，MDK 的设备数据库中有很多厂商的芯片，是专为微控制器开发的一款工具，为满足基于 MCU 进行嵌入式软件开发的工程师需求而设计，支持 ARM7，ARM9，Cortex-M4/M3/M1，Cortex-R0/R3/R4 等 ARM 微控制器内核。KEIL 是公司的名称，有时候也指 KEIL 公司的所有软件开发工具。Keil 公司在2005年被 ARM 公司收购。&lt;/p&gt;
&lt;p&gt;uVision 是 KEIL 公司开发的一个集成开发环境（IDE）。它包括工程管理，源代码编辑，编译设置，下载调试和模拟仿真等功能，uVision 有 uVision2、uVision3、uVision4 和 uVision5 四个版本，目前最新的版本是 uVision5。它提供一个环境，让开发者易于操作。uVision 通用于 KEIL 的开发工具中，例如 MDK，PK51，PK166，DK251等。&lt;/p&gt;
&lt;h4 id=&#34;armclang&#34;&gt;armclang
&lt;/h4&gt;
&lt;p&gt;就是俗称的AC6
armclang是ARM公司提供的一款C/C++编译器，专门用于为ARM架构的处理器生成高性能代码。该编译器通常与ARM的其他工具链一起使用，适合嵌入式系统开发。&lt;/p&gt;
&lt;p&gt;请注意，确保在项目中使用合适的工具和版本，并根据需求查阅最新的文档。&lt;/p&gt;
&lt;h4 id=&#34;openocd&#34;&gt;OpenOCD
&lt;/h4&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/41517198&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;跟我一起学OpenOCD(一) - 知乎 (zhihu.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;OpenOCD是一个开源的调试/编程工具，主要用于嵌入式系统，它支持多种硬件设备和调试协议，如JTAG和SWD。它通常与GNU工具链结合使用，可以为开发人员提供硬件调试和烧录固件的功能。&lt;/p&gt;
&lt;h4 id=&#34;ozone&#34;&gt;Ozone
&lt;/h4&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.armbbs.cn/forum.php?mod=viewthread&amp;amp;tid=95855&amp;amp;highlight=Ozone&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ozone使用介绍-基础功能 - 开发环境 - 硬汉嵌入式论坛 - Powered by Discuz! (armbbs.cn)&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;mingw&#34;&gt;MinGW
&lt;/h4&gt;
&lt;p&gt;mingw 是一个为 Microsoft Windows 平台编译和运行 Unix 程序的工具套装，它提供了类似于 Unix 环境下的编译器、链接器等工具，以便在 Windows 平台上开发使用 GCC（GNU 编译器集合）和其他开源 Unix 工具的软件。&lt;/p&gt;
&lt;h4 id=&#34;llvm&#34;&gt;LLVM
&lt;/h4&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/140462815&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;LLVM基本概念入门 - 知乎&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;来自于百度百科的解释&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LLVM 命名最早源自于底层虚拟机（Low Level Virtual Machine）的缩写，由于命名带来的混乱，LLVM就是该项目的全称。LLVM 核心库提供了与编译器相关的支持，可以作为多种语言编译器的后台来使用。能够进行程序语言的编译器优化、链接优化、在线编译优化、代码生成。LLVM的项目是一个模块化和可重复使用的编译器和工具技术的集合。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;现在的LLVM是一个编译器框架。LLVM作为编译器框架，是需要各种功能模块支撑起来的，你可以将clang和lld都看做是LLVM的组成部分，框架的意思是，你可以基于LLVM提供的功能开发自己的模块，并集成在LLVM系统上，增加它的功能，或者就单纯自己开发软件工具，而利用LLVM来支撑底层实现。LLVM由一些库和工具组成，正因为它的这种设计思想，使它可以很容易和IDE集成（因为IDE软件可以直接调用库来实现一些如静态检查这些功能），也很容易构建生成各种功能的工具（因为新的工具只需要调用需要的库就行）&lt;/p&gt;
&lt;h4 id=&#34;arm-none-eabi-gcc&#34;&gt;arm-none-eabi-gcc
&lt;/h4&gt;
&lt;p&gt;arm-none-eabi-gcc 是一个专为 ARM 架构的嵌入式系统设计的 GCC 编译器版本。它可以生成裸机代码，适用于没有操作系统的应用程序。开发者常用它来编译针对 ARM Cortex 和其他 ARM 设备的软件。&lt;/p&gt;
&lt;h4 id=&#34;arm-none-eabi-gcc和armclang的区别&#34;&gt;arm-none-eabi-gcc 和 armclang的区别
&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;arm-none-eabi-gcc&lt;/code&gt; 和 &lt;code&gt;armclang&lt;/code&gt; 是两种不同的编译工具链，主要用于嵌入式系统中基于 ARM 处理器的代码编译。它们之间存在一些关键的区别，以下是它们各自的特点及区别的简要概述：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;开发者和背景&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;arm-none-eabi-gcc&lt;/strong&gt;: 是 GNU 编译器集合（GCC）的一个变体，专门用于 ARM 处理器。这个工具链是开源的，由 GNU 项目支持。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;armclang&lt;/strong&gt;: 是 ARM 公司推出的编译器，属于 ARM Compiler 工具链的一部分。ARM Compiler 6及更高版本基于开源的 LLVM/Clang 技术，但包含许多 ARM 提供的专有优化和扩展。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;编译技术和优化&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;arm-none-eabi-gcc&lt;/strong&gt;: 利用 GCC 的优化技术，提供了广泛的架构支持和成熟的优化方法。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;armclang&lt;/strong&gt;: 使用 LLVM 编译技术框架，通常提供更现代的优化策略和更好的代码生成质量，尤其是在 C++ 的高级特性支持方面。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;语言支持&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;两者都支持主要的编程语言如 C 和 C++。但是，由于 ARM Compiler 包括来自 LLVM/Clang 的优势，armclang 可能在支持最新 C++ 标准方面有更好的表现。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;调试和错误信息&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;armclang&lt;/strong&gt; 通常提供更详细的错误和警告信息，这可以使调试过程更加高效。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;arm-none-eabi-gcc&lt;/strong&gt; 的错误信息较为传统，但由于广泛使用，网上有大量关于其调试的资源和社区支持。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;生态系统和集成&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;arm-none-eabi-gcc&lt;/strong&gt; 由于是开源和免费，被广泛应用于多种开发环境和项目中。其生态系统非常成熟，有大量的第三方库和工具支持。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;armclang&lt;/strong&gt; 尽管集成了许多 ARM 特定的优化，但作为商业产品，可能在使用上不如 GCC 灵活，特别是在版权和许可证管理方面。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;性能&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;性能比较并不绝对，依赖于具体的应用场景和代码特性。在某些情况下，armclang 生成的代码运行效率更高，而在其他情况下，arm-none-eabi-gcc 可能表现得更好。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在选择哪一个编译器进行项目开发时，需要考虑多个因素，如团队的熟悉度、项目需求对优化的依赖程度、成本（尤其是 armclang 可能涉及的许可成本）以及与其他工具的兼容性等。&lt;/p&gt;
&lt;h4 id=&#34;clangd&#34;&gt;clangd
&lt;/h4&gt;
&lt;p&gt;clangd是llvm项目推出的C++语言服务器，通过LSP(Language Server Protocal)协议向编辑器如vscode/vim/emacs提供语法补全、错误检测、跳转、格式化等等功能。C++的LSP曾经是&lt;a class=&#34;link&#34; href=&#34;https://zhida.zhihu.com/search?content_id=214022597&amp;amp;content_type=Article&amp;amp;match_order=1&amp;amp;q=cquery&amp;amp;zhida_source=entity&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;cquery&lt;/a&gt;, ccls, clangd三足鼎立。但是clangd支持clang-tidy实时检查的功能是另外两者不具备的，而且cquery和ccls都是单个开发者主导的项目，clangd背后则是有llvm的背书。目前来看，“姓赵”的clangd在这场c++ lsp赛跑中已经有了不小的领先优势。&lt;/p&gt;
&lt;h4 id=&#34;vscode的intellisense&#34;&gt;VScode的IntelliSense
&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;IntelliSense 是 VS Code 提供的智能代码补全和理解功能&lt;/strong&gt;，它结合了代码补全、参数信息、快速信息和成员列表等功能，极大地提高了开发效率。&lt;/p&gt;
&lt;p&gt;IntelliSense 的核心组成&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;代码补全 (Code Completion)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;输入时自动显示建议列表&lt;/li&gt;
&lt;li&gt;包含变量、函数、类、方法等&lt;/li&gt;
&lt;li&gt;支持模糊匹配 (如输入 &lt;code&gt;fs.rm&lt;/code&gt; 可匹配 &lt;code&gt;fs.rmdir&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;参数提示 (Parameter Hints)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;显示函数参数信息&lt;/li&gt;
&lt;li&gt;当前参数位置高亮显示&lt;/li&gt;
&lt;li&gt;函数重载时可通过箭头切换&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;快速信息 (Quick Info)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;悬停时显示符号定义&lt;/li&gt;
&lt;li&gt;包含文档注释、类型信息等&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误检查 (Error Checking)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;实时语法检查&lt;/li&gt;
&lt;li&gt;类型错误检测&lt;/li&gt;
&lt;li&gt;未定义符号提示&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&#34;intellisense-的工作原理&#34;&gt;IntelliSense 的工作原理
&lt;/h5&gt;
&lt;p&gt;VS Code 通过以下方式提供 IntelliSense：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;基于词法分析&lt;/strong&gt;：简单的文本匹配补全&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;基于语言服务器协议 (LSP)&lt;/strong&gt;：通过语言服务器获取深度分析&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;基于 TypeScript/JavaScript 的 TS Server&lt;/strong&gt;：专为 JS/TS 优化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;基于标签 (Tag Parser)&lt;/strong&gt;：如 C/C++ 扩展使用的方案&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;交叉编译器&#34;&gt;交叉编译器
&lt;/h4&gt;
&lt;p&gt;在一种计算机环境中运行的编译程序，能编译出在另外一种环境下运行的代码，这个编译过程就叫交叉编译.简单地说，就是在一个平台上生成另一个平台上的可执行代码&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/133779123&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;arm 交叉编译器各种gcc 傻傻分不清楚：gnueabi,gnueabhf,none-eaib - 知乎&lt;/a&gt;&lt;/p&gt;
&lt;h5 id=&#34;交叉编译工具链的命名规范&#34;&gt;交叉编译工具链的命名规范
&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;arch [-vendor]  [-os]  [-(gnu)eabi]&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;arch : 架构的意思，如ARM ，MIPS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;vendor： 工具链的提供厂商&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;os： 支持的操作系统&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;eabi：嵌入式应用二进制接口（Embedded Application Binary Interface）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;arm gcc还分为 是否支持操作系统
&lt;strong&gt;支持操作系统：&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://zhida.zhihu.com/search?content_id=117860044&amp;amp;content_type=Article&amp;amp;match_order=1&amp;amp;q=arm-none-linux-eabi-gcc&amp;amp;zhida_source=entity&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;arm-none-linux-eabi-gcc&lt;/a&gt;
&lt;strong&gt;不支持操作系统：&lt;/strong&gt; arm-none-eabi-gcc
none表示vendor是none，也就是不属于某一公司的
（更多的解释是&lt;code&gt;none&lt;/code&gt;是指无操作系统）&lt;/p&gt;
&lt;h5 id=&#34;abi-和-eabi&#34;&gt;ABI 和 EABI
&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;ABI&lt;/strong&gt;：二进制应用程序接口(Application Binary Interface (ABI) for the ARM Architecture)。在计算机中，应用二进制接口描述了应用程序（或者其他类型）和操作系统之间或其他应用程序的低级接口。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EABI&lt;/strong&gt;：嵌入式ABI。嵌入式应用二进制接口指定了文件格式、数据类型、寄存器使用、堆积组织优化和在一个嵌入式软件中的参数的标准约定。开发者使用自己的汇编语言也可以使用 EABI 作为与兼容的编译器生成的汇编语言的接口。&lt;/p&gt;
&lt;p&gt;两者主要区别是，ABI是计算机上的，EABI是嵌入式平台上（如ARM，MIPS等）&lt;/p&gt;
&lt;h4 id=&#34;ninjamakecmake&#34;&gt;ninja，make，cmake
&lt;/h4&gt;
&lt;h5 id=&#34;cmake&#34;&gt;cmake
&lt;/h5&gt;
&lt;p&gt;cmake是一个生成 .ninja 和 .makefile 的工具。cmake只需要用户通过对源码文件的简单描述（就是CMakeLists.txt文件），就能自动生成一个project的makefile文件或者ninja文件，然后就可以通过ninja或者make进行启动编译了，很多IDE都在用cmake作为项目管理工具。&lt;/p&gt;
&lt;h5 id=&#34;make与ninja&#34;&gt;make与ninja
&lt;/h5&gt;
&lt;p&gt;make功能强大，可以给人看，ninja启动速度快，项目构建速度快，但不是给人看的
可以认为两者同级。&lt;/p&gt;
&lt;h5 id=&#34;层级关系&#34;&gt;层级关系
&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;开发者层&lt;/strong&gt;：编写CMakeLists.txt定义构建规则&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成器层&lt;/strong&gt;：CMake解析配置，生成底层构建文件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行器层&lt;/strong&gt;：Make/Ninja执行具体构建命令&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具链层&lt;/strong&gt;：编译器(如gcc)、链接器等实际执行编译&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;hal库hardware-abstraction-layer-硬件抽象层库&#34;&gt;HAL库（Hardware Abstraction Layer 硬件抽象层库）
&lt;/h4&gt;
&lt;h5 id=&#34;1-核心定义与归属&#34;&gt;1. 核心定义与归属
&lt;/h5&gt;
&lt;p&gt;HAL 库是 &lt;strong&gt;STMicroelectronics（意法半导体）&lt;/strong&gt; 为自家 &lt;strong&gt;STM32 系列微控制器（MCU）&lt;/strong&gt; 量身打造的底层软件库，是 STM32 生态中核心的开发工具之一，基于 ARM 的 CMSIS 标准构建。&lt;/p&gt;
&lt;h5 id=&#34;2-核心组成模块&#34;&gt;2. 核心组成模块
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;外设驱动模块&lt;/strong&gt;：覆盖 STM32 所有常用外设（GPIO、UART、SPI、I2C、ADC、DAC、定时器、DMA、CAN、USB 等），每个外设都封装了完整的操作接口（初始化、配置、数据收发 / 采集、中断处理等）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;系统级功能模块&lt;/strong&gt;：包含时钟树配置（HAL_RCC_XXX 系列函数）、中断控制器配置、低功耗模式（睡眠 / 停机 / 待机）管理、复位处理等核心系统功能。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具链适配模块&lt;/strong&gt;：兼容主流开发环境（STM32CubeIDE、Keil MDK、IAR EWARM），支持与 STM32CubeMX（图形化配置工具）联动，可自动生成初始化代码，大幅减少手动编码工作量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;辅助功能模块&lt;/strong&gt;：提供延时函数（HAL_Delay）、错误处理机制、外设状态查询等通用工具函数，提升开发便捷性。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;cmsiscortex-microcontroller-software-interface-standard&#34;&gt;CMSIS（Cortex Microcontroller Software Interface Standard）
&lt;/h4&gt;
&lt;h5 id=&#34;1-核心定义与归属-1&#34;&gt;1. 核心定义与归属
&lt;/h5&gt;
&lt;p&gt;CMSIS 是 &lt;strong&gt;ARM 公司&lt;/strong&gt; 制定的 &lt;strong&gt;行业统一软件接口标准&lt;/strong&gt;（注意：不是具体的软件库，而是 “规范 / 协议”），面向所有基于 ARM Cortex-M 内核（M0/M0+/M3/M4/M7 等）的微控制器，所有主流 MCU 厂商（ST、NXP、Microchip、TI、瑞萨等）均需遵循该标准。&lt;/p&gt;
&lt;h5 id=&#34;2-核心组成模块关键子规范&#34;&gt;2. 核心组成模块（关键子规范）
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CMSIS-Core（内核核心层）&lt;/strong&gt;：最基础、最核心的模块，定义了：
&lt;ul&gt;
&lt;li&gt;内核寄存器的统一访问接口（如 NVIC 中断控制器、Systick 定时器、MPU 内存保护单元的配置函数）；&lt;/li&gt;
&lt;li&gt;系统初始化函数（&lt;code&gt;SystemInit()&lt;/code&gt;）、时钟配置接口，统一不同厂商 Cortex-M MCU 的内核启动流程；&lt;/li&gt;
&lt;li&gt;内核状态查询、中断优先级管理等通用 API，避免开发者直接操作内核寄存器导致的兼容性问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CMSIS-Driver（外设驱动接口层）&lt;/strong&gt;：定义了外设驱动的统一接口模板（如 UART、SPI、GPIO、ADC 等），厂商需按该模板实现驱动函数（如&lt;code&gt;UART_Transmit&lt;/code&gt;、&lt;code&gt;SPI_Receive&lt;/code&gt;），确保不同厂商的外设驱动接口一致。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CMSIS-RTOS（实时操作系统接口层）&lt;/strong&gt;：定义了 RTOS 的统一 API 规范（如任务创建、信号量、消息队列、定时器等），主流 RTOS（FreeRTOS、RTX5、μC/OS-III）均遵循该标准，使 RTOS 能跨厂商 MCU 无缝移植。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CMSIS-DSP（数字信号处理库接口层）&lt;/strong&gt;：定义了 DSP 功能的统一接口（如 FFT、滤波、矩阵运算、PID 控制等），ARM 提供了标准的 CMSIS-DSP 库实现，开发者可直接调用，无需关注底层算法细节。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CMSIS-Pack（软件包格式层）&lt;/strong&gt;：统一了 MCU 设备描述、驱动库、中间件、示例代码的打包格式，方便开发工具（如 Keil MDK、STM32CubeIDE）自动识别、导入和管理软件资源。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;3-特点与适用场景&#34;&gt;3. 特点与适用场景
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;优点：通用性极强、跨平台性好、生态完善，是 Cortex-M MCU 开发的 “通用语言”，适用于所有基于 Cortex-M 内核的 MCU 项目，尤其适合需要跨厂商移植、使用中间件（RTOS/DSP）的复杂项目。&lt;/li&gt;
&lt;li&gt;缺点：仅定义接口规范，不提供具体的驱动实现（需厂商或第三方基于规范开发），开发者无法直接使用 CMSIS，必须结合厂商库（如 HAL 库）或第三方库才能落地。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;hal-库与-cmsis-的关系&#34;&gt;HAL 库与 CMSIS 的关系
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;层级关系&lt;/strong&gt;：CMSIS 是 &lt;strong&gt;底层标准&lt;/strong&gt;，HAL 库是 &lt;strong&gt;基于 CMSIS 标准的具体实现&lt;/strong&gt;——HAL 库的内核操作（如中断配置、Systick 定时器、时钟初始化）完全遵循 CMSIS-Core 规范，外设驱动接口也兼容 CMSIS-Driver 模板。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;作用互补&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;CMSIS 解决 “跨厂商兼容性”：让代码能在 ST、NXP、TI 等不同厂商的 Cortex-M MCU 间移植；&lt;/li&gt;
&lt;li&gt;HAL 库解决 “ST 内部跨型号开发效率”：让 STM32 用户无需关注 CMSIS 底层细节，快速调用封装好的 API 开发功能。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;依赖关系&lt;/strong&gt;：HAL 库必须遵循 CMSIS 标准才能保证兼容性（否则无法适配 Cortex-M 内核）；而 CMSIS 需要 HAL 库这类厂商库来落地实现，才能被开发者直接使用（CMSIS 本身只是 “规则”，不是可执行代码）。
简单总结：&lt;strong&gt;CMSIS 是 “通用接口规则”，HAL 库是 ST 按规则为 STM32 定制的 “工具包”&lt;/strong&gt;，两者结合既保证了跨平台兼容性，又提升了 STM32 的开发效率。&lt;/li&gt;
&lt;/ol&gt;
</description>
        </item>
        <item>
        <title>微机原理</title>
        <link>https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/</link>
        <pubDate>Tue, 24 Jun 2025 23:16:11 +0800</pubDate>
        
        <guid>https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/</guid>
        <description>&lt;h2 id=&#34;常见名词&#34;&gt;常见名词
&lt;/h2&gt;
&lt;p&gt;CPU，中央处理单元，Central Processing Unit&lt;/p&gt;
&lt;p&gt;ALU，算术逻辑单元，Arithmetic and Logic Units&lt;/p&gt;
&lt;p&gt;CU，控制单元，控制器，Control Unit&lt;/p&gt;
&lt;p&gt;CPU通常由中央处理单元，算术逻辑单元，寄存器组三部分组成&lt;/p&gt;
&lt;p&gt;EU，执行单元，Execution Unit&lt;/p&gt;
&lt;p&gt;BIU，总线接口单元，Bus Interface Unit&lt;/p&gt;
&lt;p&gt;PC，程序计数器，Program Counter&lt;/p&gt;
&lt;p&gt;IR，指令寄存器，Instruction Register&lt;/p&gt;
&lt;p&gt;GR，通用寄存器，General Register&lt;/p&gt;
&lt;p&gt;注意$IO$端口和$IO$接口不是同一个东西&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/qq_34801169/article/details/102782643&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;操作系统知识：程序计数器（pc）、指令寄存器（IR）、通用寄存器（GR）、状态寄存器（SR）、程序状态字PSW_pc和ir-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;特殊运算符和指令&#34;&gt;特殊运算符和指令
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;PTR&lt;/code&gt;用来指定存储器操作数的字长
&lt;code&gt;Byte PTR[BX]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;所有单操作数指令要求操作数不能是立即数，如果是存储器操作数，需要指定字长&lt;/p&gt;
&lt;h2 id=&#34;微型计算机基础概论&#34;&gt;微型计算机基础概论
&lt;/h2&gt;
&lt;h3 id=&#34;微型计算机系统&#34;&gt;微型计算机系统
&lt;/h3&gt;
&lt;p&gt;微型计算机系统 由 硬件系统 和 软件系统 组成
&lt;strong&gt;硬件系统&lt;/strong&gt;
硬件系统 由 微型计算机（主机） 和 外设组成&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;微型计算机（主机）由 微处理器（CPU），存储器 ，IO接口 ，总线 组成&lt;/li&gt;
&lt;li&gt;外设 就包括键盘，鼠标，显示器，硬盘等&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;软件系统&lt;/strong&gt;
软件系统 由 系统软件 和 应用软件 构成&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;微型计算机运行流程&lt;/strong&gt;
微机运行的基本流程为，程序存储在存储器中，按程序流程自动连续取出指令并执行；自动连续的实现是程序计数器 PC 的自增；步骤可概括为取指令、译码、执行。修改 PC 指针的值，可实现程序的顺序执行、跳转、循环、过程调用和中断服务等功能。&lt;/p&gt;
&lt;h3 id=&#34;计算机中的数制与编码&#34;&gt;计算机中的数制与编码
&lt;/h3&gt;
&lt;p&gt;十进制&lt;code&gt;D&lt;/code&gt;，二进制&lt;code&gt;B&lt;/code&gt;，十六进制&lt;code&gt;H&lt;/code&gt;，八进制&lt;code&gt;O&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;有符号二进制数的表示&#34;&gt;有符号二进制数的表示
&lt;/h3&gt;
&lt;p&gt;最高位是符号位，0表示正号，1表示负号&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原码&lt;/strong&gt;
数值部分保持不变，最高位是符号位
&lt;strong&gt;反码&lt;/strong&gt;
正数的反码与正数的原码一样
负数的反码 等于 负数原码 数值部分 按位取反
&lt;strong&gt;补码&lt;/strong&gt;
正数的补码与正数的反码和原码一样
负数的补码 的符号位 与 负数原码一致，数值部分等于 负数原码 数值部分取反后再加1&lt;/p&gt;
&lt;p&gt;特殊数&lt;code&gt;-128&lt;/code&gt;的补码表示为&lt;code&gt;10000000&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;微处理器与总线&#34;&gt;微处理器与总线
&lt;/h2&gt;
&lt;h3 id=&#34;cpu中央处理单元&#34;&gt;CPU中央处理单元
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;CPU&lt;/code&gt;是微型计算机的运算和指挥控制中心
一般由&lt;code&gt;ALU（运算器）&lt;/code&gt;，&lt;code&gt;CU（控制单元）&lt;/code&gt;，&lt;code&gt;寄存器组&lt;/code&gt;组成
CPU内还有两个独立部件：EU（执行单元）和BIU（总线接口单元）
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086CPU%E5%86%85%E9%83%A8%E7%BB%93%E6%9E%84.png&#34;
	width=&#34;811&#34;
	height=&#34;624&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086CPU%E5%86%85%E9%83%A8%E7%BB%93%E6%9E%84_hu5357207533187028771.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086CPU%E5%86%85%E9%83%A8%E7%BB%93%E6%9E%84_hu2737783820847314729.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;129&#34;
		data-flex-basis=&#34;311px&#34;
	
&gt;
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E5%BE%AE%E5%A4%84%E7%90%86%E5%99%A8%E7%BB%93%E6%9E%84%E7%A4%BA%E6%84%8F%E5%9B%BE.png&#34;
	width=&#34;1160&#34;
	height=&#34;683&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E5%BE%AE%E5%A4%84%E7%90%86%E5%99%A8%E7%BB%93%E6%9E%84%E7%A4%BA%E6%84%8F%E5%9B%BE_hu5700801025308735065.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E5%BE%AE%E5%A4%84%E7%90%86%E5%99%A8%E7%BB%93%E6%9E%84%E7%A4%BA%E6%84%8F%E5%9B%BE_hu8790980325570178500.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;169&#34;
		data-flex-basis=&#34;407px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;微处理器主要性能指标&#34;&gt;微处理器主要性能指标
&lt;/h4&gt;
&lt;p&gt;CPU的字长/位数，及其一次性能处理的位数
CPU主频，指的是CPU时钟频率&lt;/p&gt;
&lt;h4 id=&#34;cu控制单元&#34;&gt;CU控制单元
&lt;/h4&gt;
&lt;p&gt;控制器的作用是控制程序的执行，是整个系统的指挥中心
具备以下功能&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;指令控制&lt;/li&gt;
&lt;li&gt;时序控制&lt;/li&gt;
&lt;li&gt;操作控制&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;eu执行单元&#34;&gt;EU执行单元
&lt;/h4&gt;
&lt;p&gt;EU负责分析指令（指令译码），执行指令
在工作时不断从BIU的指令队列取指令&lt;/p&gt;
&lt;h4 id=&#34;biu总线接口单元&#34;&gt;BIU总线接口单元
&lt;/h4&gt;
&lt;p&gt;BIU主要功能是负责CPU与存储器，IO接口之间的信息传送
BIU可以负责取指令，取操作数，写结果
BIU内部有一个指令队列和地址加法器
地址加法器能产生20位的物理地址&lt;/p&gt;
&lt;h4 id=&#34;cpu程序执行步骤&#34;&gt;CPU程序执行步骤
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;从存储器取出下一条指令&lt;/li&gt;
&lt;li&gt;指令译码&lt;/li&gt;
&lt;li&gt;如果指令需要，从存储器中读取操作数&lt;/li&gt;
&lt;li&gt;执行指令（算术逻辑运算，IO操作，数据传输等）&lt;/li&gt;
&lt;li&gt;如果需要，写入存储器
核心步骤，取指令，译码指令，执行指令&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;工作时序&#34;&gt;工作时序
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;时钟周期：每个时钟脉冲持续的时间&lt;/li&gt;
&lt;li&gt;总线周期：通过总线进行一次读或写操作的过程称为一个总线周期，一个总线周期包含多个时钟周期&lt;/li&gt;
&lt;li&gt;指令周期：执行一条指令所需的时间，一个指令周期包含多个总线周期
一个基本的总线周期由四个时钟周期构成，若内存或 IO 接口速度较慢，则还会在 T3 后插入 Tw 等待周期。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;写操作为例的总线周期
包含4个时钟周期（T1,T2,T3,T4）
T1地址输出，T2缓存，T3和T4数据输出&lt;/p&gt;
&lt;h3 id=&#34;80888086-cpu&#34;&gt;8088/8086 CPU
&lt;/h3&gt;
&lt;h5 id=&#34;8088与8086处理器的区别&#34;&gt;8088与8086处理器的区别
&lt;/h5&gt;
&lt;p&gt;8088 外部数据线为8根（8086为16根），为准16位CPU，16 位数据要分两次传送；（ 注意：8088和8086均为16位处理 器，内部数据线均为16位，且地址总线均为20位）
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8088%E4%B8%8E8086%E5%A4%84%E7%90%86%E5%99%A8%E5%8C%BA%E5%88%AB.png&#34;
	width=&#34;993&#34;
	height=&#34;487&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8088%E4%B8%8E8086%E5%A4%84%E7%90%86%E5%99%A8%E5%8C%BA%E5%88%AB_hu5053405734855977721.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8088%E4%B8%8E8086%E5%A4%84%E7%90%86%E5%99%A8%E5%8C%BA%E5%88%AB_hu9370541274539670867.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;203&#34;
		data-flex-basis=&#34;489px&#34;
	
&gt;
指令预取队列：8088为4字节，8086为6字节&lt;/p&gt;
&lt;p&gt;两者均有两种工作模式，最小工作模式和最大工作模式&lt;/p&gt;
&lt;h4 id=&#34;80888086指令流水线&#34;&gt;8088/8086指令流水线
&lt;/h4&gt;
&lt;p&gt;采用EU（执行单元）和BIU（总线接口单元）并行工作，可同时取指令，执行指令，分析指令
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086%E6%8C%87%E4%BB%A4%E6%B5%81%E6%B0%B4%E7%BA%BF.png&#34;
	width=&#34;1136&#34;
	height=&#34;386&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086%E6%8C%87%E4%BB%A4%E6%B5%81%E6%B0%B4%E7%BA%BF_hu15710173565322608804.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086%E6%8C%87%E4%BB%A4%E6%B5%81%E6%B0%B4%E7%BA%BF_hu11775171834208968470.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;294&#34;
		data-flex-basis=&#34;706px&#34;
	
&gt;&lt;/p&gt;
&lt;h5 id=&#34;补充-流水线技术&#34;&gt;补充-流水线技术
&lt;/h5&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E4%BA%94%E9%98%B6%E6%AE%B5%E6%B5%81%E6%B0%B4%E7%BA%BF.png&#34;
	width=&#34;1088&#34;
	height=&#34;640&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E4%BA%94%E9%98%B6%E6%AE%B5%E6%B5%81%E6%B0%B4%E7%BA%BF_hu15348091575994016305.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E4%BA%94%E9%98%B6%E6%AE%B5%E6%B5%81%E6%B0%B4%E7%BA%BF_hu15856999597711058177.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;170&#34;
		data-flex-basis=&#34;408px&#34;
	
&gt;
在指令执行过程中，有几类指令相关影响流水线中指令的执行，使得指令不能在预先设定的执行周期中执行，造成流水线断流
&lt;strong&gt;相关问题&lt;/strong&gt;
结构相关；数据相关；控制相关&lt;/p&gt;
&lt;h6 id=&#34;结构相关&#34;&gt;结构相关
&lt;/h6&gt;
&lt;p&gt;当CPU的硬件结构不能够同时支持几条指令的执行时，这几条指令将发生结构相关，比如流水线同时访问同一个存储器&lt;/p&gt;
&lt;h6 id=&#34;数据相关&#34;&gt;数据相关
&lt;/h6&gt;
&lt;p&gt;一条指令的执行需要上一条或者上几条指令的执行结果时
，会造成流水线的断流现象。&lt;/p&gt;
&lt;p&gt;所以，当发生数据相关时，需要尽可能早的把上一条或上几条指令的执行结果 交给相关指令作为操作数。这就需要“内部前推&lt;/p&gt;
&lt;h6 id=&#34;控制相关&#34;&gt;控制相关
&lt;/h6&gt;
&lt;p&gt;当指令执行到分支指令或者跳转指令时，将产生控制相关，此时会产生流水线断流。
解决方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;阻塞流水线直到确定走向&lt;/li&gt;
&lt;li&gt;预测分支是否发生，并给予该预测执行指令&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;80888086内存分段&#34;&gt;8088/8086内存分段
&lt;/h4&gt;
&lt;p&gt;8088/8086&lt;strong&gt;内部结构为16位&lt;/strong&gt;，为了增大内存管理能力使其能产生20位的物理地址，采用了分段管理方法&lt;/p&gt;
&lt;p&gt;段首地址即段基地址
20位物理地址=段基地址 * 16+段偏移地址
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-808880086%E5%86%85%E5%AD%98%E5%88%86%E6%AE%B5.png&#34;
	width=&#34;1014&#34;
	height=&#34;415&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-808880086%E5%86%85%E5%AD%98%E5%88%86%E6%AE%B5_hu14263394686829289510.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-808880086%E5%86%85%E5%AD%98%E5%88%86%E6%AE%B5_hu15358846135240444311.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;244&#34;
		data-flex-basis=&#34;586px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;80888086内部寄存器&#34;&gt;8088/8086内部寄存器
&lt;/h4&gt;
&lt;p&gt;8088/8086内部寄存器分为   通用寄存器（8个），段寄存器（4个），控制寄存器（2个）
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086%E5%86%85%E9%83%A8%E5%AF%84%E5%AD%98%E5%99%A8.png&#34;
	width=&#34;747&#34;
	height=&#34;706&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086%E5%86%85%E9%83%A8%E5%AF%84%E5%AD%98%E5%99%A8_hu13494009740208978098.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086%E5%86%85%E9%83%A8%E5%AF%84%E5%AD%98%E5%99%A8_hu11349535306249906087.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;105&#34;
		data-flex-basis=&#34;253px&#34;
	
&gt;&lt;/p&gt;
&lt;h5 id=&#34;通用寄存器&#34;&gt;通用寄存器
&lt;/h5&gt;
&lt;p&gt;通用寄存器包括 数据寄存器，地址指针寄存器，变址寄存器&lt;/p&gt;
&lt;h6 id=&#34;数据寄存器&#34;&gt;数据寄存器
&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;AX（Accumulator）：累加器，常用于存放算术逻辑运算中的操作数，另外所有的IO指令都是用累加器与外设接口传送信息&lt;/li&gt;
&lt;li&gt;BX（Base）：基址寄存器，常用来存放访问内存时的&lt;strong&gt;偏移地址&lt;/strong&gt;（一般和DS一起用DS:[BX]）&lt;/li&gt;
&lt;li&gt;CX（Count）：计数寄存器，在循环和串操作指令中用作计数器&lt;/li&gt;
&lt;li&gt;DX（Data）：数据寄存器，在寄存器间接寻址的IO指令中存放IO端口地址&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;都可拆分为H，L两个8位寄存器&lt;/p&gt;
&lt;p&gt;在做双字节乘除法运算时，DX与AX可以合起来存一个双字长的数（32位），DX存高16位，AX存低16位&lt;/p&gt;
&lt;h6 id=&#34;地址指针寄存器&#34;&gt;地址指针寄存器
&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;SP（Stack Pointer）：堆栈指针寄存器，常用来存放 栈顶偏移地址&lt;/li&gt;
&lt;li&gt;BP（Base Pointer）：基址指针寄存器，一般也用来存放访问内存时的&lt;strong&gt;偏移地址&lt;/strong&gt;（一般和SS一起用SS:[BP]）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;BX和BP区别: (1)作为通用寄存器，二者均可用于存放数据；(2)作为基址寄存器，用BX表示 所寻找的数据在 数据段 ；用BP则表示数据在 堆栈段&lt;/p&gt;
&lt;h6 id=&#34;变址寄存器&#34;&gt;变址寄存器
&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;SI（Source Index）：源变址寄存器&lt;/li&gt;
&lt;li&gt;DI（Destination Index）：目的变址寄存器&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;段寄存器&#34;&gt;段寄存器
&lt;/h5&gt;
&lt;p&gt;段寄存器，用于存放段基址，即段起始地址的高16位&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CS（Code Segment）：代码段寄存器&lt;/li&gt;
&lt;li&gt;SS（Stack Segment）：堆栈段寄存器&lt;/li&gt;
&lt;li&gt;DS（Data Segment）：数据段寄存器&lt;/li&gt;
&lt;li&gt;ES（Extra Segment）：附加数据段寄存器&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;控制寄存器&#34;&gt;控制寄存器
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;IP（Instruction Pointer）：指令指针寄存器，其内容为下一条要执行指令的偏移地址（CS段中）&lt;/li&gt;
&lt;/ul&gt;
&lt;h6 id=&#34;标志寄存器&#34;&gt;&lt;strong&gt;标志寄存器&lt;/strong&gt;
&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;FLAGS：状态寄存器，16位寄存器
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8.png&#34;
	width=&#34;1050&#34;
	height=&#34;196&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8_hu11152031068871006802.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8_hu152377642170095446.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;535&#34;
		data-flex-basis=&#34;1285px&#34;
	
&gt;
&lt;strong&gt;状态标志位&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;CF（Carry Flag）：进位标志位，进行加减运算时，若最高位向前有进位错位，则CF=1&lt;/li&gt;
&lt;li&gt;PF（Parity Flag）：奇偶标志位，运算结果低8位中1的个数为偶数，PF=1&lt;/li&gt;
&lt;li&gt;AF（Auxiliary Carry Flag）：辅助进位标志位，加减法运算，D3向D4进位时，AF=1&lt;/li&gt;
&lt;li&gt;ZF（Zero Flag）：零标志位，运算结果为0时，ZF=1&lt;/li&gt;
&lt;li&gt;SF（Sign Flag）：当运算结果最高位为1时，SF=1&lt;/li&gt;
&lt;li&gt;OF（Overflow Flag）：当算术结果超出了 &lt;code&gt;带符号数&lt;/code&gt;的范围时，即溢出时，OF=1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;控制标志位&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TF（Trap Flag）：陷井标志位，也叫跟踪标志位。TF=1时，使CPU处于单步执行指令的工作方式&lt;/li&gt;
&lt;li&gt;IF（Interrupt Enable Flag）：中断允许标志位。IF=1使CPU可以响应可屏蔽中断请求&lt;/li&gt;
&lt;li&gt;DF（Direction Flag）：方向标志位。在数据串操作时确定操作的方向&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;IF=1，允许响应可屏蔽中断请求，对应指令：STI
IF=0，禁止响应可屏蔽中断请求，对应指令：CLI&lt;/p&gt;
&lt;p&gt;DF=0，串操作指令中的地址是增加方向，对应指令：CLD
DF=1，串操作指令中的地址是减少方向，对应指令：STD&lt;/p&gt;
&lt;p&gt;TF=1，CPU按跟踪方式（单步方式）执行程序&lt;/p&gt;
&lt;h4 id=&#34;8088外部引脚及其功能&#34;&gt;8088外部引脚及其功能
&lt;/h4&gt;
&lt;p&gt;最小模式下的引脚描述&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8088%E5%BE%AE%E5%A4%84%E7%90%86%E5%99%A8%E5%BC%95%E8%84%9A%E6%8F%8F%E8%BF%B0.png&#34;
	width=&#34;398&#34;
	height=&#34;512&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8088%E5%BE%AE%E5%A4%84%E7%90%86%E5%99%A8%E5%BC%95%E8%84%9A%E6%8F%8F%E8%BF%B0_hu12981524713681856048.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8088%E5%BE%AE%E5%A4%84%E7%90%86%E5%99%A8%E5%BC%95%E8%84%9A%E6%8F%8F%E8%BF%B0_hu6343090435501543611.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;77&#34;
		data-flex-basis=&#34;186px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;按功能对引脚进行划分：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;基础工作引脚：$Vcc,GND,CLK(4.77Mhz)$&lt;/li&gt;
&lt;li&gt;地址总线：${AD}&lt;em&gt;0-{AD}&lt;em&gt;7,A_8-A&lt;/em&gt;{15},A&lt;/em&gt;{16}-A_{19}$&lt;/li&gt;
&lt;li&gt;数据总线：${AD}_0-{AD}_7$&lt;/li&gt;
&lt;li&gt;模式控制引脚：$MN/\overline{MX}$&lt;/li&gt;
&lt;li&gt;读写控制引脚：$IO/\overline M,\overline{RD},\overline{WR}$&lt;/li&gt;
&lt;li&gt;中断控制引脚：$INTR,NMI,INTA$&lt;/li&gt;
&lt;li&gt;复位：$RESET$&lt;/li&gt;
&lt;li&gt;总线保持请求/响应：$HOLD,HLDA$&lt;/li&gt;
&lt;li&gt;地址锁存信号：$ALE$&lt;/li&gt;
&lt;li&gt;外部就绪信号：$READY$&lt;/li&gt;
&lt;li&gt;测试信号输入：$\overline {TEST}$&lt;/li&gt;
&lt;li&gt;数据传输方向控制：$DT/\overline R$&lt;/li&gt;
&lt;li&gt;数据允许信号：$\overline {DEN}$&lt;/li&gt;
&lt;li&gt;系统状态输出：$\overline{{SS}_0}$（与$IO/\overline M,DT/\overline R$合作）&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&#34;各引脚具体功能&#34;&gt;各引脚具体功能
&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;$A_{16}-A_{19}/S_3-S_6$：地址，状态复用的引脚，三态输出。（分时复用）状态信号中$S_6$恒等于0，$S_5$指示中断允许标志位$IF$的状态，$S_4,S_5$组合指示CPU正在使用的段寄存器&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$A_8-A_{15}$：8位地址信号，三态输出&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;${AD}&lt;em&gt;{0}-{AD}&lt;/em&gt;{7}$：地址，数据分时复用的双向信号线，三态。当$ALE=1$时，这些引脚上传输的是地址信号，当$\overline {DEN}=0$时，这些引脚上传输的是数据信号&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$IO/\overline M$：输入输出/存储器控制信号，三态。该引脚是用来区分当前操作是访问存储器还是访问$IO$端口&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$\overline {WR}$：写信号输出，三态。当此引脚输出为低电平时，表示CPU正在对存储器或IO端口进行写操作&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$DT/\overline {R}$：数据传送方向控制信号，三态。高电平时，CPU向存储器或IO端口发送数据；低电平时，CPU从存储器或IO接口接收数据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$\overline {DEN}$：数据允许信号，三态。该信号有效时，表示 数据总线 上具有有效信号。它在每次 访问内存或IO接口以及在中断响应期间有效，常用作数据总线驱动信号&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$ALE$：地址锁存信号，三态输出，高电平有效。它为高电平时，表示CPU地址线上有有效地址&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$\overline {RD}$：读选通信号，三态输出，低电平有效。其有效时，表示CPU正在对存储器或IO接口进行读操作&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$READY$：外部同步控制输入信号，高电平有效。它是由被访问的内存或IO设备所发出的响应信号。它为高电平时，表示存储器或IO设备已经准备好，CPU可以进行数据传送 。CPU在T3的周期采样$READY$信号，若其为低，CPU自动插入等待周期$T_w$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$INTR$ ：可屏蔽中断请求输入信号，高电平有效。CPU在每条指令的最后一个周期采样该信号，以决定是否进入中断响应周期&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$\overline {TEST}$：测试信号输入引脚&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$NMI$：非屏蔽中断请求输入信号，上升沿触发。这个引脚上的中断请求信号不能用让软件屏蔽，CPU在当前指令&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$RESET$：系统复位输入信号，高电平有效。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$\overline {INTA}$：中断响应信号输出，低电平有效，此信号是CPU对中断请求信号$INTR$ 的响应。             在响应过程中，CPU在$\overline {INTA}$上连续输出两个负脉冲用作外部中断的中断向量码的读选通信号&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$HOLD$：总线保持请求信号输入，高电平有效。当某一总线主控设备要占用系统总线时，通过此引脚向CPU提出请求&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$HLDA$：总线保持响应信号输出，高电平有效。这是CPU对$HOLD$请求的响应信号。CPU收到$HOLD$信号后，就会对其做出响应，一方面会使CPU的所有三态输出的地址信号，数据信号和对应的控制信号变为高阻态；同时输出一个有效的$HLDA$，表示CPU已放弃对总线的控制。当CPU检测到$HOLD$信号变低后，就立即使$HLDA$变低，同时恢复对总线的控制&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;${SS}_0$：系统状态信号输出&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$CLK$： 时钟信号输入引脚&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$Vcc$：5V电源输入引脚&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$GND$：地线&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;80888086结构功能&#34;&gt;8088/8086结构功能
&lt;/h3&gt;
&lt;p&gt;外部结构
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086%E5%A4%96%E9%83%A8%E7%BB%93%E6%9E%84.png&#34;
	width=&#34;785&#34;
	height=&#34;541&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086%E5%A4%96%E9%83%A8%E7%BB%93%E6%9E%84_hu9340733778461164024.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-80888086%E5%A4%96%E9%83%A8%E7%BB%93%E6%9E%84_hu13399290470043408283.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;145&#34;
		data-flex-basis=&#34;348px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;总线&#34;&gt;总线
&lt;/h3&gt;
&lt;h4 id=&#34;总线定义&#34;&gt;总线定义
&lt;/h4&gt;
&lt;p&gt;总线是传输信号或信息的公共路径，是遵循同一技术规范的连接与操作方式&lt;/p&gt;
&lt;h4 id=&#34;总线特点&#34;&gt;总线特点
&lt;/h4&gt;
&lt;p&gt;公共性，可同时挂在多个设备&lt;/p&gt;
&lt;h4 id=&#34;总线分类&#34;&gt;总线分类
&lt;/h4&gt;
&lt;p&gt;按传送的信息类型分类&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;数据总线（Data Bus）&lt;/li&gt;
&lt;li&gt;地址总线（Address Bus）&lt;/li&gt;
&lt;li&gt;控制总线（Control Bus）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;按总线的层次结构划分&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;前端总线&lt;/li&gt;
&lt;li&gt;系统总线&lt;/li&gt;
&lt;li&gt;外设总线&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;总线结构&#34;&gt;总线结构
&lt;/h4&gt;
&lt;p&gt;单总线结构，多总线结构&lt;/p&gt;
&lt;h4 id=&#34;总线基本功能&#34;&gt;总线基本功能
&lt;/h4&gt;
&lt;p&gt;总线上任意时刻只能允许一对设备进行信息交换&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;总线传输同步：协调通信双方的传输操作&lt;/li&gt;
&lt;li&gt;总线仲裁控制：避免多个设备同时使用总线造成的冲突，确定总线上哪个设备可以占用总线传输数据&lt;/li&gt;
&lt;li&gt;出错处理：检错和处理&lt;/li&gt;
&lt;li&gt;总线驱动：增加驱动能力&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;总线的数据传送&#34;&gt;总线的数据传送
&lt;/h5&gt;
&lt;h6 id=&#34;1同步定时的传输方式&#34;&gt;1.同步定时的传输方式
&lt;/h6&gt;
&lt;p&gt;用公共的时钟统一各部件数据发送和接收的时机 （严格按节拍进行，不需要握手信号，效率高）&lt;/p&gt;
&lt;h6 id=&#34;2异步定时的传输方式&#34;&gt;2.异步定时的传输方式
&lt;/h6&gt;
&lt;p&gt;用控制和状态信号协调各部件数据发送和接收的时机（应答式）&lt;/p&gt;
&lt;h6 id=&#34;3半同步定时的传输方式&#34;&gt;3.半同步定时的传输方式
&lt;/h6&gt;
&lt;p&gt;允许不同速度的部件协同工作，主控设备可以根据从设备的状态延长总线 时钟周期，但总线周期一定是时钟周期的整数倍&lt;/p&gt;
&lt;h4 id=&#34;常用系统总线和外设总线标准&#34;&gt;常用系统总线和外设总线标准
&lt;/h4&gt;
&lt;p&gt;常用的系统总线标准包括：ISA 总线、PCI 总线、PCIE 总线、AGP 总线
常用的外设总线标准包括：SATA 总线、USB 总线、RS485 总线、IDE 总线、RS232 总线&lt;/p&gt;
&lt;h2 id=&#34;指令系统&#34;&gt;指令系统
&lt;/h2&gt;
&lt;p&gt;指令：控制计算机完成指定操作并能够被计算机所识别的命令。 指令系统：一台计算机能够识别的所有指令的集合称为该机的指令系统&lt;/p&gt;
&lt;p&gt;指令格式： &lt;code&gt;操作码 操作数1，操作数2&lt;/code&gt;
操作数数量：零操作数指令，单操作数指令，双操作数指令&lt;/p&gt;
&lt;p&gt;指令中操作数类型：立即操作数，寄存器操作数，存储器操作数
寄存器操作数的指令执行速度&amp;gt; 立即数操作数&amp;gt; 存储器操作数&lt;/p&gt;
&lt;p&gt;CISC（Complex Instruction Set Computer），复杂指令系统计算机
RISC（Reduced Instruction Set Computer），精简指令系统计算机&lt;/p&gt;
&lt;p&gt;指令性指令是CPU中实际存在的可执行的语句。指示性语句是用于说明程序结构，变量等的语句，后者在编译过程中执行，编译完成后不再存在&lt;/p&gt;
&lt;h3 id=&#34;对于每个指令&#34;&gt;对于每个指令
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;指令码的含义&lt;/li&gt;
&lt;li&gt;指令对操作数的要求&lt;/li&gt;
&lt;li&gt;指令对标志位的影响&lt;/li&gt;
&lt;li&gt;指令的功能&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;寻址方式&#34;&gt;寻址方式
&lt;/h2&gt;
&lt;h4 id=&#34;立即寻址immediate-addressing&#34;&gt;立即寻址（Immediate Addressing）
&lt;/h4&gt;
&lt;p&gt;源操作数是立即数，立即数存放在代码段
&lt;code&gt;MOV AX,3102H&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;直接寻址direct-addressing&#34;&gt;直接寻址（Direct Addressing）
&lt;/h4&gt;
&lt;p&gt;操作数是存储器操作数，存放的地址由指令直接给出
&lt;code&gt;MOV AX,[3102H]&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;寄存器寻址register-addressing&#34;&gt;寄存器寻址（Register Addressing）
&lt;/h4&gt;
&lt;p&gt;操作数为CPU内部寄存器
&lt;code&gt;MOV AX,BX&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;寄存器间接寻址register-indirect-addressing&#34;&gt;寄存器间接寻址（Register Indirect Addressing）
&lt;/h4&gt;
&lt;p&gt;寄存器存放的不是数据本身，而是存放数据的偏移地址
寄存器间接寻址方式中 存放操作数偏移地址 的寄存器只允许是 $SI,DI,BX,BP$，它们也被称为间址寄存器&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;选择$SI,DI,BX$作为间址寄存器时，操作数在数据段，段基址由$DS$决定&lt;/li&gt;
&lt;li&gt;选择$BP$作为间址寄存器，则操作数在堆栈段，段基地址由$SS$决定
允许段重设
&lt;code&gt;MOV AX,[BX]&lt;/code&gt;
&lt;code&gt;MOV AX,ES:[SI]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;寄存器相对寻址&#34;&gt;寄存器相对寻址
&lt;/h4&gt;
&lt;p&gt;操作数在内存中的偏址地址由间址寄存器的值加上一个8位或16位的偏移量
&lt;code&gt;MOV AX,DATA[BX]&lt;/code&gt;
&lt;code&gt;MOV AX,[BX+DATA]&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;基址-变址寻址&#34;&gt;基址-变址寻址
&lt;/h4&gt;
&lt;p&gt;基址-变址寻址方式由一个基址寄存器存的值和一个变址寄存器存的值 相加得到偏移地址&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不允许出现两个基址寄存器&lt;/li&gt;
&lt;li&gt;不允许出现两个变址寄存器
&lt;code&gt;MOV AX,[BX][SI]&lt;/code&gt;
&lt;code&gt;MOV AX,[SI][BX]&lt;/code&gt;
&lt;code&gt;MOV AX,[BX+SI]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;基址-变址-相对寻址&#34;&gt;基址-变址-相对寻址
&lt;/h4&gt;
&lt;p&gt;所寻地址在内存中，偏移地址由一个基址寄存器、一个变址寄存器和数值偏移 量相加给出。其它规定同“基址-变址寻址”
&lt;code&gt;MOV AX,DATA[SI][BX]&lt;/code&gt;
&lt;code&gt;MOV AX,[BX+DATA][SI]&lt;/code&gt;
&lt;code&gt;MOV AX,[BX+SI+DATA]&lt;/code&gt;
&lt;code&gt;MOV AX,[BX+SI]DATA&lt;/code&gt;
&lt;code&gt;MOV AX,[BX]DATA[SI]&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;隐含寻址&#34;&gt;隐含寻址
&lt;/h4&gt;
&lt;p&gt;指令中隐含了部分固定的操作数的地址
&lt;code&gt;MUL BL&lt;/code&gt;
把AL与BL相乘的乘积放入AX&lt;/p&gt;
&lt;h2 id=&#34;堆栈段&#34;&gt;堆栈段
&lt;/h2&gt;
&lt;p&gt;规定由SS指示堆栈段的段基址，堆栈的最低地址
堆栈指针SP始终指向堆栈的顶部（栈顶）。堆栈的最高地址叫栈底
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E5%A0%86%E6%A0%88%E6%AE%B5.png&#34;
	width=&#34;918&#34;
	height=&#34;517&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E5%A0%86%E6%A0%88%E6%AE%B5_hu13912653914353356906.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E5%A0%86%E6%A0%88%E6%AE%B5_hu2629891891702791425.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;177&#34;
		data-flex-basis=&#34;426px&#34;
	
&gt;
栈的压入指令
&lt;code&gt;PUSH src&lt;/code&gt;
栈的弹出指令
&lt;code&gt;POP dest&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;操作原则&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;操作数为1个字，且只能是寄存器或存储器操作&lt;/li&gt;
&lt;li&gt;存放数据从高地址向低地址方向增长&lt;/li&gt;
&lt;li&gt;堆栈段位置由SS决定，SP指向栈顶&lt;/li&gt;
&lt;li&gt;PUSH压入过程为先减SP再压数据&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SP-2 -&amp;gt; SP
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;src高8位-&amp;gt;[SP+1]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;src低8位-&amp;gt;[SP]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;POP弹出过程为先弹数据再加SP&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[SP]-&amp;gt;dest低8位
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[SP+1]-&amp;gt;dest高8位
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SP+2-&amp;gt;SP
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;堆栈主要用途：保护现场&lt;/p&gt;
&lt;h2 id=&#34;数据传送指令&#34;&gt;数据传送指令
&lt;/h2&gt;
&lt;p&gt;数据传送指令的执行均不影响标志位&lt;/p&gt;
&lt;h3 id=&#34;一般传送指令mov&#34;&gt;一般传送指令MOV
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;MOV dest,src&lt;/code&gt;
对操作数要求：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;两个操作数字长相同&lt;/li&gt;
&lt;li&gt;两个操作数不能同时为存储器操作数&lt;/li&gt;
&lt;li&gt;不能用立即数直接给段寄存器赋值&lt;/li&gt;
&lt;li&gt;两个操作数不能同时为段寄存器&lt;/li&gt;
&lt;li&gt;IP和CS只作为MOV的源操作数，不做目标操作数&lt;/li&gt;
&lt;li&gt;FLAGS整体不能作为操作数&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;两个操作数不能同时为存储器操作数，原因是存储器不能确定字长，是在存储器中取1个字节还是多个字节，没有限定&lt;/p&gt;
&lt;h3 id=&#34;堆栈操作指令push和pop&#34;&gt;堆栈操作指令PUSH和POP
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;PUSH src&lt;/code&gt;
&lt;code&gt;POP dest&lt;/code&gt;
操作数为1个字，且只能是寄存器或存储器操作，不能是立即数&lt;/p&gt;
&lt;h3 id=&#34;交换指令xchg&#34;&gt;交换指令XCHG
&lt;/h3&gt;
&lt;p&gt;功能：交换源地址与目标地址中的内容
&lt;code&gt;XCHG OPRD1,OPRD2&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;输入输出指令in和out&#34;&gt;输入/输出指令IN和OUT
&lt;/h3&gt;
&lt;p&gt;功能：对输入/输出端口进行读写
输入指令IN用于从IO端口读数据到累加器AL（AX）中
输出指令OUT用于把累加器AL（AX）的内容写到IO端口
IO端口寻址&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;直接寻址：指令中的IO端口地址为8位&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;IN AL/AX,port
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;OUT port,AL/AX
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;寄存器间接寻址：端口地址为16位，由DX寄存器指定&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;IN AL/AX,DX 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;OUT DX,AL/AX
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;操作原则&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;只有AL或AX可以与I/O端口进行数据交换&lt;/li&gt;
&lt;li&gt;IO端口地址可以是8位立即数指向的地址（即直接寻址）或由DX保存的16 位地址（即间接寻址）
当端口地址是16位时，只能用DX取给定端口地址&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;取偏移地址指令lea-load-effect-address&#34;&gt;取偏移地址指令LEA （Load Effect Address）
&lt;/h3&gt;
&lt;p&gt;功能：将存储器操作数的16位偏移地址送到指定寄存器
&lt;code&gt;LEA reg16, mem &lt;/code&gt;
操作原则&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;源操作数必须是存储器操作数，如：
&lt;code&gt;LEA BX, BUFFER&lt;/code&gt;
&lt;code&gt;LEA BX, [SI]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;目标操作数必须是16位通用寄存器，最好使用间址寄存器（BX, SI, DI, BP）
源操作数必须是存储器操作数&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;算数运算指令&#34;&gt;算数运算指令
&lt;/h2&gt;
&lt;p&gt;不带进位和带进位的加减指令
无符号和有符号的乘除指令&lt;/p&gt;
&lt;p&gt;算术运算指令的执行会影响状态标志位
乘法指令执行结果为相乘数的双倍字长
除法指令被除数是除数的双倍字长&lt;/p&gt;
&lt;h3 id=&#34;乘法指令&#34;&gt;乘法指令
&lt;/h3&gt;
&lt;p&gt;乘法指令采用隐含寻址，隐含了存放被乘数的累加器AL或AX，以及存放结果的AX或AX，DX&lt;/p&gt;
&lt;p&gt;无符号乘法指令
&lt;code&gt;MUL BYTE PTR[BX]&lt;/code&gt;
有符号乘法指令
&lt;code&gt;IMUL OPRD&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;除法指令&#34;&gt;除法指令
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;DIV OPRD&lt;/code&gt;
如果$OPRD$是单字节数
意思是$AX/OPRD$
结果：AL=商，AH=余数
如果$OPRD$是双字节数
意思是$DX,AX/OPRD$
结果：AX=商，DX=余数&lt;/p&gt;
&lt;h3 id=&#34;算数移位指令&#34;&gt;算数移位指令
&lt;/h3&gt;
&lt;h4 id=&#34;非循环移位&#34;&gt;非循环移位
&lt;/h4&gt;
&lt;p&gt;算数移位，逻辑移位
左移，右移&lt;/p&gt;
&lt;h4 id=&#34;循环移位&#34;&gt;循环移位
&lt;/h4&gt;
&lt;p&gt;分为带进位移位和不带进位移位&lt;/p&gt;
&lt;h2 id=&#34;存储器&#34;&gt;存储器
&lt;/h2&gt;
&lt;p&gt;RAM（Random-Acess Memory）一般可分为SRAM（静态RAM），DRAM（动态RAM）
ROM（Read Only Memory）一般可分为 掩膜ROM，一次性可写ROM，EPROM，EEPROM，闪速存储器Flash&lt;/p&gt;
&lt;p&gt;高位地址，选通芯片
低位地址，选芯片的读写单元&lt;/p&gt;
&lt;p&gt;译码，将输入的一组高位地址信号通过变换，产生一个有效的输出信号，用于选中某一个存储器芯片，从而确定了该存储器芯片在内存的地址范围&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;全地址译码&lt;/strong&gt;
用全部高位地址信号作为译码信号，使得存储器芯片的每一个单元都占据一个唯一的内存地址
&lt;strong&gt;部分地址译码&lt;/strong&gt;
用部分高位地址信号作为译码信号，使得被选中存储器芯片占有几组不同的地址范围&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cache高速缓冲器&lt;/strong&gt;
Cache高速缓冲存储器，Cache是构成内存储器的部件之一，设置Cahce的原因是内存的速度与处理器的工作速度不匹配&lt;/p&gt;
&lt;p&gt;微机中的存储器系统&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Cache存储器系统&lt;/li&gt;
&lt;li&gt;虚拟存储器系统
&lt;strong&gt;Cache存储系统&lt;/strong&gt;
Cache存储系统主要有Cache高速缓冲器和主内存构成，有硬件系统负责管理&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;io系统&#34;&gt;IO系统
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;输入输出系统&lt;/strong&gt;
在计算机系统中，通常把处理器和主存储器之外的部分统称为输入/输出系统， 包括输入/输出设备、输入/输出接口和输入/输出软件&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IO接口&lt;/strong&gt;
IO接口就是外设连接到系统总线上的一组逻辑电路的总称&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IO端口&lt;/strong&gt;
端口是接口电路中用于缓存数据及控制信息的部件
CPU与I/O接口进行通信实际上是通过I/O接口内部的一组寄存器实现的，这些寄存器通常称为I/O端口（I/O Port）。它包括3种类型：&lt;strong&gt;数据端口、状态端口和命令（控制）端口&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IO端口编址方式&lt;/strong&gt;
分为统一编址和独立编址&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I/O端口与内存单元统一编址，指令及控制信号统一，内存地址资源减少&lt;/li&gt;
&lt;li&gt;I/O端口独立编址，内存地址资源充分利用，使用不同的控制信号，能够应用于端口的指令较少&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;输入接口需要具备数据控制能力，一般采用三态门接口，防止外设的输入影响数据总线，如74LS244&lt;/p&gt;
&lt;p&gt;输出接口需要具备数据锁存能力，一般采用锁存器接口，如74LS273&lt;/p&gt;
&lt;h4 id=&#34;基本输入输出方式&#34;&gt;基本输入输出方式
&lt;/h4&gt;
&lt;p&gt;1.无条件传送方式
2.查询方式
3.中断方式
4.直接存储器存取方式（DMA）&lt;/p&gt;
&lt;h2 id=&#34;中断&#34;&gt;中断
&lt;/h2&gt;
&lt;p&gt;CPU执行程序中，由于发生了某种随机的事件(外部或内部)，引起CPU暂时 中断正在运行的程序，转去执行一段特殊的服务程序(称为中断服务程序或 中断处理程序)，以处理该事件，该事件处理完后又返回被中断的程序继续 执行，这一过程称为中断
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E4%B8%AD%E6%96%AD%E4%B8%80%E8%88%AC%E8%BF%87%E7%A8%8B.png&#34;
	width=&#34;664&#34;
	height=&#34;790&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E4%B8%AD%E6%96%AD%E4%B8%80%E8%88%AC%E8%BF%87%E7%A8%8B_hu8553328482153604593.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-%E4%B8%AD%E6%96%AD%E4%B8%80%E8%88%AC%E8%BF%87%E7%A8%8B_hu8640506032818885660.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;84&#34;
		data-flex-basis=&#34;201px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;中断响应过程&#34;&gt;中断响应过程
&lt;/h4&gt;
&lt;h5 id=&#34;可屏蔽外部中断响应过程&#34;&gt;可屏蔽外部中断响应过程
&lt;/h5&gt;
&lt;p&gt;通过两个连续的中断响应总线周期获取中断类型码
获取中断向量后并调用中断，服务程序&lt;/p&gt;
&lt;h5 id=&#34;内部中断响应过程&#34;&gt;内部中断响应过程
&lt;/h5&gt;
&lt;p&gt;无中断响应总线周期
中断类型码固定或由指令（INT n）给出&lt;/p&gt;
&lt;h2 id=&#34;主要芯片&#34;&gt;主要芯片
&lt;/h2&gt;
&lt;h3 id=&#34;1计数器8253&#34;&gt;1.计数器8253
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8253%E8%AE%A1%E6%97%B6%E5%99%A8.png&#34;
	width=&#34;1571&#34;
	height=&#34;1022&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8253%E8%AE%A1%E6%97%B6%E5%99%A8_hu7755516545594645311.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8253%E8%AE%A1%E6%97%B6%E5%99%A8_hu11752557453604915962.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;153&#34;
		data-flex-basis=&#34;368px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;特殊引脚&#34;&gt;特殊引脚
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;CLK——时钟脉冲输入&lt;/li&gt;
&lt;li&gt;GATE——门控信号输入&lt;/li&gt;
&lt;li&gt;OUT——定时输出&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;编程方式&#34;&gt;编程方式
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;控制字直接写入控制寄存器&lt;/li&gt;
&lt;li&gt;计数值写入对应计数器&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;工作方式&#34;&gt;工作方式
&lt;/h4&gt;
&lt;p&gt;总览&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;16位减法计数，计数值减为0时输出相应控制信号&lt;/li&gt;
&lt;li&gt;输出控制信号的形式可通过软件设置&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&#34;方式0计数结束中断&#34;&gt;方式0——计数结束中断
&lt;/h5&gt;
&lt;p&gt;软件启动，不自动重复计数
计时结束输出高电平，输出可以用作中断请求信号&lt;/p&gt;
&lt;p&gt;不自动重复计数是指   &lt;strong&gt;每写入一次计数初值只计数一个周期&lt;/strong&gt;&lt;/p&gt;
&lt;h5 id=&#34;方式1可重复触发的单稳态触发器&#34;&gt;方式1——可重复触发的单稳态触发器
&lt;/h5&gt;
&lt;p&gt;硬件启动，不自动重复计数
但是可以通过GATE重复触发计数，当GATE出现上升沿时，下一个CLK的下降沿开始计数
计数结束后，OUT端输出高电平&lt;/p&gt;
&lt;h5 id=&#34;方式2频率发生器&#34;&gt;方式2——频率发生器
&lt;/h5&gt;
&lt;p&gt;既可以软件启动，也可以硬件启动
自动重复计数，OUT端输出N-1个时钟周期的高电平，1个时钟周期的低电平&lt;/p&gt;
&lt;h5 id=&#34;方式3方波发生器&#34;&gt;方式3——方波发生器
&lt;/h5&gt;
&lt;p&gt;软硬件启动，自动重复计数
输出对称方波（连续方波）
N为偶数，完全对称，N为奇数，正脉冲会长一点&lt;/p&gt;
&lt;h5 id=&#34;方式4软件触发选通&#34;&gt;方式4——软件触发选通
&lt;/h5&gt;
&lt;p&gt;软件启动，不自动重复计数
计数结束输出一个CLK宽度的低电平&lt;/p&gt;
&lt;h5 id=&#34;方式5硬件触发选通&#34;&gt;方式5——硬件触发选通
&lt;/h5&gt;
&lt;p&gt;硬件启动，不自动重复计数
波形与方式4一致，计数结束输出一个CLK宽度的低电平&lt;/p&gt;
&lt;h4 id=&#34;小结&#34;&gt;小结
&lt;/h4&gt;
&lt;p&gt;需要两个写脉冲——两次写操作&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;第一次写脉冲写入控制字&lt;/li&gt;
&lt;li&gt;第二次写脉冲写入计数初值&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;能输出连续波形的只有方式2和方式3&lt;/p&gt;
&lt;h3 id=&#34;2可编程并行接口8255&#34;&gt;2.可编程并行接口8255
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8255.png&#34;
	width=&#34;1102&#34;
	height=&#34;758&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8255_hu13140301037335165003.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8255_hu378289627695085032.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;145&#34;
		data-flex-basis=&#34;348px&#34;
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;三个端口&#34;&gt;三个端口
&lt;/h4&gt;
&lt;p&gt;A口：支持0，1，2工作方式
B口：支持0，1工作方式
C口，支持0工作方式&lt;/p&gt;
&lt;h4 id=&#34;工作方式-1&#34;&gt;工作方式
&lt;/h4&gt;
&lt;h5 id=&#34;方式0基本输入输出方式&#34;&gt;方式0——基本输入输出方式
&lt;/h5&gt;
&lt;h5 id=&#34;方式1选通工作方式&#34;&gt;方式1——选通工作方式
&lt;/h5&gt;
&lt;p&gt;方式1输出接口A&lt;/p&gt;
&lt;p&gt;$\overline {OBF}$：接口输出缓冲器满信号，告诉外设可以从该端口读走信号
$\overline {ACK}$：外设从端口取走数据，发出响应信号
外设取走信号后，发出$\overline {ACK}$响应信号，同时使$\overline {OBF}=1$，同时还会产生一个有效的$INTR$信号&lt;/p&gt;
&lt;p&gt;方式1输入接口A&lt;/p&gt;
&lt;p&gt;$\overline {{STB}_A}$：外设写入
${{IBF}_A}$：当输入缓冲器满后，接口发出的高电平有效信号&lt;/p&gt;
&lt;h5 id=&#34;方式2双向传送方式&#34;&gt;方式2——双向传送方式
&lt;/h5&gt;
&lt;p&gt;可以既作为输入口，又作为输出口
只有A口可以工作在此模式下，当A口工作在方式2时，B口可以工作在方式0或1&lt;/p&gt;
&lt;h4 id=&#34;控制字&#34;&gt;控制字
&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8255%E5%B9%B6%E8%A1%8C%E6%8E%A5%E5%8F%A3%E6%8E%A7%E5%88%B6%E5%AD%97.png&#34;
	width=&#34;1179&#34;
	height=&#34;789&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8255%E5%B9%B6%E8%A1%8C%E6%8E%A5%E5%8F%A3%E6%8E%A7%E5%88%B6%E5%AD%97_hu14765288225054634413.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8255%E5%B9%B6%E8%A1%8C%E6%8E%A5%E5%8F%A3%E6%8E%A7%E5%88%B6%E5%AD%97_hu8589257034260744238.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;149&#34;
		data-flex-basis=&#34;358px&#34;
	
&gt;
方式控制字：用于确定3个端口的工作方式及数据传送方向
位控制字：仅用于C端口，可设置C口某位的初始状态（高低电平）&lt;/p&gt;
&lt;p&gt;D7=1，方式控制字
D7=0，位控制字&lt;/p&gt;
&lt;h3 id=&#34;3da转换芯片dac0832&#34;&gt;3.DA转换芯片DAC0832
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-DAC0832.png&#34;
	width=&#34;1176&#34;
	height=&#34;806&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-DAC0832_hu14063487422228576702.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-DAC0832_hu4722366844357209555.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;145&#34;
		data-flex-basis=&#34;350px&#34;
	
&gt;
差动输出，双缓冲&lt;/p&gt;
&lt;h4 id=&#34;工作方式-2&#34;&gt;工作方式
&lt;/h4&gt;
&lt;h5 id=&#34;单缓冲工作方式&#34;&gt;单缓冲工作方式
&lt;/h5&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-DAC0832%E5%8D%95%E7%BC%93%E5%86%B2%E6%96%B9%E5%BC%8F.png&#34;
	width=&#34;673&#34;
	height=&#34;402&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-DAC0832%E5%8D%95%E7%BC%93%E5%86%B2%E6%96%B9%E5%BC%8F_hu11514619749141126763.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-DAC0832%E5%8D%95%E7%BC%93%E5%86%B2%E6%96%B9%E5%BC%8F_hu4258811121347970124.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;167&#34;
		data-flex-basis=&#34;401px&#34;
	
&gt;&lt;/p&gt;
&lt;h5 id=&#34;双缓冲工作方式&#34;&gt;双缓冲工作方式
&lt;/h5&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-DAC0832%E5%8F%8C%E7%BC%93%E5%86%B2%E5%B7%A5%E4%BD%9C%E6%96%B9%E5%BC%8F.png&#34;
	width=&#34;500&#34;
	height=&#34;878&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-DAC0832%E5%8F%8C%E7%BC%93%E5%86%B2%E5%B7%A5%E4%BD%9C%E6%96%B9%E5%BC%8F_hu11817361872452783474.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-DAC0832%E5%8F%8C%E7%BC%93%E5%86%B2%E5%B7%A5%E4%BD%9C%E6%96%B9%E5%BC%8F_hu12455462119672804061.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;56&#34;
		data-flex-basis=&#34;136px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;4ad转换芯片adc0809&#34;&gt;4.AD转换芯片ADC0809
&lt;/h3&gt;
&lt;h3 id=&#34;5可编程中断控制器8259a&#34;&gt;5.可编程中断控制器8259A
&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259A.png&#34;
	width=&#34;1053&#34;
	height=&#34;724&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259A_hu10206134159472984562.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259A_hu7535512307012891829.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;145&#34;
		data-flex-basis=&#34;349px&#34;
	
&gt;&lt;/p&gt;
&lt;h5 id=&#34;特殊引脚-1&#34;&gt;特殊引脚
&lt;/h5&gt;
&lt;p&gt;$INT$：接CPU的中断请求引脚
$\overline {INTA}$：接CPU的中断响应引脚
$A0$：8259A内部寄存器选择信号
$CAS0-CAS2$：多个8259级联引脚时使用，级联控制线
$\overline {SP}$：在非缓冲模式下，用来指定8259A是从片还是主片，$\overline {SP}$=1的8259是主片&lt;/p&gt;
&lt;h5 id=&#34;内部结构&#34;&gt;内部结构
&lt;/h5&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259%E5%86%85%E9%83%A8%E7%BB%93%E6%9E%84.png&#34;
	width=&#34;1102&#34;
	height=&#34;712&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259%E5%86%85%E9%83%A8%E7%BB%93%E6%9E%84_hu8084468173589079257.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259%E5%86%85%E9%83%A8%E7%BB%93%E6%9E%84_hu6595531071189504617.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;154&#34;
		data-flex-basis=&#34;371px&#34;
	
&gt;&lt;/p&gt;
&lt;h5 id=&#34;工作过程&#34;&gt;工作过程
&lt;/h5&gt;
&lt;p&gt;&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259A%E7%9A%84%E5%B7%A5%E4%BD%9C%E8%BF%87%E7%A8%8B.png&#34;
	width=&#34;1081&#34;
	height=&#34;719&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259A%E7%9A%84%E5%B7%A5%E4%BD%9C%E8%BF%87%E7%A8%8B_hu4638044446882469720.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259A%E7%9A%84%E5%B7%A5%E4%BD%9C%E8%BF%87%E7%A8%8B_hu17404546974619976441.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;150&#34;
		data-flex-basis=&#34;360px&#34;
	
&gt;&lt;/p&gt;
&lt;h5 id=&#34;工作方式-3&#34;&gt;工作方式
&lt;/h5&gt;
&lt;h6 id=&#34;中断优先方式与中断嵌套&#34;&gt;中断优先方式与中断嵌套
&lt;/h6&gt;
&lt;p&gt;（1）固定优先级方式
（2）循环优先级方式&lt;/p&gt;
&lt;h6 id=&#34;屏蔽中断源的方式&#34;&gt;屏蔽中断源的方式
&lt;/h6&gt;
&lt;p&gt;普通屏蔽方式：对IMR某位置1，则屏蔽该位对应的中断请求&lt;/p&gt;
&lt;h6 id=&#34;级联工作方式&#34;&gt;级联工作方式
&lt;/h6&gt;
&lt;p&gt;（1）主片、从片有不同的地址
（2）主片、从片分别进行编程&lt;/p&gt;
&lt;h5 id=&#34;8259a的编程&#34;&gt;8259A的编程
&lt;/h5&gt;
&lt;h6 id=&#34;初始化编程&#34;&gt;初始化编程
&lt;/h6&gt;
&lt;p&gt;初始化命令字ICW1（初始化字）：单片/多片级联、电平/边沿触发
初始化命令字ICW2（中断向量码）：给CPU提供中断向量
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259AICW1&amp;amp;2.png&#34;
	width=&#34;1098&#34;
	height=&#34;787&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259AICW1&amp;amp;2_hu10199151641521457777.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259AICW1&amp;amp;2_hu10928153089286359980.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;139&#34;
		data-flex-basis=&#34;334px&#34;
	
&gt;
注意：例如，写入ICW1，端口地址为20H，写入ICW2时，端口地址为21H&lt;/p&gt;
&lt;p&gt;初始化命令字ICW3（级联控制字）：指出哪个引脚进行了级联
&lt;img src=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259AICW3.png&#34;
	width=&#34;933&#34;
	height=&#34;617&#34;
	srcset=&#34;https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259AICW3_hu4193772609768098813.png 480w, https://NomadJoeviolet.github.io/p/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86-8259AICW3_hu14172121435931954740.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;151&#34;
		data-flex-basis=&#34;362px&#34;
	
&gt;
初始化命令字ICW4（中断结束方式字）：给出8259A结束中断处理的方式&lt;/p&gt;
&lt;h6 id=&#34;操作方式编程&#34;&gt;操作方式编程
&lt;/h6&gt;
&lt;p&gt;操作命令字OCW1（中断屏蔽字）：某位为1则该引脚中断被屏蔽
操作命令字OCW2（中断结束和优先级循环）：指定优先级顺序和中断结束方式
操作命令字OCW3（屏蔽方式和状态读出控制字）：设置特殊屏蔽、查询方式&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
