51单片机--AD/DA

news2024/11/28 19:00:00

AD/DA介绍

AD和DA是模拟信号和数字信号之间的转换过程。
AD,全称为模拟到数字(Analog-to-Digital),指的是将模拟信号转换为数字信号的过程。在AD转换中,模拟信号经过采样、量化和编码等步骤,被转换为离散的数字信号。这样可以更方便地处理和传输信号,在数字系统中进行数字信号的处理和分析。
DA,全称为数字到模拟(Digital-to-Analog),指的是将数字信号转换为模拟信号的过程。在DA转换中,数字信号经过解码和重构处理,被转换为连续的模拟信号。这样可以将数字信号转换为模拟信号,使其能够被模拟系统接收和处理。
AD和DA转换常见于各种电子设备和系统中,例如音频设备、通信系统、传感器等。AD转换可以将实际物理量(如声音、温度、光强)转换为数字形式进行处理,而DA转换则可以将数字信号转换为模拟形式输出到外部设备或环境中
AD和DA转换的准确性和性能对于系统的精度和稳定性至关重要,因此在设计和选择AD和DA转换器时需要考虑多个因素,如分辨率、采样率、信噪比、线性度等。
在这里插入图片描述

硬件电路模型

在这里插入图片描述

AD转换电路

  1. 采样电路:根据采样信号,对要转换的模拟量进行抽样,通常使用开关电容电路或采样保持电路实现。
  2. 模拟信号输入电路:将要转换的模拟信号经过滤波、放大等处理后输入到采样电路。
    该电路通常包括输入缓冲器、低通滤波器和增益放大器等。
  3. A/D转换器(ADC):采样电路输出的模拟信号通过ADC芯片进行转换。ADC芯片可能采用逐次逼近法、积分法或其他转换方法。
  4. 数字信号输出:转换后的数字信号通过总线或其他方式传输给单片机

DA转换电路

  1. 数字信号输入:单片机通过总线或其他方式将要转换的数字信号输入到DA转换电路。
  2. D/A转换器(DAC):数字信号经过DAC芯片进行转换,DAC芯片可能采用R-2R网络、串行接口或其他转换方法。
  3. 模拟信号输出电路:转换后的模拟信号经过滤波、放大等处理后输出到外部设备或环境.

举个例子,麦克风接收声音:通过声音的大小、音调、音色等因素转换为高低不同的电压,转换后的电压值就是数字信号;然后用扩音器放出声音:单片机或者芯片通过总线将存储在寄存器上的数字信号传入到DAC中;DAC将数字信号转换为对应的声音,最后进行输出。

AD原理

在这里插入图片描述

这是单片机上的ADC模块原理图;
与单片机芯片连接的引脚:

DIN:串行数据输入
CS;片选信号;这是一种控制信号,用于选择要与主设备进行通信的从属设备。
DLCK:串行时钟
DOUT:串行数据输出

与外部电阻连接的引脚:

AIN0:连接着分压电阻;
AIN1:连接着热敏电阻;
AIN2:连接着光敏电阻;

在这里插入图片描述

下面是AD转换器的内部结构:逐次逼近型AD转换器
在这里插入图片描述
它使用二分搜索的方法逼近输入的模拟信号,并将其转换为数字输出;
逐次逼近型AD转换器通常由以下几个主要组成部分构成:

  1. 比较器(Comparator):用于比较输入模拟信号和DAC输出的数字量,产生一个比较结果。

  2. 数字-模拟转换器(Digital-to-Analog Converter,DAC):将数字量转换为模拟信号输出。在逐次逼近型AD转换器中,DAC通常是一个逐位逼近型DAC,可以根据比较结果生成合适的模拟电压输出。

  3. 控制逻辑(Control Logic):用于控制转换过程,包括初始化、逐位逼近、对比和停止等步骤。控制逻辑会根据比较结果调整DAC的输出,直到得到一个与输入模拟信号尽可能接近的数字输出。

  4. 计数器(Counter):用于计数和记录逼近过程中的比特位。逐次逼近型AD转换器从高位(MSB)开始逼近,通过逐步调整DAC输出的比特位。计数器会在每一次逼近过程中更新。

DA原理

在这里插入图片描述
与单片机相连的引脚:P21;通过放大器将数字信号转换为模拟信号到DA1(LED灯上);

T型电阻网络DA转换器
在这里插入图片描述
T型电阻网络DAC通常由一个或多个可变电阻和固定比例的电阻组成。其中,可变电阻用于控制输出模拟信号的大小,而固定比例的电阻则用于分割参考电压以确定输出模拟信号的范围。
在T型电阻网络DAC中,输入的数字信号首先被编码为N位二进制数。每个二进制位对应一个电阻。根据输入二进制数中1的个数,相应的开关会连接或断开对应的电阻通过这样的连接和断开过程,可变电阻的总阻值可以被调整,从而实现不同模拟输出电压的生成。当电阻网络的总阻值变化时,输出模拟电压也会相应地变化。
需要注意的是,T型电阻网络DAC的精度受限于电阻的精度和线性度。此外,由于电阻切换过程中可能引入的开关跳变,可能产生瞬态误差(glitch),导致输出信号的非理想性。
在这里插入图片描述

PWM型DA转换器
在这里插入图片描述
PWM型DA转换器(Pulse Width Modulation)是一种常见的数字模拟转换器,通过调节脉冲的宽度来实现模拟输出信号的调节
PWM型DA转换器基于脉冲信号,其输出信号的模拟值由脉冲的占空比决定。PWM型DA转换器通常包含一个计数器和一个比较器。计数器用于生成一个周期性的计数序列,比较器用于将计数值与给定的参考值进行比较产生脉冲信号。
工作原理如下:通过改变计数器的计数范围,以及在每个计数值处进行比较的阈值,可以控制脉冲信号的占空比。占空比表示脉冲高电平的时间与周期的比例,反映了输出模拟信号的幅度
在PWM型DA转换器中,**输入的数字信号首先被编码为N位二进制数。这个二进制数通常对应了脉冲信号的占空比调节值。**因此,输入数字信号越大,对应的脉冲信号的高电平时间也越长,从而模拟输出信号的幅度也会相应增加。
在这里插入图片描述

运算放大器

运算放大器(Operational Amplifier,简称运放或OP-AMP)是一种具有很高放大倍数的电路单元。它常用于模拟电路中,可以将输入信号进行放大、加、减、微分、积分等数学运算,并输出相应的结果。
运放通常由集成电路或分立元件组成,在现代电子行业广泛应用。它的工作原理是利用多级放大电路实现非常高的增益,同时通过外部反馈网络来控制其响应和特性。运放具有差分输入和单端输出的特点,其中两个输入端分别为非反相输入端和反相输入端,输出端则与输入端之间存在一个差分增益。
在这里插入图片描述

运放电路

在这里插入图片描述

1.运算放大器的正相输入端和反向输入端分别连接到待比较的两个电压源。
2.运算放大器的输出端与反馈电阻组成反馈网络,将输出信号通过反馈电阻返回到运放的正相输入端。
3.参考电压源为基准,通常连接到运放的正相输入端。
当运放的非反相输入端(+)所对应的电压高于反相输入端(-)时,运算放大器的输出会趋向于最大正饱和电压。相反地,当非反相输入端(+)的电压低于反相输入端(-)时,输出会趋向于最大负饱和电压。

在这里插入图片描述

反向放大器的原理如下:

  1. 输入信号通过输入电阻连接到运放的反相输入端(-)。
  2. 反馈电阻将运放的输出信号反馈到反相输入端(-)。
  3. 运放的非反相输入端(+)通常连接到地或参考电压源。

根据反馈原理,在稳定工作状态下,反向放大器的负反馈将使输入电流接近于零。根据欧姆定律,输入电流通过输入电阻产生的电压与输出电压成比例。

根据虚短和虚断点理想条件,可以得出反向放大器的放大倍数为:
放大倍数(Av) = -(Rf / Rin)

其中,Rf为反馈电阻,Rin为输入电阻。

由于反向放大器的特性,输出信号与输入信号之间存在180度的相位差,且放大倍数为负值。当输入信号为正时,输出信号为负;当输入信号为负时,输出信号为正。

反向放大器常用于信号放大、滤波、调节增益等应用。通过调整反馈电阻和输入电阻的比例,可以实现不同的放大倍数,并控制输出信号的幅度。

在这里插入图片描述
同向放大器是一种电子设备,常用于放大电信号。它的工作原理基于放大器中的晶体管或其他增益元件。

同向放大器的主要原理是将输入信号通过增益元件进行放大,并输出放大后的信号。增益元件通常是一个晶体管,例如双极性晶体管(BJT)或场效应晶体管(FET)。

在同向放大器中,输入信号被传送到晶体管的基极(对于BJT)或栅极(对于FET)。晶体管被偏置,以确保它在其工作区域内正常工作。当输入信号施加在晶体管上时,它会引起晶体管中的电流和电压的变化。

晶体管中的电流和电压变化会导致输出信号的放大。通过调整晶体管的工作点,可以控制输出信号的幅度和偏置。同向放大器通常采用反馈网络来提高线性度和稳定性。

在这里插入图片描述
电压跟随器(Voltage Follower)是一种放大器电路,它具有高输入阻抗、低输出阻抗和1倍的电压增益。它的主要功能是将输入电压信号复制到输出端,同时提供更低的输出阻抗。

电压跟随器的原理很简单:输入信号被连接到放大器的非反馈输入端,而输出信号则从放大器的输出端获取。由于没有反馈网络,所以该电路没有电压增益,信号只是通过放大器进行缓冲传递。这使得输出信号与输入信号具有相同的幅度,但输出阻抗远低于输入阻抗。

XPT2046

在这里插入图片描述

简介:XPT2046 是一款 4 线制电阻式触摸屏控制器,内含 12 位分辨率 125KHz 转换速率逐步逼近型 A/D 转换器
XPT2046 支持从 1.5V 到 5.25V 的低电压 I/O 接口。XPT2046 能通过执行两次 A/D 转换查出被按的屏幕位置, 除此之外,还可以测量加在触摸屏上的压力。内部自带 2.5V 参考电压,可以作为辅助输入、温度测量和电池监测之用,电池监测的电压范围可以从 0V 到 6V。
XPT2046 片内集成有一个温度传感器。 在 2.7V 的典型工作状态下,关闭参考电压,功耗可小于 0.75mW。
XPT2046 采用微小的封装形式:TSSOP-16,QFN-16 和 VFBGA-48。 工作温度范围为-40℃~+85℃。与 ADS7846、TSC2046、AK4182A 完全兼容。

在我们单片机上,已经内置了XPT2046控制器,我们只需要根据它的时序结构,就可以实现模数转换

XPT2046时序

XPT2046 数据接口是串行接口,其典型工作时序如图 12 所示,图中展示的信号来自带有基本串行接口的单片机或数据信号处理器。(SPI通信)
在这里插入图片描述
片选信号CS保持低电平;对于DLCK,上升沿表示输入,下降沿表示输出;然后进行数据输入到DIN,最后将信号进行读出DOUT;

代码:

#include <REGX52.H>
#include<INTRINS.H>

//引脚定义
sbit XPT2046_DIN=P3^4;
sbit XPT2046_CS=P3^5;
sbit XPT2046_DLCK=P3^6;
sbit XPT2046_DOUT=P3^7;

//读出信号

unsigned int XPT2046_ReadAD(unsigned char Command)
{
	unsigned char i;
	unsigned int Data=0;
	XPT2046_DLCK=0;//串行时钟置于低电平
	XPT2046_CS=0;//片选信号置于低电平
	for(i=0;i<8;i++)
	{
		XPT2046_DIN=Command&(0x80>>i);//信号输入
		XPT2046_DLCK=1;//上升沿输入
		XPT2046_DLCK=0;
	}
	//这是一个12位的AD转换器,可输出12位的分辨率
	for(i=0;i<16;i++)
	{
		XPT2046_DLCK=1;
		XPT2046_DLCK=0;//下降沿输出
		//需要通过不断的上升下降表示接受不同的数据位
		if(XPT2046_DOUT)Data|=0x8000>>i;
	}
	XPT2046_CS=1;//片选置于高电平
	return Data>>8;//返回8位的数字信号
}
	

在这里插入图片描述

这是从高位开始输入的;位7选择1;位6-4表示通道的选择,需要参考对应表;位3我们选择8位的转换分辨率的;位2选择单端输入方式;位1与位0选择低电平即可,不用用到总处于供电状态;

单端模式简单,在采样过程完成后,转换过程中可以关闭驱动开关,降低功耗。但这种模式的缺点是精度
直接受参考电压源的精度限制,同时由于内部驱动开关的导通电阻存在,导通电阻与触摸屏电阻的分压作用,也会带来测量误差
差分模式的优点是: +REF 和-REF 的输入分别直接接到 YP、 YN 上,可消除由于驱动开关的导通电阻引入的坐标测量误差。缺点是:无论是采样还是转换过程中,驱动开关都需要接通,相对单端模式而言,功耗增加了。

那么我们就有这样的信号模板

0xxx 1100

在这里插入图片描述
我们根据原理图,选出对应的输出配置:

#define XPT2046_VBAT 0xAC
#define XPT2046_AUX 0xEC
#define XPT2046_XP 0x9C
#define XPT2046_YP 0xDC

AD模数转换代码:

将分压电阻,热敏电阻,光敏电阻转换为对应的数字信号并显示于屏幕上;
XPT2046.h:

#ifndef __XPT2046_H__
#define __XPT2046_H__

//输入端口地址的宏定义
#define XPT2046_VBAT 0xAC
#define XPT2046_AUX 0xEC
#define XPT2046_XP 0x9C
#define XPT2046_YP 0xDC


unsigned int XPT2046_ReadAD(unsigned char Command);

#endif

XPT2046.c

#include <REGX52.H>
#include<INTRINS.H>

//引脚定义
sbit XPT2046_DIN=P3^4;
sbit XPT2046_CS=P3^5;
sbit XPT2046_DLCK=P3^6;
sbit XPT2046_DOUT=P3^7;

//读出信号

unsigned int XPT2046_ReadAD(unsigned char Command)
{
	unsigned char i;
	unsigned int Data=0;
	XPT2046_DLCK=0;
	XPT2046_CS=0;
	for(i=0;i<8;i++)
	{
		XPT2046_DIN=Command&(0x80>>i);
		XPT2046_DLCK=1;
		XPT2046_DLCK=0;
	}
	for(i=0;i<16;i++)
	{
		XPT2046_DLCK=1;
		XPT2046_DLCK=0;
		if(XPT2046_DOUT)Data|=0x8000>>i;
	}
	XPT2046_CS=1;
	return Data>>8;
}

Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delayms(unsigned int x);

#endif

Delay.c

void Delayms(unsigned int x)		//@11.0592MHz
{
	unsigned char i, j;

	while(x--)
	{
	
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

LCD1602.c

#include <REGX52.H>

//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0

//函数定义:
/**
  * @brief  LCD1602延时函数,12MHz调用可延时1ms
  * @param  无
  * @retval 无
  */
void LCD_Delay()
{
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}

/**
  * @brief  LCD1602写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602设置光标位置
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @retval 无
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));
	}
	else if(Line==2)
	{
		LCD_WriteCommand(0x80|(Column-1+0x40));
	}
}

/**
  * @brief  LCD1602初始化函数
  * @param  无
  * @retval 无
  */
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
	LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
	LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
	LCD_WriteCommand(0x01);//光标复位,清屏
}

/**
  * @brief  在LCD1602指定位置上显示一个字符
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的字符
  * @retval 无
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}

/**
  * @brief  在LCD1602指定位置开始显示所给字符串
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串
  * @retval 无
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
	{
		LCD_WriteData(String[i]);
	}
}

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;
}

/**
  * @brief  在LCD1602指定位置开始显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~65535
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以有符号十进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-32768~32767
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
	unsigned char i;
	unsigned int Number1;
	LCD_SetCursor(Line,Column);
	if(Number>=0)
	{
		LCD_WriteData('+');
		Number1=Number;
	}
	else
	{
		LCD_WriteData('-');
		Number1=-Number;
	}
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以十六进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~0xFFFF
  * @param  Length 要显示数字的长度,范围:1~4
  * @retval 无
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i,SingleNumber;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		SingleNumber=Number/LCD_Pow(16,i-1)%16;
		if(SingleNumber<10)
		{
			LCD_WriteData(SingleNumber+'0');
		}
		else
		{
			LCD_WriteData(SingleNumber-10+'A');
		}
	}
}

/**
  * @brief  在LCD1602指定位置开始以二进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度,范围:1~16
  * @retval 无
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
	}
}

LCD1602.h

#ifndef __LCD1602_H__
#define __LCD1602_H__

//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

#endif

main.c

#include <REGX52.H>
#include"Delay.h"
#include"LCD1602.h"
#include"XPT2046.h"

unsigned int ADValue;

void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"ADJ NTC  GR");
	while(1)
	{
		ADValue=XPT2046_ReadAD(XPT2046_XP);   //读取AIN0,可调电阻
		LCD_ShowNum(2,1,ADValue,3);
		ADValue=XPT2046_ReadAD(XPT2046_YP);   //读取AIN1,热敏电阻
		LCD_ShowNum(2,6,ADValue,3);
		ADValue=XPT2046_ReadAD(XPT2046_VBAT);   //读取AIN2,光敏电阻
		LCD_ShowNum(2,11,ADValue,3);
		Delayms(100);//延迟100ms,会根据实况不断刷新数据
	}
}

AD的实例代码

产生PWM的方法


在这里,我们利用软件程序进行实现PWM,就是利用计数器和某一个值进行比较,根据比较结果输出一个对应的高低电平;像图中的,只要比较值大于计数器的值,那么就输出0,比较值大于等于计数器的值,那么就输出1;

DA信号输出的呼吸灯代码

Timer0.c

#include <REGX52.H>

/**
  * @brief 定时器0初始化
	* @param 无
	* @reval 无
  */
void Timer0Init(void)		//100us @11.0592MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |=0x01;
	TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;     //允许T0中断
	EA=1;      //CPU开放总中断
	PT0=0;      //定时器0中断优先级
}

Timer0.h

#ifndef __TIMER0_H__
#define __TIMER0_H__

void Timer0Init();

#endif

Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

Delay.c


void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}


main.c

#include <REGX52.H>
#include"Delay.h"
#include"Timer0.h"

sbit DA=P2^1;

unsigned char Counter,Compare;//计数值和比较值
unsigned char i;

void main()
{
	Timer0Init();
	while(1)
	{
		for(i=0;i<100;i++)//利用循环不断增加
		{
			Compare=i;
			Delay(10);//延长周期,不然LED闪烁过快
		}
		for(i=100;i>0;i--)
		{
			Compare=i;
			Delay(10);
		}
		
	}
}

//通过100us中断一次,将计数值与比较值比较,赋上对应的值
void Timer0_Routine() interrupt 1
{
	
	TL0 = 0xA4;		
	TH0 = 0xFF;		
	Counter++;
	Counter%=100;
	if(Counter<Compare)
	{
		DA=1;
	}
	else
	{
		DA=0;
	}
	
}

在这里插入图片描述

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

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

相关文章

liteflow 2.10 配置中心简单记录

除nacos是一个key 同时管理chain和script node外,可以理解为配置文件整体放到一个key下nacos下的文件必须是xml格式,系统只实现了xml parser其它etcd,zk,Apollo 是两个namespace/path(chain及script node各一)下多个key,每个key对应一个chain/node所有配置中心的核心代码…

跟我一起从零开始学python(十)Hadoop从零开始入门

前言 回顾之前讲了python语法编程 &#xff0c;必修入门基础和网络编程&#xff0c;多线程/多进程/协程等方面的内容&#xff0c;后续讲到了数据库编程篇MySQL&#xff0c;Redis&#xff0c;MongoDB篇&#xff0c;和机器学习&#xff0c;全栈开发&#xff0c;数据分析前面没看…

【Windows】不要让你的win键落灰!掌握常用的组合快捷键,使用电脑更高效了

Windows 操作系统提供了丰富的键盘快捷键&#xff0c;能够大幅提高工作效率和操作便利性。在此介绍一些与 Win 键相关的常用快捷键&#xff0c;帮助你更好地利用 Windows 系统。想要在使用电脑时更高效吗&#xff1f;掌握常用的组合快捷键&#xff0c;让你的 Win 键从此不再落灰…

phkit - 中英音素处理、文本转拼音、文本正则化

文章目录 关于 phkit安装包含组件pinyinkitchinesesymbolsequencepinyinphonemenumberconvertstyleenglish关于 phkit phoneme toolkit: 拼音相关的文本处理工具箱,中文和英文的语音合成前端文本解决方案。 github : https://github.com/KuangDD/phkit

【Lua学习笔记】Lua进阶——Table(2)

文章目录 Table的一万种用法二维数组类和结构体Table操作insert & removesortconcat 接上文【Lua学习笔记】Lua进阶——Table&#xff0c;迭代器 Table的一万种用法 二维数组 a {{ 1, 2, 3 },{ 4, 5, 6 }, } print(#a) -->2 for i1,#a dob a[i]for j1,#b doprint(b[…

opencv-25 图像几何变换04- 透视 cv2.warpPerspective()

什么是透视&#xff1f; 透视是一种几何学概念&#xff0c;用于描述在三维空间中观察物体时&#xff0c;由于视角的不同而产生的变形效果。在现实世界中&#xff0c;当我们从不同的角度或位置观察物体时&#xff0c;它们会呈现出不同的形状和大小。这种现象被称为透视效果。 透…

web-文件上传和upload-labs靶场通关

目录 前端过滤 uploads-lab-1: 后端验证 upload-labs-2&#xff1a;mime验证 upload-labs-3&#xff1a;黑名单绕过 upload-labs-4&#xff1a;黑名单绕过-.htaccess(这里得用旧版的phpstudy&#xff0c;新版的不行) upload-labs-5&#xff1a;后缀名绕过 upload-labs-…

探索南美专线:开启您的国际贸易之旅

​作为一个国际贸易从业者&#xff0c;您可能已经听说过南美专线。南美洲作为一个充满潜力的市场&#xff0c;吸引着越来越多的企业前来探索商机。南美专线是连接亚洲和南美洲的重要贸易通道&#xff0c;它为企业提供了便捷、高效的物流运输服务&#xff0c;助力您开拓南美市场…

Pycharm工具Python开发自动添加注释(详细)

方法自动添加参数注释 定义了一个函数&#xff0c;在函数下面敲入了三个双引号后&#xff0c;enter回车并没有自动出现注释&#xff0c;如图&#xff1a; 解决办法 Pycharm中依次打开File —> Settings —> Tools —> Python Integrated Tools&#xff0c;如图&…

android 如何分析应用的内存(十二)

android 如何分析应用的内存&#xff08;十二&#xff09; 上一篇介绍了ASan&#xff0c;这次介绍ASan的加强版HWASan HWASan的使用 从NDK r21和Android 10 开始&#xff0c;Android支持HWAsan。HWAsan仅仅支持arm64架构的设备。 系统级准备 HWASan需要系统的支持&#xf…

ZLMediaKit+wvp-GB28181-pro 安装文档

文章目录 前言1. 安装zlm1.1 镜像说明1.2 docker安装1.2.1 docker安装命令1.2.2 docker-compose安装 1.3. zlm配置和日志重点说明 2. 安装wvp2.1 目录结构说明2.1.1 导入idea2.1.2 sql文件夹自带初始化库脚本2.1.3 进入web_src 编译静态资源2.1.4 修改resources配置 2.2 wvp 启…

javafx实现拖拽复制功能

效果 代码 package cn.juhe.zjsb.test;import javafx.application.Application; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.SnapshotParameters; import javafx.scene.control.Label; import javafx.scene.control.TextField; impor…

java语言agent探针技术使用

打包插件 使用了三款 spring-boot-maven-plugin maven-jar-plugin maven-assembly-plugin&#xff08;可用或不可用&#xff09;&#xff0c;用于打zip包 web打包插件 spring-boot-maven-plugin maven-assembly-plugin 打包后生成的MANIFEST.MF文件 Manifest-Version:…

【LeetCode】79.单词搜索

题目 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或…

可可口乐题解

样例输入&#xff1a; cococala样例输出&#xff1a; 1思路分析&#xff1a; 这道题的 n n n是 8 8 8&#xff0c;所以可以无脑 d f s dfs dfs&#xff0c;那就变得非常简单了。 代码 (注释详解) &#xff1a; #include<iostream> using namespace std; char t[10]{…

flask中redirect、url_for、endpoint介绍

flask中redirect、url_for、endpoint介绍 redirect 在 Flask 中&#xff0c;redirect() 是一个非常有用的函数&#xff0c;可以使服务器发送一个HTTP响应&#xff0c;指示客户端&#xff08;通常是浏览器&#xff09;自动导航到新的 URL。基本上&#xff0c;它是用来重定向用…

我国数据出境制度实践进展

随着互联网在全球的普及和数字经济在全球的发展&#xff0c;数据跨境流动已经成为各个国家和地区重点关注的议题。数据的跨境流动同时具备个人权益保护、企业合规经营和各国监管合作与博弈三个维度&#xff0c;各国和地区近年来对个人信息的跨境流动高度重视&#xff0c;相继出…

《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(3)-再识Fiddler让你感性认识一下

1.简介 上一篇通过宏哥的介绍想必各位小伙伴或者童鞋们对Fiddler已经有了一个理性地认识&#xff0c;今天宏哥在从Fiddler的外貌介绍和分享一下&#xff0c;让小伙伴们或者童鞋们再对Fiddler有一个感性的认识&#xff0c;今天主要是对Fiddler的界面进行一个详细的介绍。 2.Fi…

饮用水、地下水除砷的方法——砷吸附树脂

砷&#xff08;As&#xff09;为非人体必需元素&#xff0c;既不溶解于水又不溶解于酸&#xff0c;在自然界有三价无机态 As(III)、五价无机态 As(V)以及有机砷MMA(甲基胂酸)、DMA(二甲基胂酸)、TMA(三甲基胂酸)等。 砷在水体中主要以三价和五价的无机酸形式存在&#xff0c;三…

Vue 渲染流程详解

在 Vue 里渲染一块内容&#xff0c;会有以下步骤及流程&#xff1a; 第一步&#xff0c;解析语法&#xff0c;生成AST 第二步&#xff0c;根据AST结果&#xff0c;完成data数据初始化 第三步&#xff0c;根据AST结果和DATA数据绑定情况&#xff0c;生成虚拟DOM 第四步&…