详解DAC数模转换+DAC输出模拟电压的测量比对实验程序

前言:详解DAC数模转换原理+DAC输出模拟电压的测量比对实验程序(使用 DAC 通道 1 输出模拟电压,然后通过 ADC1 的通道 1 对该输出电压进行读取,并显示在 LCD 模块上面,DAC 的输出电压可以通过按键(或 USMART)进行调整。)

目录

1.数模转换DAC原理

硬件设计

2.实验程序讲解

源码


1.数模转换DAC原理

        STM32的DAC模块(数字/模拟转换模块)是12位数字输入, 电压输出型的DAC。DAC可以配置为8位或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐或右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道可以 独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可以通过引脚输入参考电压VREF+以获得更精确的转换结果。

1.1.STM32的DAC模块主要特点有

  • ①2个DAC转换器:每个转换器对应1个输出通道
  • ②8位或者12位单调输出
  • ③12位模式下数据左对齐或者右对齐
  • ④同步更新功能
  • ⑤噪声波形生成
  • ⑥三角波形生成
  • ⑦双DAC通道同时或者分别转换
  • ⑧每个通道都有DMA功能

1.2.DAC模块方图:

在DHRx相应寄存器写值就可以被控制写到DORx数据寄存器输出,

控制MAMPx和WAVEBx等寄存器可以相应的位可以生成三角波、噪音波,

下图中的左上角是触发控制,可以通过外部的定时器的事件触发或者软件触发。

VDDA和VSSA为DAC模块模拟部分的供电。

Vref+则是DAC模块的参考电压。(1.8v~13.3v)

DAC_OUTx就是DAC的输出通道了,F4的DAC1_OUT1对应PA4,DAC1_OUT2对应PA5引脚。

使用DAC时,引脚要配置为模拟模式(AIN)。

1.3.DAC转换:

1.4.DAC数据格式:

1.5.DAC触发选择:

1.6. DAC输出电压:

除以4095是因为是最高12位,参考电压一般都是3.3V 。

1.7.DAC通道使能:

1.8.DAC输出缓冲器使能:

1.9.DAC相关寄存器:

硬件设计

本次实验使用STM32F4的DAC引脚PA4,ADC引脚PA5。(DAC输出,ADC测量输入)

可以使用跳线帽将两个引脚连接到一起,实现例如输入100数值的DAC它的电压是不是0.3v?可以用内部的ADC再去测量这个电压,测量出来看一下是不是0.3v,进行一个比较。

用到的硬件资源有:
1 ) 指示灯 DS0
2 KEY_UP KEY1 按键
3 ) 串口
4 TFTLCD 模块
5 ADC
6 DAC
我们使用 DAC 通道 1 输出模拟电压,然后通过 ADC1 的通道 1 对该输出电压进行读取,并显示在 LCD 模块上面, DAC 的输出电压,我们通过按键(或 USMART )进行设置。
我们需要用到 ADC 采集 DAC 的输出电压,所以需要在硬件上把他们短接起来。 ADC 和 DAC 的连接原理图如下图 所示:

P12 是多功能端口,我们只需要通过跳线帽短接 P14 ADC DAC ,就可以开始做本
章实验了。如下图 所示:

2.实验程序讲解

        通过以上介绍,我们了解了 STM32F4 实现 DAC 输出的相关设置,我们将使用 DAC 模块的通道 1 来输出模拟电压。这里我们用到的库函数以及相关定义分布在文件 stm32f4xx_dac.c 以及头文件 stm32f4xx_dac.h 中。实现上面功能的详细设置步骤如下:
1 )开启 PA 口时钟,设置 PA4 为模拟输入。
STM32F407ZGT6 DAC 通道 1 是接在 PA4 上的,所以,我们先要使能 GPIOA 的时钟,然后设置 PA4 为模拟输入。 这里需要特别说明一下,虽然 DAC 引脚设置为输入,但是 STM32F4 内部会连接在 DAC 模拟输出上, 是引脚复用映射。
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能 GPIOA 时
钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化

对于 DAC 通道与引脚对应关系,这在 STM32F4 的数据手册引脚表上有列出,如下图:  

2 )使能 DAC1 时钟。
同其他外设一样,要想使用,必须先开启相应的时钟。 STM32F4 DAC 模块时钟是由APB1 提供的,所以我们先要在通过调用函数 RCC_APB1PeriphClockCmd 来使能 DAC1 时钟。
APB1 提供的,所以我们先要在通过调用函数 RCC_APB1PeriphClockCmd 来使能 DAC1 时
钟。
3 )初始化 DAC, 设置 DAC 的工作模式。
该部分设置全部通过 DAC_CR 设置实现,包括: DAC 通道 1 使能、 DAC 通道 1 输出 缓存关闭、不使用触发、不使用波形发生器等设置。这里 DAC 初始化是通过函数 DAC_Init 完成的:
void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct);
结构体类型 DAC_InitTypeDef 的定义:
typedef struct
{uint32_t DAC_Trigger; uint32_t DAC_WaveGeneration; uint32_t DAC_LFSRUnmask_TriangleAmplitude; uint32_t DAC_OutputBuffer; 
}DAC_InitTypeDef;
这个结构体的定义还是比较简单的,只有四个成员变量,下面我们一一讲解。
第一个参数 DAC_Trigger 用来设置是否使用触发功能,前面已经讲解过这个的含义,这里
我们不是用触发功能,所以值为 DAC_Trigger_None
第二个参数 DAC_WaveGeneratio 用来设置是否使用波形发生,这里我们前面同样讲解过不
使用。所以值为 DAC_WaveGeneration_None
第三个参数 DAC_LFSRUnmask_TriangleAmplitude 用来设置屏蔽 / 幅值选择器,这个变量只
在使用波形发生器的时候才有用,这里我们设置为 0 即可,值为 DAC_LFSRUnmask_Bit0
第四个参数 DAC_OutputBuffer 是用来设置输出缓存控制位,前面讲解过,我们不使用输出
缓存,所以值为 DAC_OutputBuffer_Disable 。到此四个参数设置完毕。看看我们的实例代码:
DAC_InitTypeDef DAC_InitType;
DAC_InitType.DAC_Trigger=DAC_Trigger_None; //不使用触发功能 TEN1=0
DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ; //DAC1 输出缓存关闭
DAC_Init(DAC_Channel_1,&DAC_InitType); //初始化 DAC 通道 1
4 )使能 DAC 转换通道
初始化 DAC 之后,理所当然要使能 DAC 转换通道,库函数方法是:
DAC_Cmd(DAC_Channel_1, ENABLE); //使能 DAC 通道 1
5 )设置 DAC 的输出值。
通过前面 4 个步骤的设置, DAC 就可以开始工作了,我们使用 12 位右对齐数据格式, 所以我们通过设置 DHR12R1 ,就可以在 DAC 输出引脚( PA4 )得到不同的电压值了。设置 DHR12R1 的库函数是:
DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12 位右对齐数据格式设置 DAC 值
第一个参数设置对齐方式,可以为 12 位右对齐 DAC_Align_12b_R ,12 位左对DAC_Align_12b_L 以及 8 位右对齐 DAC_Align_8b_R 方式。 第二个参数就是 DAC 的输入值了,这个很好理解,初始化设置为 0 。这里,还可以读出 DAC 对应通道最后一次转换的数值,函数是:
DAC_GetDataOutputValue(DAC_Channel_1);
设置和读出一一对应很好理解,这里就不多讲解了。
最后,再提醒一下大家,本例程,我们使用的是 3.3V 的参考电压,即 Vref+ 连接 VDDA
通过以上几个步骤的设置,我们就能正常的使用 STM32F4 DAC 通道 1 来输出不同的模拟电压了。

源码

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "adc.h"
#include "dac.h"
#include "key.h"
#include "beep.h"int main(void)
{ u16 adcx;float temp;u8 t=0;	 u16 dacval=0;u8 key;	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2delay_init(168);      //初始化延时函数uart_init(115200);		//初始化串口波特率为115200LED_Init();					//初始化LED LCD_Init();					//LCD初始化Adc_Init(); 				//adc初始化KEY_Init(); 				//按键初始化Dac1_Init();		 		//DAC通道1初始化	POINT_COLOR=RED; LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");	LCD_ShowString(30,70,200,16,16,"DAC TEST");	LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(30,110,200,16,16,"2024/6/12");	 LCD_ShowString(30,130,200,16,16,"WK_UP:+  KEY1:-");	 POINT_COLOR=BLACK;//设置字体为黄色      	 LCD_ShowString(30,150,200,16,16,"DAC VAL:");	      LCD_ShowString(30,170,200,16,16,"DAC VOL:0.000V");	      LCD_ShowString(30,190,200,16,16,"ADC VOL:0.000V");DAC_SetChannel1Data(DAC_Align_12b_R,dacval);//初始值为0	while(1){t++;key=KEY_Scan(0);			  if(key==WKUP_PRES){		 if(dacval<4000)dacval+=200;DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值}else if(key==2)	{if(dacval>200)dacval-=200;else dacval=0;DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值}	 if(t==10||key==KEY1_PRES||key==WKUP_PRES) 	//WKUP/KEY1按下了,或者定时时间到了{	  adcx=DAC_GetDataOutputValue(DAC_Channel_1);//读取前面设置DAC的值LCD_ShowxNum(94,150,adcx,4,16,0);     	   //显示DAC寄存器值temp=(float)adcx*(3.3/4096);			         //得到DAC电压值adcx=temp;LCD_ShowxNum(94,170,temp,1,16,0);     	   //显示电压值整数部分temp-=adcx;temp*=1000;LCD_ShowxNum(110,170,temp,3,16,0X80); 	   //显示电压值的小数部分adcx=Get_Adc_Average(ADC_Channel_5,10);		//得到ADC转换值	  temp=(float)adcx*(3.3/4096);			        //得到ADC电压值adcx=temp;LCD_ShowxNum(94,190,temp,1,16,0);     	  //显示电压值整数部分temp-=adcx;temp*=1000;LCD_ShowxNum(110,190,temp,3,16,0X80); 	  //显示电压值的小数部分LED0=!LED0;	   t=0;}	    delay_ms(10);	 GPIO_ResetBits(GPIOF,GPIO_Pin_9);  //LED0????GPIOF.9??,?  ??LED0=0;GPIO_SetBits(GPIOF,GPIO_Pin_10);   //LED1????GPIOF.10??,? ??LED1=1;GPIO_ResetBits(GPIOF,GPIO_Pin_8); //BEEP????, ??BEEP=0;delay_ms(800);  		   //??800msGPIO_SetBits(GPIOF,GPIO_Pin_9);	   //LED0????GPIOF.0??,?  ??LED0=1;GPIO_ResetBits(GPIOF,GPIO_Pin_10); //LED1????GPIOF.10??,? ??LED1=0;delay_ms(800);                     //??800msGPIO_SetBits(GPIOF,GPIO_Pin_9);	   //LED0????GPIOF.0??,?  ??LED0=1;GPIO_SetBits(GPIOF,GPIO_Pin_10); //LED1????GPIOF.10??,? ??LED1=1;delay_ms(1800);                     //??800msGPIO_ResetBits(GPIOF,GPIO_Pin_9);	   //LED0????GPIOF.0??,?  ??LED0=0;GPIO_ResetBits(GPIOF,GPIO_Pin_10); //LED1????GPIOF.10??,? ??LED1=0;GPIO_SetBits(GPIOF,GPIO_Pin_8);   //BEEP????, ??BEEP=1;delay_ms(1800);                     //??800ms			for(i=0;i<5;i++){GPIO_ResetBits(GPIOF,GPIO_Pin_8); //BEEP????, ??BEEP=0;GPIO_SetBits(GPIOF,GPIO_Pin_9);	   //LED0????GPIOF.9??,?  ??LED0=1;delay_ms(800);GPIO_ResetBits(GPIOF,GPIO_Pin_9); //LED0????GPIOF.9??,? ??LED0=0;delay_ms(800);     }for(i=0;i<5;i++){GPIO_SetBits(GPIOF,GPIO_Pin_10);	   //LED0????GPIOF.10??,?  ??LED1=1;delay_ms(800);GPIO_ResetBits(GPIOF,GPIO_Pin_10); //LED0????GPIOF.10??,? ??LED1=0;delay_ms(800);     }	}	
}

dac.c

#include "dac.h"//DAC通道1输出初始化
void Dac1_Init(void)
{  GPIO_InitTypeDef  GPIO_InitStructure;DAC_InitTypeDef DAC_InitType;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化DAC_InitType.DAC_Trigger=DAC_Trigger_None;	//不使用触发功能 TEN1=0DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;	//DAC1输出缓存关闭 BOFF1=1DAC_Init(DAC_Channel_1,&DAC_InitType);	 //初始化DAC通道1DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC通道1DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值
}
//设置通道1输出电压
//vol:0~3300,代表0~3.3V
void Dac1_Set_Vol(u16 vol)
{double temp=vol;temp/=1000;temp=temp*4096/3.3;DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右对齐数据格式设置DAC值
}

adc.c

#include "adc.h"
#include "delay.h"		 //初始化ADC
//这里我们仅以规则通道为例
//我们默认仅开启通道1																	   
void  Adc_Init(void)
{    GPIO_InitTypeDef  GPIO_InitStructure;ADC_CommonInitTypeDef ADC_CommonInitStructure;ADC_InitTypeDef       ADC_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//使能ADC1时钟//先初始化IO口GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化  RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);	//ADC1复位RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);	//复位结束	 ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInit(&ADC_CommonInitStructure);ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐	ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1 ADC_Init(ADC1, &ADC_InitStructure);ADC_Cmd(ADC1, ENABLE);//开启AD转换器	 
}				  
//获得ADC值
//ch:通道值 0~16
//返回值:转换结果
u16 Get_Adc(u8 ch)   
{//设置指定ADC的规则组通道,一个序列,采样时间ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );	//ADC1,ADC通道,480个周期,提高采样时间可以提高精确度			    ADC_SoftwareStartConv(ADC1);		//使能指定的ADC1的软件转换启动功能	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束return ADC_GetConversionValue(ADC1);	//返回最近一次ADC1规则组的转换结果
}
//获取通道ch的转换值,取times次,然后平均 
//ch:通道编号
//times:获取次数
//返回值:通道ch的times次转换结果平均值
u16 Get_Adc_Average(u8 ch,u8 times)
{u32 temp_val=0;u8 t;for(t=0;t<times;t++){temp_val+=Get_Adc(ch);delay_ms(5);}return temp_val/times;
} 

相关知识:

 一、运算放大器(Operational Amplifier,简称 Op-Amp 或 运放)是一种高度灵活且多功能的电子组件,具有非常高的电压增益、高输入阻抗和低输出阻抗的特性。它在电子电路中扮演着核心角色,可以执行一系列复杂的信号处理任务。

 以下是运算放大器的一些主要作用:

1. **信号放大**:    - 运算放大器可以放大微弱的输入信号,使之达到足够的幅度,以便于后续电路处理或测量。它可以用于电压放大,既可以在同相配置中使用,也可以在反相配置中使用。

2. **数学运算**:    - 运放可以实现信号的加法、减法、积分和微分等数学运算,这些功能对于信号处理、控制系统和数据转换等领域至关重要。

3. **滤波**:    - 结合电阻和电容,运算放大器可以构成各种类型的滤波器,包括低通、高通、带通和带阻滤波器,用于信号的清洁和频率选择。

4. **比较器**:    - 运放可以用于比较两个电压信号,当输入信号超过某个阈值时,产生逻辑电平的变化,这在过零检测和电压监控电路中很常见。

5. **阻抗变换**:    - 运放可以用作缓冲器,将高阻抗信号转换为低阻抗信号,以匹配不同电路的阻抗要求。

6. **精密整流和稳压**:    - 在某些配置下,运放可以用于精密整流电路,以及作为反馈环路的一部分来实现稳压。

7. **信号转换**:    - 运放可以将电压信号转换为电流信号,反之亦然,这对于驱动负载或与电流敏感设备接口很有用。

8. **频率和脉冲生成**:    - 运算放大器可以用于产生特定频率的信号,如正弦波、方波或三角波,以及用于脉冲宽度调制(PWM)。

9. **数据转换**:    - 在模数转换器(ADC)和数模转换器(DAC)中,运放通常用于信号的调节和校准。

由于运算放大器的灵活性和多功能性,它几乎存在于所有现代电子设备中,从简单的音频放大器到复杂的工业控制系统,再到高精度测量仪器,都有其身影。

二、引脚复用和重映射

复用功能
首先、我们可以这样去理解stm32引脚的复用功能。以stm32F103RCT6芯片引脚PA9、PA10为例。
这两个芯片引脚定义如下:
PA9引脚: PA9/USART1_TX/TIM1_CH2
PA10引脚:PA10/USART1_RX/TIM1_CH3
1、这里的PA9引脚和PA10引脚我们可以理解为引脚名,用于区分两个不同的引脚。
2、可以看到PA9引脚、PA10引脚都有三种功能。其中第一项PA9和PA10是其默认功能,默认功能为GPIO功能,也即是作为通用的输入输出端口使用。
3、这样我们就知道,当PA9引脚和PA10引脚不在作为默认的GPIO功能使用,而是作为USART1_TX/USART1_RX或者作为TIM1_CH2/TIM1_CH3功能使用时,就是对PA9引脚和PA10引脚的复用。
4、总而言之,对于stm32来说,由于其内部各种外设的存在,往往每个引脚都会有几种不同的功能,这几种不同的功能都可以使用这一个端口引脚。但是由于stm32的端口引脚都有一个自己的默认功能存在,当该引脚不在作为默认功能使用时对于该引脚来说就是复用。由于大多数引脚的默认功能和其引脚名称PA9引脚或者PA10引脚一样都是作为GPIO功能使用,因此当不在作为GPIO功能而是作为其他外设的相关功能使用时就是对引脚的复用。

重映射功能
为了让工程师能够更好的安排布局及方便布线,在stm32中引入了外设引脚的重映射功能。即一个外设的引脚除了具有默认的引脚外还可以通过配置重映射寄存器的方式将这个外设的引脚映射到其他的引脚上去。
同样的以PA9引脚和PA10引脚为例,对于stm32F103RCT6芯片来说,有如下引脚定义:
PA9引脚: PA9/USART1_TX/TIM1_CH2
PA10引脚:PA10/USART1_RX/TIM1_CH3
PB6引脚: PB6/I2C1_SCL/TIM4_CH1/USART1_TX
PB7引脚: PB7/I2C1_SDA/FSMC_NADV/TIM4_CH2/USART1_RX

1、首先、我们要明确一点,重映射的概念是对于芯片的各种外设本身来说的而非GPIO。因为引脚作为GPIO功能使用时一般是其默认的功能,而重映射的概念是建立在对引脚的复用功能上的。也即是当引脚复用为非GPIO功能时才可能会使用到重映射的功能。
2、USART1_REMAP=0表示没有使用重映射功能的情况;USART1_REMAP=1则表示使用重映射功能的情况。
3、从上面表中可以看到,默认情况下(没有使用重映射),USART1的TX和RX引脚默认使用的就是PA9引脚和PA10引脚。
4、在开启重映射功能时,USART1的TX和RX引脚还可以重映射到PB6和PB7引脚上去。

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

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

相关文章

了解CDN:提升网络性能和安全性的利器

在当今的数字时代&#xff0c;网站性能和安全性是每一个网站管理员必须关注的核心问题。内容分发网络&#xff08;CDN&#xff0c;Content Delivery Network&#xff09;作为解决这一问题的重要工具&#xff0c;逐渐成为主流。本文将详细介绍CDN的定义、作用及其工作原理&#…

小白学react之Next.js 14(一)不配置路由的玩法

Next.js 14是目前最新版本&#xff0c;我们用就用最新的玩一下。 建一个示例之后&#xff0c;我在找配置&#xff0c;我应该在那建一个新的页面。找半天硬是没找着&#xff0c;答案是现在不需要配置。 我们来看一下Next.js 14的项目结构&#xff1a; 很明显&#xff0c;在src/…

数学建模系列(4/4):Matlab建模实战

目录 引言 1. Matlab简介与安装 1.1 Matlab简介 1.2 Matlab的安装 2. Matlab基础操作 2.1 Matlab基础语法和常用命令 2.2 Matlab中的数据类型和数据结构 3. 用Matlab进行建模 3.1 矩阵运算与线性代数 矩阵运算 3.2 Matlab中的绘图功能 绘制2D图形 绘制3D图形 3.3…

物联网技术-第5章-物联网数据处理

目录 1.物联网数据特征 2.物联网数据处理 &#xff08;1&#xff09;数据清洗 &#xff08;2&#xff09;数据存储 &#xff08;3&#xff09;数据融合 &#xff08;4&#xff09;数据挖掘 3.大数据基本概念 4.云计算基本概念 &#xff08;1&#xff09;背景 &#xf…

RTD 基础知识——电阻温度检测器简介

电阻温度检测器或 RTD 可能是简单的温度传感器类型。这些设备的工作原理是金属的电阻随温度变化。纯金属通常具有正的电阻温度系数&#xff0c;这意味着它们的电阻随温度升高而增加。RTD 可在 -200 C 至 850 C 的较大温度范围内工作&#xff0c;并提供高精度、出色的长期稳定性…

HoVer-Net复现:手把手带你实现细胞核的分割与分类,并输出叠加图像|24-06-21

小罗碎碎念 先说一下&#xff0c;只要你跟着我一步一步走&#xff0c;你能实现的效果——对细胞核进行分割和分类&#xff0c;并在原始图像上以颜色叠加的方式直观地展示这些结果。 昨天我在交流群里进行了一下预热&#xff0c;并且提供了一些前期的教程&#xff0c;反响还不…

C# 实现去除多行文本框光标闪烁,并设置行距

一、前言 本篇主要通过继承RichTextBox 的方式实现去除多行文本框的光标闪烁&#xff0c;以及能够设置行距大小&#xff0c;这是因为C#提供的TextBox 和 RichTextBox 本身无这样的功能 二、代码 封装 RichTextBox 为CustomTextBox using System; using System.Collections.Ge…

解决element-plus没有导出的成员FormInstance

使用element-plus的el-form时&#xff0c;报错“"element-plus"”没有导出的成员“FormInstance”。你是否指的是“FooterInstance”? 解决方法&#xff1a; 引入ElForm类型&#xff0c;在外重新定义FormInstance的类型为ElForm的实例类型 示例&#xff1a; import…

React+TS前台项目实战(十四)-- 响应式头部导航+切换语言相关组件封装

文章目录 前言Header头部相关组件1. 功能分析2. 相关组件代码详细注释3. 使用方式4. Gif图效果展示 总结 前言 在这篇博客中&#xff0c;我们将封装一个头部组件&#xff0c;根据不同设备类型来显示不同的导航菜单&#xff0c;会继续使用 React hooks 和styled-components库来…

Oracle最终还是杀死了MySQL

起因 大约15年前&#xff0c;Oracle收购了Sun公司&#xff0c;从而也拥有了MySQL&#xff0c;互联网上关于Oracle何时会“扼杀MySQL”的讨论此起彼伏。 当时流传着各种理论&#xff1a;从彻底扼杀 MySQL 以减少对 Oracle 专有数据库的竞争&#xff0c;到干掉 MySQL 开源项目&…

qt开发-07_radioButton

QRadioButton 部件提供了一个带有文本标签的单选框&#xff08;单选按钮&#xff09;。 QRadioButton 是一个可以切换选中&#xff08;checked&#xff09;或未选中&#xff08;unchecked&#xff09;状态的选项按钮。 单选框通常呈现给用户一个“多选一”的选择。也就是说&…

Emacs之复制时:禁止转换成tab符号(一百三十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

购物网站系统

摘 要 随着互联网的快速发展&#xff0c;不同的平台软件也不断涌出市场&#xff0c;在众多的平台中&#xff0c;购物网站深受人们的欢迎&#xff0c;也成为生活中不可缺少的一部分。经过对国内外购物情况的调查&#xff0c;社区购物在近几年来成为电商发展的新趋势&#xff0c…

递归乘法00

题目链接 递归乘法 题目描述 注意点 保证乘法范围不会溢出 解答思路 使用加法代替乘法&#xff0c;递归计算A * B&#xff0c;每个递归的过程加上一个A&#xff0c;且对B减1&#xff0c;直到B为0为止 代码 class Solution {public int multiply(int A, int B) {if (B 0…

C++ 教程 - 05 构建编译

文章目录 构建工具cmake安装与使用CMakeLists.txt编写使用案例 构建工具 cmake, Cross Platform Make&#xff0c; &#xff08;对C&#xff09;跨平台编译工具&#xff0c;将CMakeLists.txt 文件编译为对应的文件&#xff0c;如linux下的 Makefile&#xff0c;然后使用make命…

[WTL/Win32]_[中级]_[MVP架构在实际项目中的应用]

场景 在开发Windows和macOS的界面软件时&#xff0c;Windows用的是WTL/Win32技术&#xff0c;而macOS用的是Cocoa技术。而两种技术的本地语言一个主打是C,另一个却是Object-c。界面软件的源码随着项目功能增多而增多&#xff0c;这就会给同步Windows和macOS的功能造成很大负担…

Github 2024-06-21 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-06-21统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量TypeScript项目3Python项目3Java项目2非开发语言项目2JavaScript项目1Rust项目1Dart项目1HTML项目1Vue项目1C++项目1TensorFlow: 机器学习的开源…

用户和账号

chage、useradd、passwd、usermod、userdel、groupadd、gpasswd、groupdel、groups、 用户账号初始配置文件 .bashrc .bash_profile .bash_logout finger、w、who、users chmod、chowd、umask、last 1.用户的分类 Linux 用户三种角色 超级用户&#x…

LInux驱动开发笔记(十)SPI子系统及其驱动

文章目录 前言一、SPI驱动框架二、总线驱动2.1 SPI总线的运行机制2.2 重要数据结构2.2.1 spi_controller2.2.2 spi_driver2.2.3 spi_device2.2.4 spi_transfer2.2.5 spi_message 三、设备驱动的编写3.1 设备树的修改3.2 相关API函数3.2.1 spi_setup( )3.2.2 spi_message_init( …

使用GPG来解密和加密文件详解

文章目录 使用私钥解密文件示例步骤 注意事项加密文件前提条件导入公钥加密文件输出加密文件示例步骤注意事项邮箱不是必须的情况1&#xff1a;有多个公钥情况2&#xff1a;只有一个公钥示例步骤示例1&#xff1a;指定公钥ID或邮箱地址示例2&#xff1a;密钥环中只有一个相关的…