STM32自学笔记串口DMA发送/接收 FIFO 突发模式

2023-05-16

参考博文

串口发送TXPA9DMA2_Stream7通道4正常模式
串口发送RXPA10DMA2_Stream5通道4循环模式

串口波特率115200
PA9,PA10复用输出

注意点
串口接受数据dma方式不能开启串口接受中断
Dma双缓冲默认开启循环模式
Dma开启时需要确保相对应的标志位清零
仅在使能指针递增模式时允许突发模式
如果禁止数据流时仍有某些数据存留在FIFO 中, DMA 控制器会将剩余的数据继续传输到目标(即使已经有效禁止了数据流)。

以后再更USART串口空闲中断接受不定长数据

USART.h文件

#ifndef __MYUSART_H_
#define __MYUSART_H_

#include "stm32f4xx.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "LED.h"


/* 最大超时时间 */
#define TIMEOUT_MAX             	10000

/* 串口发送和接收数据寄存器地址 */
#define USART1_DR_BASE      	    (USART1_BASE + 0X04)



/* 串口波特率配置 */
#define USART1_BaudRate				115200



/* 串口发送使用的GPIO时钟 */
#define USART1_TX_GPIO_CLK			RCC_AHB1Periph_GPIOA
/* 串口发送使用的GPIO */
#define USART1_TX_GPIO				GPIOA
/* 串口发送使用的引脚 */
#define USART1_TX_Pin				GPIO_Pin_9
/* 串口发送复用配置的源 */
#define USART1_TX_PinSource			GPIO_PinSource9

/* 串口接收使用的GPIO时钟 */
#define USART1_RX_GPIO_CLK			RCC_AHB1Periph_GPIOA
/* 串口接收使用的GPIO */
#define USART1_RX_GPIO				GPIOA
/* 串口接收使用的引脚 */
#define USART1_RX_Pin				GPIO_Pin_10
/* 串口接收复用配置的源 */
#define USART1_RX_PinSource			GPIO_PinSource10


/*串口发送和接收使用DMA的时钟 */
#define USART1_DMA_CLK				RCC_AHB1Periph_DMA2
/* 串口发送使用的DMA流 */
#define USART1_TX_DMAStream			DMA2_Stream7
/* 串口发送使用的通道 */
#define USART1_TX_DMA_Channel		DMA_Channel_4
/* 串口发送DMA中断 */
#define USART_TX_DMA_IRQn			DMA2_Stream7_IRQn

/* 串口接收使用的DMA流 */
#define USART1_RX_DMAStream			DMA2_Stream5
/* 串口接收使用的通道 */
#define USART1_RX_DMA_Channel		DMA_Channel_4
/* 串口接收DMA中断 */
#define USART_RX_DMA_IRQn			DMA2_Stream5_IRQn



/* 完成 / 不完成 */
#define COMPLETE					1
#define UNCOMPLETE					0


/* 发送缓冲区大小 */
#define SENDBUFF_SIZE 					128
/* 发送缓冲区 */
extern uint8_t USART1_SendBuff[SENDBUFF_SIZE];
/* 发送标志 初始化发送完成  即USART1_TX_FLAG = COMPLETE */
extern uint8_t USART1_TX_FLAG;

/* 接收缓冲区大小 */
#define RECEIVEBUFF_SIZE				64
/* 接收缓冲区0 */
extern uint8_t USART1_ReceiveBuff0[RECEIVEBUFF_SIZE];
/* 接收缓冲区1 */
extern uint8_t USART1_ReceiveBuff1[RECEIVEBUFF_SIZE];



void USART1_Init(void);
void USART1_printf(char *format, ...);



#endif // __MYUSART_H_

USART.C文件

#include "USART.h"




/* 发送缓冲区 */
uint8_t USART1_SendBuff[SENDBUFF_SIZE] = {0};

/* 发送标志 初始化发送完成  即USART1_TX_FLAG = COMPLETE */
uint8_t USART1_TX_FLAG = COMPLETE;



/* 接收缓冲区0 */
uint8_t USART1_ReceiveBuff0[RECEIVEBUFF_SIZE] = {0};

/* 接收缓冲区1 */
uint8_t USART1_ReceiveBuff1[RECEIVEBUFF_SIZE] = {0};



/**
  * @brief  配置串口1 USART1 DMA发送和接收 并开启DMA传输完成中断
			串口发送和接收DMA FIFO模式 阈值4个字(16个字节) 突发模式16个节拍的1次突发
  * @retval None
  */
void USART1_Init(void)
{
	__IO uint16_t    	Timeout = TIMEOUT_MAX;	//配置超时等待时间
	
	/* 初始化结构体 */
	GPIO_InitTypeDef 	GPIO_InitStructure;		//GPIO初始化结构体 
	USART_InitTypeDef	USART_InitStructure;	//USART初始化结构体
	DMA_InitTypeDef		DMA_InitStructure;		//DMA初始化结构体
	NVIC_InitTypeDef 	NVIC_InitStructure;		//中断初始化结构体
	
	
	
	/*************** 配置GPIO ***************/
	
	/* 打开串口发送GPIO的时钟 */
	RCC_AHB1PeriphClockCmd(USART1_TX_GPIO_CLK|USART1_RX_GPIO_CLK, ENABLE);
	
	/* 设置串口发送的引脚为复用 */
	//设置复用推挽输出
	GPIO_InitStructure.GPIO_Pin = USART1_TX_Pin;
	//设置为复用模式
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	//设置为推挽模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	//输出速度为50MHz
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	//上拉
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	//根据初始化结构体配置
	GPIO_Init(USART1_TX_GPIO, &GPIO_InitStructure);
	
	/* 打开串口接收GPIO的时钟 */
	RCC_AHB1PeriphClockCmd(USART1_RX_GPIO_CLK, ENABLE);
	
	/* 设置串口接收的引脚为复用 */
	//设置复用推挽输出
	GPIO_InitStructure.GPIO_Pin = USART1_RX_Pin;
	//设置为复用模式
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	//设置为推挽模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	//输出速度为50MHz
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	//浮空
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	//根据初始化结构体配置
	GPIO_Init(USART1_RX_GPIO, &GPIO_InitStructure);
	
	/* 复用串口发送和接收引脚 */
	GPIO_PinAFConfig(USART1_TX_GPIO, USART1_TX_PinSource, GPIO_AF_USART1);
	GPIO_PinAFConfig(USART1_RX_GPIO, USART1_RX_PinSource, GPIO_AF_USART1);
	
	
	
	/*************** 配置串口 ***************/
	
	/* 开启串口1时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	/* 配置串口1 波特率115200 停止位1位 无校验位 使能发送和接收 */
	//设置波特率115200
	USART_InitStructure.USART_BaudRate = USART1_BaudRate;
	//设置字长为8位
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	//设置停止位1位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	//无校验
	USART_InitStructure.USART_Parity = USART_Parity_No;
	//开启接收和发送
	USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
	//硬件流控制:不使用硬件流
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	//配置USART1
	USART_Init(USART1, &USART_InitStructure);
	
	/* 开启DMA发送和接收 */
	USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
	USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
	
	
	
	/*************** 配置串口发送DMA ***************/
	
	/* 打开DMA时钟 */
	RCC_AHB1PeriphClockCmd(USART1_DMA_CLK, ENABLE);
	
	/* 复位DMA
		在启用DMA流之前,请检查它是否已禁用。
		请注意,当同一个流被多次使用时,此步骤非常有用:
		启用,然后禁用,然后重新启用...
		在这种情况下,DMA流禁用只有在进行中的数据传输结束时才有效。
		在确认启用位之前不可能重新配置它已经被硬件清除了。
		如果流只使用一次,则此步骤可能被绕过。
		***个人理解 假如之前使用该DMA的这个流则此时DMA是启用状态
		现在我们复用该流,但是该DMA是启用状态,只有当它数据传输结束的时候我们才能真正的禁用它
		所以我们得检测它是不是在启用状态,如果是启用状态则等待它数据传输完成。
		在他禁用有效之后也就是数据传输完成之后我们再配置该DMA的流*/
	DMA_DeInit(USART1_TX_DMAStream);
	
	/* 检测确保DMA数据流复位完成 也就是一直是启用状态 如果复位完成应该是DISABLE */
	while(DMA_GetCmdStatus(USART1_TX_DMAStream) == ENABLE);
	
	/* 串口发送DMA配置 */
	//通道选择
	DMA_InitStructure.DMA_Channel = USART1_TX_DMA_Channel;
	//外设基地址
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)USART1_DR_BASE;
	//存储器地址
	DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART1_SendBuff;
	//模式选择 存储器到外设
	DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
	//需要传输的数据数目
	DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;
	//外设地址是否自增 这里选择不自增
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	//存储器地址是否自增 这里选择自增
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	//设置外设数据宽度 1个字节
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	//设置存储器数据宽度 1个字节
	DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
	//一次传输模式
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	//循环传输模式
	//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
	//设置优先级高
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	//启用FIFO模式
	DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
	//外设单次模式		不使用突发模式
	DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
	//存储器突发模式 	16个字节一次突发
	DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC16;
	
	/* 根据初始化结构体配置DMA */
	DMA_Init(USART1_TX_DMAStream, &DMA_InitStructure);
	
	
	
	/*************** 配置串口接收DMA ***************/
	
	/* 打开DMA时钟 */
	RCC_AHB1PeriphClockCmd(USART1_DMA_CLK, ENABLE);
	
	/* 复位DMA
		在启用DMA流之前,请检查它是否已禁用。
		请注意,当同一个流被多次使用时,此步骤非常有用:
		启用,然后禁用,然后重新启用...
		在这种情况下,DMA流禁用只有在进行中的数据传输结束时才有效。
		在确认启用位之前不可能重新配置它已经被硬件清除了。
		如果流只使用一次,则此步骤可能被绕过。
		***个人理解 假如之前使用该DMA的这个流则此时DMA是启用状态
		现在我们复用该流,但是该DMA是启用状态,只有当它数据传输结束的时候我们才能真正的禁用它
		所以我们得检测它是不是在启用状态,如果是启用状态则等待它数据传输完成。
		在他禁用有效之后也就是数据传输完成之后我们再配置该DMA的流*/
	DMA_DeInit(USART1_RX_DMAStream);
	
	/* 检测确保DMA数据流复位完成 也就是一直是启用状态 如果复位完成应该是DISABLE */
	while(DMA_GetCmdStatus(USART1_RX_DMAStream) == ENABLE);
	
	/* 串口发送DMA配置 */
	//通道选择
	DMA_InitStructure.DMA_Channel = USART1_RX_DMA_Channel;
	//外设基地址
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)USART1_DR_BASE;
	//存储器地址
	DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART1_ReceiveBuff0;
	//模式选择 外设到存储器
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
	//需要传输的数据数目
	DMA_InitStructure.DMA_BufferSize = RECEIVEBUFF_SIZE;
	//外设地址是否自增 这里选择不自增
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	//存储器地址是否自增 这里选择自增
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	//设置外设数据宽度 1个字节
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	//设置存储器数据宽度 1个字节
	DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
	//一次传输模式
	//DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	//循环传输模式
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
	//设置优先级高
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	//启用FIFO模式
	DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
	//外设单次模式		不使用突发模式
	DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
	//存储器突发模式 	16个字节一次突发
	DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC16;
	
	/* 串口接收DMA双缓冲模式 */
	DMA_DoubleBufferModeConfig(USART1_RX_DMAStream, (uint32_t)USART1_ReceiveBuff1, DMA_Memory_0);
	DMA_DoubleBufferModeCmd(USART1_RX_DMAStream, ENABLE);
	
	/* 根据初始化结构体配置DMA */
	DMA_Init(USART1_RX_DMAStream, &DMA_InitStructure);
	
	
	
	/*************** 配置串口发送DMA中断 ***************/
	
	/* 设置串口发送DMA传输完成中断 */
	
	/* 指定要启用或禁用的IRQ通道。
	此参数可以是@ref IRQn_类型的枚举器枚举
	(对于完整的STM32设备IRQ通道列表,请参考stm32f4xx.h文件)*/
	NVIC_InitStructure.NVIC_IRQChannel = USART_TX_DMA_IRQn;
	
	/* 指定IRQ通道的抢占优先级
	在NVIC的IRQChannel中指定。此参数可以是值
	如表@ref MISC_NVIC_Priority_table所述,介于0和15之间较低的优先级值表示优先级较高*/
	//设置抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	
	/* 指定指定IRQ通道的子优先级级别在NVIC信道中。
	此参数可以是值
	如表@ref MISC_NVIC_Priority_table所述,介于0和15之间
	较低的优先级值表示优先级较高*/
	//设置子优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	
	/*指定是否在NVIC的IRQChannel中定义IRQ通道将启用或禁用。
	此参数可以设置为启用或禁用*/
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	
	/* 根据指定的初始化NVIC外围设备
	*NVIC_InitStruct中的参数。*/
	//根据自定义的中断初始化结构体初始化中断
	NVIC_Init(&NVIC_InitStructure);
	
	/* 打开串口发送DMA传输完成中断 */
	DMA_ITConfig(USART1_TX_DMAStream, DMA_IT_TC, ENABLE);
	
	
	
	/*************** 配置串口接收DMA中断 ***************/
	
	/* 设置串口接收DMA传输完成中断 */
	
	/* 指定要启用或禁用的IRQ通道。
	此参数可以是@ref IRQn_类型的枚举器枚举
	(对于完整的STM32设备IRQ通道列表,请参考stm32f4xx.h文件)*/
	NVIC_InitStructure.NVIC_IRQChannel = USART_RX_DMA_IRQn;
	
	/* 指定IRQ通道的抢占优先级
	在NVIC的IRQChannel中指定。此参数可以是值
	如表@ref MISC_NVIC_Priority_table所述,介于0和15之间较低的优先级值表示优先级较高*/
	//设置抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	
	/* 指定指定IRQ通道的子优先级级别在NVIC信道中。
	此参数可以是值
	如表@ref MISC_NVIC_Priority_table所述,介于0和15之间
	较低的优先级值表示优先级较高*/
	//设置子优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	
	/*指定是否在NVIC的IRQChannel中定义IRQ通道将启用或禁用。
	此参数可以设置为启用或禁用*/
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	
	/* 根据指定的初始化NVIC外围设备
	*NVIC_InitStruct中的参数。*/
	//根据自定义的中断初始化结构体初始化中断
	NVIC_Init(&NVIC_InitStructure);
	
	/* 打开串口接收DMA传输完成中断 */
	DMA_ITConfig(USART1_RX_DMAStream, DMA_IT_TC, ENABLE);
	
	
	
	/*************** 使能DMA和串口 ***************/
	
	/* 使能串口接收DMA */
	DMA_Cmd(USART1_RX_DMAStream, ENABLE);
	
	/* 检查DMA流是否已有效启用。
		如果存在配置参数错误,传输未启动(即
		配置了错误的FIFO阈值…)*/
	//检测DMA数据流是否有效并带有超时检测功能
	Timeout = TIMEOUT_MAX;
	while(DMA_GetCmdStatus(USART1_RX_DMAStream) == DISABLE && Timeout-- > 0);
	//超时就让程序运行下面循环:红色LED灯闪烁
	if(Timeout == 0)
	{
		while(1)
		{
			LED_R = ~LED_R;
			Delay_ms(500);
		}
	}
	
	/* 使能串口 */
	USART_Cmd(USART1, ENABLE);
	
}




/**
  * @brief  串口发送 DMA方式
  * @param  length: 数组长度
  * @retval 无
  */
static void USART1_DMA_Send(uint16_t length)
{
	/* 等待上一次发送完成 如果USART1_TX_FLAG为COMPLETE则上一次发送完成 */
	while(USART1_TX_FLAG != COMPLETE)
	{
	}
	
	/* 设置这次的发送标志未完成 */
	USART1_TX_FLAG = UNCOMPLETE;
	
	/* 设置需要发送的数组地址
		也可以用寄存器操作DMA2_Stream7->M0AR = (uint32_t)data;*/
	//DMA_MemoryTargetConfig(DMA2_Stream7, (uint32_t)data, DMA_Memory_0);
	
	/* 设置需要发送的字节长度
		也可以用寄存器操作DMA2_Stream7->NDTR = (uint16_t)length;*/
	DMA_SetCurrDataCounter(USART1_TX_DMAStream, length);
	
	/* 使能串口发送DMA */
	DMA_Cmd(USART1_TX_DMAStream, ENABLE);
}



/**
  * @brief  串口发送仿printf DMA方式
  * @param  format: 需要发送的数据
  * @retval 无
  */
void USART1_printf(char *format, ...)
{
	//VA_LIST 是在C语言中解决变参问题的一组宏,所在头文件:#include <stdarg.h>,用于获取不确定个数的参数。
	va_list arg_ptr;													//实例化可变长参数列表
	
	va_start(arg_ptr, format); 											//初始化可变参数列表,设置format为可变长列表的起始点(第一个元素)
	//SENDBUFF_SIZE + 1 假如不加1的话最大只能发SENDBUFF_SIZE - 1个字节 因为vsnprintf()函数会再拼接好字符串之后自动加上'\0' 占一个字节
	//所以我们要提高一个字节
	vsnprintf((char*)USART1_SendBuff, SENDBUFF_SIZE + 1, format, arg_ptr);	//USART1_SendBuff从的首地址开始拼合,拼合format内容;防止产生数组越界
	
	va_end(arg_ptr);													//注意必须关闭
	
	/* 串口DMA发送 */
	USART1_DMA_Send(strlen((const char*)USART1_SendBuff));
}







重定向c库函数printf到串口,重定向后可使用printf函数
//int fputc(int ch, FILE *f)
//{
//	/* 发送一个字节数据到串口 */
//	USART1_SendData(ch);

//	/* 等待发送完毕 */
//	while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);		

//	return (ch);
//}

/重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
不能使用中断
//int fgetc(FILE *f)
//{
//	/* 等待串口输入数据 */
//	while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

//	return (int)USART_ReceiveData(USART1);
//}




中断函数


/**
* @brief  串口DMA发送传输完成中断函数
  * @param  None
  * @retval None
  */
void DMA2_Stream7_IRQHandler(void)
{
	/* 检查DMA传输完成标志位 */
	if(DMA_GetITStatus(USART1_TX_DMAStream, DMA_IT_TCIF7))
	{
		//清除标志位
		DMA_ClearITPendingBit(USART1_TX_DMAStream, DMA_IT_TCIF7);
		//设置发送标志位为完成
		USART1_TX_FLAG = COMPLETE;
	}
}

/**
  * @brief  串口DMA接收传输完成中断函数
  * @param  None
  * @retval None
  */
void DMA2_Stream5_IRQHandler(void)
{
	/* 检查DMA传输完成标志位 */
	if(DMA_GetITStatus(USART1_RX_DMAStream, DMA_IT_TCIF5))
	{
		//清除中断标志 
		DMA_ClearITPendingBit(USART1_RX_DMAStream, DMA_IT_TCIF5);
		LED_B = ~LED_B;
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32自学笔记串口DMA发送/接收 FIFO 突发模式 的相关文章

  • ffmpeg错误总结

    av err2str 在C 43 43 项目中 xff0c 使用FFmpeg中的av err2str函数时 xff0c 报错 解决 xff1a 调用该函数的文件开始加上以下代码 xff1a span class token keyword
  • 【JVM】垃圾回收算法

    垃圾回收算法 文章目录 垃圾回收算法标记 清除算法标记 复制算法Appel式回收 标记整理算法混合使用 标记 清除算法 标记 清除算法是最早出席那也是最基础的垃圾收集算法 xff0c 是1960年由Lisp之父John McCarthy所提
  • 【JVM】如何判决一个对象的生死

    如何判决一个对象的生死 文章目录 如何判决一个对象的生死如何判断对象是否存活 xff08 应该被回收 xff09 引用计数法可达性分析算法引用生存还是死亡 如何判断对象是否存活 xff08 应该被回收 xff09 引用计数法 很多教科书判断
  • 【大前端】vue,jq,uniapp ajax默认的请求格式

    vue jq uniapp ajax默认的请求格式 文章目录 vue jq uniapp ajax默认的请求格式常见的内容类型 xff08 content type xff09 jq默认请求格式默认内容类型 xff1a multipart
  • 【大前端】uniapp上传图片

    uniapp上传图片 看本篇文章之前建议看下本篇文章 直接上代码 uni chooseImage success chooseImageRes 61 gt 获取文件的路径 const tempFilePaths 61 chooseImage
  • 【JavaWeb】el表达式与jstl标签的使用

    el表达式与jstl标签的使用 el表达式 简介 el表达式的全称 xff1a Expression Language 是表达式语言 EL表达式的作用 xff1a EL表达式主要是代替jsp页面中的表达式脚本在jsp页面中进行数据的输出 因
  • 【Java】说说Java的线程池

    说说Java的线程池 文章目录 说说Java的线程池为什么要使用线程池ThreadPoolExecutor提供的构造方法解析 线程池处理流程 为什么要使用线程池 创建 销毁线程需要消耗系统资源 xff0c 线程池可以复用已创建的线程控制并发
  • 【Java】Java的类加载器和双亲委派模型

    文章目录 类加载器双亲委派模型 类加载器 对于任意一个类 xff0c 都必须由加载它的类加载器和这个类本身一起共同确立其在Java虚拟机中的唯一性 xff0c 每一个类加载器 xff0c 都有一个独立的类名称空间 比较两个类是否 34 相等
  • 【git】说说git的基础命令

    git的基础命令 命令名称作用git config global user name 用户名设置用户签名git config global user email 邮箱设置用户签名git init初始化本地库git status查看本地库状态
  • 【maven】maven基础知识入门

    maven 文章目录 maven什么是maven为什么使用maven项目构建过程的几个主要环节maven核心概念如何通过坐标到仓库中查找jar包 什么是maven Maven 是 Apache 软件基金会组织维护的一款自动化构建工具 xff
  • 【spring】说说spring的IOC与DI

    说说spring的IOC与DI 文章目录 说说spring的IOC与DIid属性和name属性标签scope Bean的作用范围Spring xff0c 配置生成Bean的三种方式Sping 的 Bean属性注入Sping的Bean属性通过
  • ffmpeg时间戳相关函数

    1 概述 ffmpeg中与时间戳相关的函数主要有 xff1a av rescale q xff0c av rescale q rnd xff0c av compare ts av rescale q span class token cla
  • 【计算机网络】网线规格的鉴别与接线方法

    网线规格的鉴别与接线发送 文章目录 网线规格的鉴别与接线发送一 怎么判断网线类型 xff1f 二 制作网线标准三 屏蔽类型四 使用场景五 米数标记接线方法 一 怎么判断网线类型 xff1f 可以根据网线外皮的标识来判断 xff0c 正规厂商
  • 【Java】说说spring-jdbc和spring事务管理

    文章目录 说说spring jdbc和spring事务管理spring jdbc1 配置数据源2 使用jdbcTemplete3 在dao层使用jdbcTemplete 外部配置方式新建配置文件jdbc properties修改数据源配置部
  • 【微服务】springcloud-dubbo,springCloudAlibaba服务调用使用dubbo

    springcloud dubbo xff0c springCloudAlibaba服务调用使用dubbo 文章目录 springcloud dubbo xff0c springCloudAlibaba服务调用使用dubbo添加依赖配置具体
  • 【项目实战】spring boot中使用webSocket

    spring boot中使用webSocket 文章目录 spring boot中使用webSocket引入依赖支持配置类接口类前端连接方式前端信息发送方式 引入依赖 需要在基础的spring boot web项目项目中添加下面一个依赖 x
  • 【项目复盘】springboot项目中使用mybatis-plus进行分页

    springboot项目中使用mybatis plus进行分页 文章目录 springboot项目中使用mybatis plus进行分页引入依赖配置类实体类持久层业务层 引入依赖 span class token generics span
  • 【项目复盘】javax.validation的简单使用

    javax validation的简单使用 javax validation需要与hibernate validator配合使用 validation bean 是基于JSR 303标准开发出来的 xff0c 使用注解方式实现 xff0c
  • 【项目复盘】springboot中使用swagger生成接口文档并配置bootstrap主题

    springboot中使用swagger生成接口文档并配置bootstrap主题 引入依赖 span class token generics span class token punctuation lt span dependency
  • 【项目复盘】微服务网关GateWay过滤

    微服务网管过滤 新建一个过滤类 span class token annotation punctuation 64 Component span span class token comment 过滤器的执行优先级 返回值越小 执行优先级

随机推荐

  • 【项目实战】Winodws下使用ELK搭建日志分析框架

    项目实战 Winodws下使用ELK搭建日志分析框架 ELK是什么 xff1a 引用官网的一句话 xff1a 核心产品包括 Elasticsearch Kibana Beats 和 Logstash xff08 也称为 ELK Stack
  • java_网络编程知识

    day11 网络编程 主要内容 软件架构CS xff0f BS网络通信三要素TCP通信Socket套接字ServerSocket 学习目标 能够辨别UDP和TCP协议特点 能够说出TCP协议下两个常用类名称 能够编写TCP协议下字符串数据传
  • AvFrame和AvPacket

    在FFmpeg中 未压缩的图像和压缩的视频码流分别使用AVFrame结构和AVPacket结构保存 针对视频编码器 其流程为从数据源获取图像格式的输入数据 保存为AVFrame对象并传入编码器 从编码器输出AVPacket结构 1 AVFr
  • 基于FreeRTOS的stm32程序初始化底层搭建(hal库)

    采用嵌入式实时操作系统 RTOS 可以更合理 更有效地利用CPU的资源 xff0c 简化应用软件的设计 xff0c 缩短系统开发时间 xff0c 更好地保证系统的实时性和可靠性 FreeRTOS是一个迷你的实时操作系统内核 作为一个轻量级的
  • ceres小结 -- vins为例

    从 typora 复制的 排版有问题 见谅 在estimator cpp文件里 这个函数 void Estimator optimization 1 声明problem ceres Problem problem 2 引入核函数loss f
  • JavaScript操作表格及CSS样式

    概述 在前端开发中 xff0c 表格主要用于存储结构化的数据 xff0c CSS主要用于修饰DOM元素 xff0c 如何通过DOM来操作表格及CSS呢 xff1f 本文主要通过一些简单的小例子 xff0c 简述DOM对表格和CSS的常见操作
  • 转:Git Submodule管理项目子模块

    使用场景 当项目越来越庞大之后 xff0c 不可避免的要拆分成多个子模块 xff0c 我们希望各个子模块有独立的版本管理 xff0c 并且由专门的人去维护 xff0c 这时候我们就要用到git的submodule功能 常用命令 span c
  • Linux/c++服务器开发方向的重点

    作者 xff1a NULL 链接 xff1a https www zhihu com question 37247264 answer 2352680534 来源 xff1a 知乎 著作权归作者所有 商业转载请联系作者获得授权 xff0c
  • Prometheus之Dockerfile编写、镜像构建、容器启动

    Python微信订餐小程序课程视频 https edu csdn net course detail 36074 Python实战量化交易理财系统 https edu csdn net course detail 35475 目录 从官方镜
  • Java的接口调用

    最近在观看一个Android开发中 xff0c 有一个问题百思不得其解 xff0c 就是从Fragment传数据回Activity和Activity传数据到Fragment中 xff0c bundle其实刚开始还是理解的 xff0c 但是当
  • X86实模式与保护模式简介

    0 引言 从80386开始 xff0c CPU有三种工作方式 xff1a 实模式 xff0c 保护模式和虚拟8086模式 v86模式 只有在刚刚启动的时候是real mode xff0c 等到操作系统运行起来以后就切换到protected
  • (1)VisDrone无人机目标检测数据集介绍

    数据集介绍 官网 xff1a http aiskyeye com VisDrone数据集 xff0c 包含了10个类 xff08 即行人 人 汽车 面包车 公共汽车 卡车 汽车 自行车 遮阳三轮车和三轮车 xff09 无人机计算机视觉相关检
  • 简单的shell编程的语法

    shell 1 span class token punctuation span 脚本以 span class token comment bin bash 开头 span span class token comment 脚本的常用执行
  • 使用c++模板的优点和缺点

    作为C 43 43 语言的新组成部分 xff0c 模板引入了基于通用编程的概念 通用编程是一种无须考虑特定对象的描述和发展算法的方法 xff0c 因此它与具体数据结构无关 但在决定使用C 43 43 模板之前 xff0c 让我们分析一下使用
  • kalibr 进行相机单目、双目标定全流程

    一 部署kalibr环境 docker 步骤 xff1a 参考链接 xff1a Installation ethz asl kalibr Wiki GitHub Docker操作知识 xff1a Docker攻略 xff1a 从安装到入门到
  • kalibr源码阅读参考

    Kalibr简介 xff1a Kalibr是一个用于标定多相机系统和IMU xff08 惯性测量单元 xff09 的开源工具包 xff0c 旨在提供一套完整的 易于使用的标定工具 它是ETH Zurich自主飞行系统实验室的一个项目 xff
  • QT5.11.1下的DirectShowPlayerService::doRender: Unresolved error code 0x80040266 ()报错)

    64 TOC QT5 11 1下的DirectShowPlayerService doRender Unresolved error code 0x80040266 报错 1 实验环境 实验环境 xff1a xff08 1 xff09 QT
  • GPS定位中的卡尔曼滤波算法

    卡尔曼滤波 xff1a 卡尔曼滤波由预测和校正两部分组成 预测部份又称时间更新过程 xff0c 是在上一个历元 k 1 状态估计值的基础上 xff0c 利用系统的状态方程来预测当前历元 k 的状态值 校正部分又叫测量更新过程 xff0c 它
  • 古月居ROS21讲入门(10)发布者Publisher的编程实现(源代码详解)

    发布者Publisher的编程实现 源代码详解 一 话题模型二 创建learning topic功能包三 实现一个发布者1 初始化ROS节点2 注册节点信息3 创建消息数据 四 配置CMakeLists txt中的编译规则五 编译并运行发布
  • STM32自学笔记串口DMA发送/接收 FIFO 突发模式

    参考博文 串口发送TXPA9DMA2 Stream7通道4正常模式串口发送RXPA10DMA2 Stream5通道4循环模式 串口波特率115200 PA9 PA10复用输出 注意点 串口接受数据dma方式不能开启串口接受中断 Dma双缓冲