06-ADC

ADC简介  Analog-Digital Converter 模拟-数字转换器

ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁。

12位逐次逼近型ADC,1us转换时间;输入电压范围:0-3.3V,转换结果范围0-4095;18个输入通道,可测量16个外部和2个内部信号源;规则组和注入组两个转换单元;模拟看门狗自动检测输入电压范围。

        数字到模拟的桥梁:PWM或DAC。目前DAC的主要应用是在波形生成这些领域,比如信号发生器、音频解码芯片等。

ADC参数:分辨率、转换速度。输入电压范围。

        16个外部信号就是GPIO口,可在引脚上直接测模拟信号即可。2个内部信号时内部温度传感器和内部参考电压,温度传感器可以测量CPU的温度,内部参考电压是一个1.2V左右的基准电压,基准电压是不随外部供电电压变化而变化的。

        规则组和注入组两个转换单元,是STM32ADC的增强功能。普通的AD转换流程是,启动一次转换,读一次值,然后再启动,再读值。STM32的ADC可以列一个组,一次性启动一个组,连续转换多个值,并且有两个组,一个是用于常规使用的规则组,一个是用于突发事件的注入组。

        ADC可以用模拟看门狗来自动执行,模拟看门狗可以检测指定的某些通道,当AD值高于它设定的上阈值或者低于下阈值时,就会申请中断可以在中断函数里执行相应的操作。就不用不断地手动读值,再进行判断了。

逐次逼近型ADC0809

        逐次逼近型ADC0809的内部结构,了解这个结构对学习STM32的ADC帮助很大。在以前芯片集成功能不强的时候,需要外挂一个ADC芯片进行AD转换。

        左边IN0-IN7,是8路输入通道,通过通道选择开关,选中一路,输入到一点进行转换。地址锁存和译码是一个多路选择开关的作用。输入信号进入到比较器后,通过逐次逼近的方法来获取电压对应的编码数据。

        DAC内部使用加权电阻网络来实现的转换。如果DAC输出的电压比较大,就调小DAC数据,如果比较小,就增大DAC数据,直到DAC输出的电压和外部通道输入的电压近似相等。这样DAC输入的数据就是外部电压的编码数据。

        电压调节的过程是逐次逼近SAR来完成的,为了最快找到未知电压的编码,通常我们会使用二分法进行寻找,会发现128,64,32这些数据,正好是二进制每一位的位权,判断过程就是二进制从高位到低位依次判断是1还是0的过程。这就是逐次逼近型名字的由来。

EOC End Of Convert 转换结束信号;

START 开始转换,给一个输入脉冲,开始转换;

CLOCK 是ADC的时钟,因为ADC内部是一步一步进行判断的。 需要时钟来推动这个过程;

VREF+和VREF-是DAC的参考电压,参考电压决定ADC的输入范围。通常低要求时,参考电压的正极和VCC接到一起、参考电压的负极和GND接在一起。

STM32的ADC

一般手册里,每个外设的最前面都有一个整体的结构图,这个结构图是非常重要的,需要多花时间看看。

        左边IN0-IN15是ADC的16个GPIO外部输入通道;VREFINT (V Reference Internal),内部参考电压;温度传感器。总共18个通道,到一个模拟多路开关,指定我们想要选择的通道。进入模数转换器,执行逐次比较,将转换结果放在数据寄存器里,用户读取寄存器获取ADC转换数值。

        普通的ADC,多路开关一般只选中一个的。但是此ADC可以同时选中多个,而且在转换时还分成了两个组,规则通道组和注入通道组,其中规则组一次性最多选中16个通道,注入组最多可以选中4个通道。
举个例子:就像是去餐厅点菜,普通的ADC是指定一个菜,老板给你做,然后做好了送给你,这里就是指定一个菜单,这个菜单最多可以填16个菜,直接把菜单寄给老板,老板就按照菜单的顺序依次做好,一次性给你端上菜,这样的话可以大大提高效率,这样这个菜单就简化成普通的模式了。那对于这个菜单也有两种,一种规则组菜单,可以同时上16个菜,有个尴尬的地方,就是这个规则组只有一个数据寄存器,就是这个桌子比较小,最多只能放一个菜,如果要上16个菜,那不好意思,前15个菜都会被挤掉,只能得到第16个菜,所以对于规则组转换来说,如果使用这个菜单的话,最好配合DMA来实现,DMA是一个数据转运小帮手,它可以在每上一个菜之后,把这个菜挪到其他地方去,防止被覆盖。

规则组虽然可以同时转换16个通道,但是数据寄存器只能存一个结果,如果不想之前的结果被覆盖,那在转换之后,就要尽快把结果拿走。
注入组就比较高级了,相当于餐厅的VIP座,在这个座位上,一次性最多可以点4个菜,并且这里数据寄存器有4个,是可以同时上4个菜的,对于注入组而言,就不用担心数据覆盖的问题了,一般情况下,使用规则组就完全足够了。如果要使用规则组的菜单,那就再配合DMA转运数据,就不用担心数据覆盖的问题。

注入组的操作:涉及的不多,可以看手册自行了解。
规则组的操作:先看模数转换器外围的一些线路,首先左下角是触发转换的部分,也就是ADC0809的START信号,开始转换。
对于STM32的ADC,触发ADC开始转换的信号有两种,一种是软件触发,就是在程序中手动调用一条代码,就可以启动转换了;另一种是硬件触发,就是这里的这些触发源。上面是注入组的触发源,下面是规则组的触发源。这些触发源主要是来自于定时器,,有定时器的各个通道,还有TRGO定时器主模式的输出,定时器可以通向ADC、DAC这些外设,用于触发转换,因为ADC经常需要过一个固定时间段转换一次,比如每隔1ms转换一次。正常的思路就是用定时器,每隔1ms申请一次中断,在中断里手动开始一次转换,这样也是可以的。但是频繁进中断对我们的程序是由一定影响的。
比如有很多中断都需要频繁进入,那肯定会影响主程序的执行,并且不同中断之间,由于优先级的不同,也会导致某些中断不能及时得到响应。那我们ADC的转换频率就肯定会产生影响了,所以对于这种需要频繁进中断,并且在中断里只完成了简单工作的情况,一般都会有硬件的支持。
比如这里给TIM3定1ms的时间,并且把TIM3的更新事件选择为TRGO输出,然后在ADC这里,选择开始触发信号为TIM3的TRGO,这样TIM3的更新事件就能通过硬件自动触发ADC转换了,整个过程不需要进中断,节省了中断资源。这就是这里定时器的触发作用。
当然这里还可以选择外部中断引脚来触发转换,都可以在程序中配置。

ADCCLK是ADC的时钟,相当于0809的CLOCK,用于驱动内部逐次比较的时钟。ADC预分频器来源于RCC。
DMA的请求:是用于触发DMA进行数据转运的,DMA章节再讲。


两个数据寄存器,是用于存放转换结果的。
        模拟看门狗,里面可以存一个阈值高限和阈值低限,如果启动了模拟看门狗,并指定了看门的通道,那这个看门狗就会关注它看门的通道,一旦超过这个阈值范围了,它就会乱叫,就会在上面,申请一个模拟看门狗的中断,最后通向NVIC。

        然后对于规则组和注入组而言,它们转换完成之后,也会有一个EOC规则组转换完成的信号,JEOC是注入组完成的信号,这两个信号会在状态寄存器里置一个标志位,我们读取这个标志位,就能知道是不是转换结束了,同时这两个标志位也可以去NVIC,申请中断,如果开启了NVIC对应的通道,它们就会触发中断,。

ADC基本结构图

左边是输出通道,16个GPIO口,外加两个内部的通道,然后进入AD转换器(有两个组,一个规则组,一个注入组),规则组最多可以选中16个通道,注入组最多可以选择4个通道,然后转换的结果可以存放在AD数据寄存器里,其中规则组只有1个数据寄存器,注入组有4个,触发控制提供了开始转换这个START信号,触发控制可以选择软件触发和硬件触发。硬件触发主要是来自于定时器,当然也可以选择外部中断的引脚,右边这里是来自于RCC的ADC时钟CLOCK,ADC的逐次比较的过程就是由这个时钟推动的。然后上面可以布置一个模拟看门狗用于监测转换结果的范围。

最后右下角还有一个开关控制,在库函数中,就是ADC_Cmd函数,用于给ADC上电的,这些就是STM32 ADC的内部结构了。

接下来是一些细节问题:

ADC12_IN0的意思是这个引脚是ADC1和ADC2的IN0都是在PA0上的。
ADC的一个高级功能:双ADC模式,这个模式比较复杂,暂时简单了解,不需要掌握。
双ADC模式就是ADC1和ADC2一起工作,它俩可以配合组成同步模式、交叉模式等等模式,比如交叉模式:ADC1和ADC2交叉地对一个通道进行采样,就可以进一步提高采样率。当然ADC1和ADC2可以分开使用。可以分别对不同的引脚进行采样。

规则组的4种转换模式:

在ADC初始化的结构体里,会有两个参数:一个是选择单次转换还是连续转换的,另一个是选择非扫描模式还是扫描模式,这两个参数组合起来,就有4种转换方式。

单次转换,每触发一次,转换结束后,就会停下来,下次转换得再触发才能开始。

连续转换:一次转换完成后,立刻开始下一次的转换。

非扫描模式:所以菜单列表就只用第一个。

扫描模式:一次可以转换多个序列,但需要使用DMA进行数据转运。

单次转换-非扫描模式:

        最简单的一种模式。序列是规则组里的菜单,有16个空位,分别是序列1到序列16。可以写入要转换的通道,在非扫描的模式下,只有序列1的位置有效。在序列1的位置指定我们想转换的通道,比如通道2,写到这个位置,然后以触发转换,ADC就会对这个通道2进行模数转换。转换结果放在数据寄存器里,同时给EOC标志位置1。我们判断这个EOC标志位,如果转换完了,如果想再启动一次转换,那就需要再触发一次,转换结束,置EOC标志位,读结果。
        如果想换一个通道转换,那在转换之前,把第一个位置的通道2改成其他通道,然后再启动转换,这样就行了。


连续转换-非扫描模式

       与单次转换不同的是,它在一次转换结束后不会停止,而是立刻开始下一轮的转换。好处:开始转换之后不需要等待一段时间的,因为它一直在转换,所以就不需要手动,也不用判断是否结束,想要读AD值的时候,直接从数据寄存器取就可以了。

单次转换-扫描模式

        
        扫描模式就用到这个菜单列表了,可以在这个菜单里点菜,比如第一个菜是通道2,第二个菜是通道5,等等,这里每个位置是通道几可以任意指定,并且也是可以重复的。然后初始化结构体有个参数,就是通道数目,因为这16个通道可以不用完,只用前几个,那就需要再给他一个通道数目的参数。告诉它,我有几个通道,比如这里指定通道数目为7,那它就只看前7个位置,然后每次触发之后,它就一次对这前7个位置进行AD转换,转换结构都放在数据寄存器里,这里为了防止数据被覆盖,就需要用DMA及时将数据挪走,那7个通道转换完成之后,产生EOC信号,转换结束,然后再触发下一次,就开始新一轮的转换。

连续转换-扫描模式

        当然在扫描模式的情况下,还可以有一种模式,叫间断模式,它的作用是,在扫描的过程中,每隔几个转换,就暂停一次。需要再次触发,才能继续,这个模式没有列出来,不然要列出来的太多了。

触发控制

        这个表是规则组的触发源:有来自引脚或定时器的信号,具体是引脚还是定时器,需要用AFIO重映射来确定。软件控制位也就是我们之前说的软件触发。这些触发信号怎么选择,可以通过设置右边的寄存器来完成,当然使用库函数的话,直接给一个参数就行了。这就是触发控制。

数据对齐

        ADC是12位的,它的转换结果是一个12位的数据,但寄存器是16位的,所以就存在一个数据对齐的问题。12位的数据向右靠,高位多出来几位补0;12位的数据向左靠,低位多出来的几位补0。

        一般使用右对齐:在读取16位寄存器直接就是转换结果。

        左对齐用途:如果你不需要高分辨率,觉得0-4095太大了,就做个简单的判断,可以选择左对齐,把数据的高8位取出来,舍弃后4位的精度。当然也可以把12位都取出来。

转换时间

AD转换的步骤:采样、保持、量化、编码

STM32ADC的总采样时间:Tconv=采样时间+12.5个ADC周期

例如:当ADCCLK=14MHz,采样时间位1.5个ADC周期,Tconv=1.5+12.5=14个ADC周期=1us

一般不敏感,因为一般AD转换都很快,如果不需要非常高速的转换频率,那转换时间就可以忽略了,AD转换需要一小段时间,就像厨子做菜一样,也需要等待一会才能上菜的。
采样保持可以放在一起,量化编码可以放在一起,总共是这两大步。量化编码就是之前讲的ADC逐次比较的过程。这个需要花一段时间,一般位数越多,花的时间就越长。
采样保持是因为 AD转换后面的量化编码,是需要一小段时间的,如果在这一小段时间里,输入电压还在不断变化,那就没法定位输入电压到底在哪里了,所以在量化编码之前,需要设置一个采样开关,比如可以用一个小容量的电容存储一下这个电压,存储好了之后,断开采样开关,在进行后面的AD转换。这样在量化编码的过程中,电压始终保持不变,这就是采样保持电路。
那采样保持的过程,需要闭合采样开关,过一段时间再断开,这里就会产生一个采样时间,那回到这里这里,我们就得到了第二条。
采样时间就是采样保持花费的时间,这个可以在程序中进行配置,采样时间越大,越能避免一些毛刺信号的干扰,不过转换时间也会相应延长,12.5个ADC周期是量化编码花费的时间,因为是12位的ADC,所以需要花费12个周期,这里多了半个周期,可能是做其他一些东西画的时间。ADC周期就是从RCC分频过来的ADCCLK,这个ADCCLK最大是14MHz,所以下面有个例子,这里就是最快的转换时间。

如果采样周期再长些,它就达不到1us了,另外也可以把ADCCLK的时钟设置超过14MHz,这样就是在超频了,那转换时间可以比1us还短,不过这样稳定性就没办法保证了

听起来很复杂,但是这个校准我们暂时不需要理解,因为校准过程是固定的,我们只需要在ADC初始化最后,加几条代码就行了,至于怎么计算,怎么校准的,我们不需要管,所以了解一下就行了

ADC的外围电路
第一个是电位器产生一个可调的电压,电阻阻值不能给的太小,
第二个是传感器输出电压的电路,一般来说,像光敏电阻,热敏电阻,红外接收管,麦克风等等,都可以等效为一个可变电阻,所以这里就可以通过和一个固定电阻串联分压,这个福鼎电阻一般可以选择和传感器阻值相近的电阻。这样可以得到一个位于中间电压区域比较好的输出。
第三个是电压转换电路,使用电阻进行分压,但是如果是高电压采集最好使用一些专用的采集芯片,比如隔离放大器等等,做好高低电压的隔离,保证电路的安全

手册介绍:
见参考手册。

代码步骤:
1.开启RCC时钟,包括ADC和GPIO的时钟,另外ADCCLK的分频器,也需要配置一下
2.配置GPIO,把需要用到的GPIO配置成模拟输入的模式
3.配置多路开关,把左边的通道接入到右边的规则组列表里,这个过程就是我们之前说的点菜,把各个通道的菜,列在菜单里
4.配置ADC转换器,在库函数里,是用结构体来配置的,可以配置这一大块电路的参数。包括ADC是单次转换还是连续转换、扫描还是非扫描、有几个通道、触发源是什么、数据对齐是左对齐还是右对齐,这一大批参数,用一个结构体配置就可以了,如果需要模拟看门狗,那会有几个函数用来配置阈值和监测通道的,那就在中断输出控制里ITConfig函数开启对应的中断输出,然后再在NVIC里,配置一下优先级,这样就能触发中断了。不过这一块模拟看门狗和中断,本节暂时不用。
开关控制,调用一下ADC_Cmd函数,开启ADC,这样ADC就配置完成了,就能正常工作了,当然在开启ADC之后,根据手册里的建议,还可以对ADC进行一下校准,这样可以减小误差,那在ADC工作的时候,如果想要软件触发转换,那会有函数可以触发,如果想读取转换结果,那也会有函数可以读取结果
配置程序的大致思路。

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);
配置ADCCLK分频器的,它可以对应APB2的72MHz时钟选择2、4、6、8分频,输入到ADCCLK

DeInit恢复缺省设置、Init初始化、StructInit结构体初始化
ADC_Cmd是用于给ADC上电的,
DMACmd是用于开启DMA输出信号的
ITConfig中断输出控制,用于控制某个中断,能不能通往NVIC
ADC_ResetCalibration 复位校准
ADC_GetResetCalibrationStatus 获取复位状态
ADC_StartCalibration 开始校准
ADC_GetCalibrationStatus 获取开始校准状态
在ADC初始化完成之后,依次调用就行了。
然后继续,ADC软件开始控制转换,就是这个用于软件触发的函数了 ADC_SoftwareStartConvCmd
ADC获取软件开始转换状态 ADC_GetSoftwareStartConvStatus
从名字上来看,这个函数好像是判断是不是正在进行的,那我们可不可以调用这个函数,来判断转换是否已经结束呢,这个可以分析一下源码,源码分析可得这个函数的返回值跟转换是否结束,毫无关系

ADC_GetFlagStatus 获取标志位状态,知道转换是否结束,然后参数给EOC的标志位,判断EOC标志位是不是置1了,如果转换结束,EOC标志位置1,然后调用这个函数,判断这个标志位,这样才是正确的判断转换是否结束的方法。
所以简单俩说, ADC_GetSoftwareStartConvStatus这个函数其实没啥用,我们一般不用,不要被他误导了

下面两个函数是用来配置间断模式的
ADC_DiscModeChannelCountConfig 是每隔几个通道间断一次,
ADC_DiscModeCmd 是不是启用间断模式,需要间断模式的话可以理解一下,

void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); ADC_规则组通道配置,这个函数比较重要,它的作用是给序列的每个位置填写指定的通道,就是填写点菜菜单的过程,第一个参数ADCx,第二个ADC_Channel,就是想要指定的通道,第三个Rank,就是序列几的位置,第四个SampleTime指定通道的采样时间

ADC_ExternalTrigConvCmd 外部触发控制转换,就是是否允许外部触发转换,
ADC_GetConversionValue 是ADC获取转换值,这个函数也比较重要,获取AD转换的数据寄存器,读取转换结果就要使用这个函数
ADC_GetDualModeConversionValue ADC获取双模式转换值,这个是双ADC模式读取转换结果的函数

以上函数就是对ADC的一些基本功能和规则组的配置,

接下来的一大批函数里面都带了一个Injected,就是注入组的意思,所以一大批函数都是对ADC注入组进行配置的,注入组暂时不多讲,

这三个函数就是对模拟看门狗进行配置的,第二个是配置高低阈值、第三个是配置看门的通道、之后ADC温度传感器、内部参考电压控制、如果要用到这两个通道,那得调用这个函数,开启一下,要不然是读不到正确的结果,这个要注意一下。

最后四个,获取标志位状态,清除标志位,获取终端状态,清除终端挂起位。常用函数,不多说。

EOC看手册得知,是规则或注入。这一点需要看参考手册进行笔记的修改。

如果想要用扫描模式实现多通道,最好要配合DMA来实现,

可能会问:一个通道转换完成之后,手动把数据转运出来,不就行了,为啥非要用DMA来转运呢,这个方案看似简单,实际操作起来会有一些问题,第一个就是在扫描模式下,你启动列表之后,它里面每一个单独的通道转换完成之后,不会产生任何的标志位,也不会触发中断,你不知道某一个通道是不是转换完了,它只有在整个列表都转换完成之后,才会产生一次EOC标志位,才能触发中断,而这时,前面的数据就已经覆盖丢失了。
第二个问题:AD转换是非常快的,通过计算转换一个通道大概只有几us,也就是说,如果你不能在几us的时间内把数据转运走,那数据就会丢失,这对于我们程序手动转运数据,要求就比较高,所以在扫描模式下,手动转运数据是比较困难的。
不过比较困难也不是说手动转运不可行,在扫描的时候,每转换一个通道就暂停一次,等我们手动把数据转运走之后,再继续触发,继续下一次转换,这样可以实现手动转运数据的功能,但是由于单个通道转换完成之后,没有标志位,所以启动转换之后,只能通过Delay延时的方法,才能保证转换完成,这种方式既不能让我们省心,也不能提高效率。所以暂不推荐使用

实现多通道一个简单的方法:可以使用单次转换、非扫描的模式。只需要在每次触发转换之前,手动更改一下列表第一个位置的通道就行了,比如第一次转换,先写入通道0,之后触发、等待、读值;第二次转换,再先把通道0改成通道1,之后触发、等待、读值。第三次转换,再先改成通道2,等等,在转换前,先指定一下通道,再启动转换。就可以轻松地实现多通道转换的功能了。

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

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

相关文章

二层综合实验

拓扑图 实验要求 1.内网IP地址使用172.16.6.0/16分配 2.sw1和sW2之间互为备份 3.VRRP/STP/VLAN/Eth-trunk均使用 4.所有Pc均通过DHCP获取IP地址 5.ISP只能配置IP地址 6.所有电脑可以正常访问IsP路由器环回 实验思路 这是一个二层综合实验每当拿到一个实验看清楚要求之后都有…

Java实现pdf中动态插入图片

今天接到一个需求&#xff0c;需要在pdf中的签名处&#xff0c;插入签名照片&#xff0c;但签名位置不固定&#xff0c;话不多说上代码&#xff1a; 1、首先引入itextpdf依赖包&#xff1a; <dependency><groupId>com.itextpdf</groupId><artifactId>…

OpenCV 图形API(2)为什么需要图形API?

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 G-API背后的动机 G-API模块为OpenCV带来了基于图的执行模型。本章简要描述了这种新模型如何在两个方面帮助软件开发者&#xff1a;优化和移植图像处理算法…

基于Spring AI开发本地Jenkins MCP Server服务

前言 首先介绍下MCP是什么&#xff1f; MCP是由开发了 Claude 模型的 Anthropic 公司2024年12月提出并开源的一项开放标准&#xff0c;全称&#xff1a;Model Context Protocol&#xff0c;它是一个开放协议&#xff0c;它使 LLM 应用与外部数据源和工具之间的无缝集成成为可能…

vcpkg安装指定版本的库

一.vcpkg安装 使用git将vcpkg源码克隆到本地制定目录&#xff08;D:\vcpkg&#xff09;&#xff0c;并初始化 git clone https://github.com/microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh # Linux/macOS .\bootstrap-vcpkg.bat # Windows 如下图&#xff1a; 二.安…

数据结构C语言练习(单双链表)

本篇练习题(单链表)&#xff1a; 1.力扣 203. 移除链表元素 2.力扣 206. 反转链表 3.力扣 876. 链表的中间结点 4.力扣 21. 合并两个有序链表 5. 牛客 链表分割算法详解 6.牛客 链表回文结构判断 7. 力扣 160. 相交链表 8. 力扣 141 环形链表 9. 力扣 142 环形链表 II…

nginx部署前端项目(linux、docker)

引言 在CentOS 7系统上使用docker安装nginx&#xff0c;使用nginx部署一个由Vue开发、打包的项目 docker安装nginx 这里不多赘述&#xff0c;直接上docker-compose.yml代码 nginx:container_name: nginximage: nginx:1.27.2ports:- "80:80"volumes:- /docker/ngin…

WPF ContentPresenter详解2

ContentPresenter与ContentControl的区别 ContentControl 和 ContentPresenter 是 WPF 中两个相关的控件&#xff0c;但它们在用途和功能上有一些关键的区别。理解这两者的区别和联系有助于更好地设计和开发用户界面。 1. 类层次结构 ContentControl&#xff1a;位于 WPF 控件…

【HTML5游戏开发教程】零基础入门合成大西瓜游戏实战 | JS物理引擎+Canvas动画+完整源码详解

《从咖啡杯到财务自由&#xff1a;一个程序员的合成之旅——当代码遇上物理引擎的匠心之作》 &#x1f31f; 这是小游戏开发系列的第四篇送福利文章&#xff0c;感谢一路以来支持和关注这个项目的每一位朋友&#xff01; &#x1f4a1; 文章力求严谨&#xff0c;但难免有疏漏之…

鸿蒙OS 5.0 服务能力框架深入剖析

鸿蒙OS 5.0 服务能力框架中关键类的作用分析 1\. 鸿蒙OS 5.0 服务能力框架导论 鸿蒙OS 5.0&#xff0c;亦称鸿蒙智联 5 1&#xff0c;标志着华为在分布式操作系统领域迈出的重要一步。与早期版本采用兼容安卓的AOSP层、Linux内核以及LiteOS内核不同&#xff0c;鸿蒙OS 5.0 专注…

RTMP推流+EasyDSS云服务+边缘AI分析的无人机监控系统设计

在现代科技不断发展的背景下&#xff0c;无人机技术已经广泛应用于各个领域&#xff0c;从航拍摄影到工业巡检&#xff0c;从农业监测到应急救援&#xff0c;无人机以其高效的工作能力&#xff0c;为人们的生活和工作带来了诸多便利与创新&#xff0c;而其视频传输与分析系统更…

HCIP(VLAN综合实验)

实验拓补图 实验分析 一、实验目的 掌握VLAN的创建和配置方法理解VLAN在局域网中的作用学习如何通过VLAN实现网络隔离和通信 二、实验环境 交换机&#xff08;SW1、SW2、SW3&#xff09;个人电脑&#xff08;PC1、PC2、PC3、PC4、PC5、PC6&#xff09;路由器&#xff08;R1…

Linux系统编程 | 线程的基本概念

&#x1f493;个人主页&#xff1a;mooridy &#x1f493;专栏地址&#xff1a;Linux 关注我&#x1f339;&#xff0c;和我一起学习更多计算机的知识! &#x1f51d;&#x1f51d;&#x1f51d; 什么是线程 程序中的一个执行路线就叫做线程 一个进程至少要有一个执行线程,单…

小林coding-12道Spring面试题

1.说一下你对 Spring 的理解?spring的核心思想说说你的理解&#xff1f; 2.Spring IoC和AOP 介绍一下?Spring的aop介绍一下?IOC和AOP是通过什么机制来实现的?怎么理解SpringIoc&#xff1f;依赖倒置&#xff0c;依赖注入&#xff0c;控制反转分别是什么&#xff1f;依赖注…

第十二章——位运算

按位的与& 若x的第i位和y的第i位都是1&#xff0c;那么&#xff08;x&y&#xff09;1&#xff0c;否则&#xff08;x&y&#xff09; 0 应用&#xff1a;希望让某一位或某些位为0 。取一个数中的一段。 按位的或| 若x的第i位1或y的第i位1&#xff0c;那么&…

计算机等级考试数据库三级(笔记3)

插入 修改 现要创建一个具有如下功能的触发器&#xff1a;每当在销售表中插入一条销售记录时&#xff0c;修改商品表中对应商品的销售总量&#xff0c;假设一次只插入一条销售记录。请补全下列代码。CREATE TRIGGER tri insert on xx FOR xx AS xx 商品表 xx 销售总量xx (SELEC…

【Leetcode 每日一题】2716. 最小化字符串长度

问题背景 给你一个下标从 0 0 0 开始的字符串 s s s&#xff0c;重复执行下述操作 任意 次&#xff1a; 在字符串中选出一个下标 i i i&#xff0c;并使 c c c 为字符串下标 i i i 处的字符。并在 i i i 左侧&#xff08;如果有&#xff09;和 右侧&#xff08;如果有&…

Flutter中实现拍照识题的功能

文章目录 **1. 功能拆解****2. 具体实现步骤****(1) 拍照或选择图片****(2) 图片预处理&#xff08;可选&#xff09;****(3) 文字识别&#xff08;OCR&#xff09;****(4) 数学公式识别 → LaTeX****方案1&#xff1a;Mathpix API&#xff08;高精度&#xff0c;付费&#xff…

【Mysql:内置函数】

日期函数&#xff1a; 查看当前日期&#xff1a; select current_date();查看当前时间&#xff1a; select current_time(); 查看当前时间戳&#xff1a; select current_timestamp(); 计算两个日期的差值&#xff1a; select datediff(date1,date2); 当前的日期时间&a…

71. 我的第一个Linux驱动实验

一、字符设备驱动框架 字符设备驱动的编写主要就是驱动对应的open、close、read。。。其实就是 file_operations结构体的成员变量的实现。 其中关于 C 库以及如何通过系统调用“陷入” 到内核空间这个我们不用去管&#xff0c;我们重点关注的是应用程序和具体的驱动&#xff0…