PY32F003F18之DMA串口

PY32F003F18使用DMA串口,官方程序省FLASH,但不省内存。单片机内存够大,节省没意义,故做了修改,少用HAL库中的发送和接收,从里面抠出有用的部分,修修改改就可以了。

一、DMA串口初始化流程:

假定:串口发送引脚USART2_TX使用PA0,串口接收引脚USART2_RX使用PA1
1、使能USART2外设时钟,__HAL_RCC_USART2_CLK_ENABLE();

2、使能GPIOA时钟,__HAL_RCC_GPIOA_CLK_ENABLE();

3、将串口发送引脚USART2_TX映射到PA0

4、将串口接收引脚USART2_RX映射到PA1

5、设置串口帧格式和波特率

6、将DMA通道1映射到USART2_TX,将DMA通道2映射到USART2_RX

  __HAL_RCC_SYSCFG_CLK_ENABLE();//使能RCC外设时钟
    HAL_SYSCFG_DMA_Req(0x0807);
    //配置"SYSCFG配置寄存器3(SYSCFG_CFGR3)"
    //DMA1_MAP[4:0]=7,将DMA通道1映射到USART2_TX
    //DMA2_MAP[4:0]=8,将DMA通道2映射到USART2_RX

7、配置DMA串口发送,传输"从内存到外设"

8、配置DMA串口接收,传输"从外设到内存"

9、关闭串口接收中断

10、不使能"串口发送数据寄存器为空"产生中断

11、不使能"串口发送完成"产生中断

二、测试程序

#include "USART2.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()
#include "My_DMA.h"
#include "delay.h"//PA0 ------> USART2_TX
//PA1 ------> USART2_RXuint8_t USART2_TX_Buffer[USART2_TX_Buffer_Size]; //USART2发送缓冲区数组;
uint8_t USART2_TX_Buffer_Send_Index=0;          //USART2_TX_Buffer[]的发送索引值;
uint8_t USART2_TX_Buffer_Load_Index=0;          //USART2_TX_Buffer[]的装载索引值
uint8_t USART2_TX_Completed_Flag;
uint8_t USART2_TX_Overtime_Conter;//USART2发送超时计数器uint8_t USART2_RX_Buffer[USART2_RX_Buffer_Size]; //USART2接收缓冲区数组
uint8_t USART2_RX_Buffer_StartIndex;//USART2_RX_Buffer[]的装载索引值
uint8_t USART2_RX_Buffer_EndIndex;//USART2_RX_Buffer[]的装载索引值
uint8_t USART2_RX1_Buffer[USART2_RX1_Buffer_Size]; //USART2接收缓冲区数组void USART2_Init(uint32_t baudrate);
void Usart2Send(void);
void Usart2Receive(void);void Usart2Send_DMA1_CH1_config(void);
void Usart2Receive_DMA1_CH2_config(void);#if USART2Type == 0 
//函数功能:
//PA2是为USART2_TX,PA3是USART2_RX
//中断优先级为0x01
//波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
void USART2_Init(uint32_t baudrate)
{GPIO_InitTypeDef  GPIO_InitStructureure;UART_HandleTypeDef UART_HandleStructureure;/HAL_UART_MspInit开始__HAL_RCC_USART2_CLK_ENABLE();//使能USART2外设时钟__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟//串口引脚映射开始/GPIO_InitStructureure.Pin = GPIO_PIN_2;     //选择第2脚,PA2是为USART2_TXGPIO_InitStructureure.Mode = GPIO_MODE_AF_PP;            //复用功能推挽模式GPIO_InitStructureure.Pull = GPIO_PULLUP;                //引脚上拉被激活GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速GPIO_InitStructureure.Alternate = GPIO_AF4_USART2;       //将引脚复用为USART2HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);//根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器//将PA0初始化为USART2_TXGPIO_InitStructureure.Pin = GPIO_PIN_3;     //选择第3脚,PA3是USART2_RXGPIO_InitStructureure.Mode = GPIO_MODE_AF_PP;            //复用功能推挽模式GPIO_InitStructureure.Pull = GPIO_PULLUP;                //引脚上拉被激活GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速GPIO_InitStructureure.Alternate = GPIO_AF4_USART2;       //将引脚复用为USART2HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);//根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器//将PA1初始化为USART2_RX
//串口引脚映射结束/
/HAL_UART_MspInit结束UART_HandleStructureure.Instance          = USART2;              //接口为USART2UART_HandleStructureure.Init.BaudRate     = baudrate;            //波特率为115200bpsUART_HandleStructureure.Init.WordLength   = UART_WORDLENGTH_8B;  //串口字长度为8UART_HandleStructureure.Init.StopBits     = UART_STOPBITS_1;     //串口停止位为1位UART_HandleStructureure.Init.Parity       = UART_PARITY_NONE;    //串口无需奇偶校验UART_HandleStructureure.Init.HwFlowCtl    = UART_HWCONTROL_NONE; //串口无硬件流程控制UART_HandleStructureure.Init.Mode         = UART_MODE_TX_RX;     //串口工作模式为发送和接收模式UART_HandleStructureure.AdvancedInit.AdvFeatureInit=UART_ADVFEATURE_NO_INIT;//不使用自动波特率
//	UART_HandleStructureure.AdvancedInit.AdvFeatureInit=UART_ADVFEATURE_AUTOBAUDRATE_INIT;//使用自动波特率配置
//	UART_HandleStructureure.AdvancedInit.AutoBaudRateEnable=UART_ADVFEATURE_AUTOBAUDRATE_ENABLE;//自动波特率使能
//	UART_HandleStructureure.AdvancedInit.AutoBaudRateMode=UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT;//自动波特率模式HAL_UART_Init(&UART_HandleStructureure);//根据UART_HandleStructureure型结构初始化USART2__HAL_RCC_SYSCFG_CLK_ENABLE();//使能RCC外设时钟HAL_SYSCFG_DMA_Req(0x0807);//配置"SYSCFG配置寄存器3(SYSCFG_CFGR3)"//DMA1_MAP[4:0]=7,将DMA通道1映射到USART2_TX//DMA2_MAP[4:0]=8,将DMA通道2映射到USART2_RXUsart2Send_DMA1_CH1_config();Usart2Receive_DMA1_CH2_config();//  HAL_NVIC_SetPriority(USART2_IRQn, 0x01, 0);//设置串口2中断优先级为0x01,0无意义.USART2_IRQn表示中断源为串口2//	__HAL_UART_ENABLE_IT(&UART_HandleStructureure, UART_IT_RXNE);//开启串口接收中断//串口接收数据时,使能"接收数据寄存器不为空"则产生中断(位RXNE=1)//Enable the UART Data Register not empty Interrupt__HAL_UART_DISABLE_IT(&UART_HandleStructureure, UART_IT_RXNE);//关闭串口接收中断//串口接收数据时,不使能"接收数据寄存器不为空"则产生中断(位RXNE=0)__HAL_UART_DISABLE_IT(&UART_HandleStructureure, UART_IT_TXE);//串口发送数据时,不使能"串口发送数据寄存器为空"产生中断(位TXE=0)//Disable the UART Transmit Complete Interrupt__HAL_UART_DISABLE_IT(&UART_HandleStructureure,UART_IT_TC);//串口发送数据时,不使能"串口发送完成"产生中断(位TC=1)
/在串口中断服务函数中发送数据配置结束////  HAL_NVIC_EnableIRQ(USART2_IRQn);//使能串口2中断//USART2_IRQn表示中断源为串口2
}
#endif#if USART2Type ==1
//函数功能:
//PA0是为USART2_TX,PA1是USART2_RX
//中断优先级为0x01
//波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
void USART2_Init(uint32_t baudrate)
{GPIO_InitTypeDef  GPIO_InitStructureure;UART_HandleTypeDef UART_HandleStructureure;/HAL_UART_MspInit开始__HAL_RCC_USART2_CLK_ENABLE();//使能USART2外设时钟__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟//串口引脚映射开始/GPIO_InitStructureure.Pin = GPIO_PIN_0;     //选择第0脚,PA0是为USART2_TXGPIO_InitStructureure.Mode = GPIO_MODE_AF_PP;            //复用功能推挽模式GPIO_InitStructureure.Pull = GPIO_PULLUP;                //引脚上拉被激活GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速GPIO_InitStructureure.Alternate = GPIO_AF9_USART2;       //将引脚复用为USART2HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);//根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器//将PA0初始化为USART2_TXGPIO_InitStructureure.Pin = GPIO_PIN_1;     //选择第1脚,PA1是USART2_RXGPIO_InitStructureure.Mode = GPIO_MODE_AF_PP;            //复用功能推挽模式GPIO_InitStructureure.Pull = GPIO_PULLUP;                //引脚上拉被激活GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速GPIO_InitStructureure.Alternate = GPIO_AF9_USART2;       //将引脚复用为USART2HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);//根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器//将PA1初始化为USART2_RX
//串口引脚映射结束/
/HAL_UART_MspInit结束UART_HandleStructureure.Instance          = USART2;              //接口为USART2UART_HandleStructureure.Init.BaudRate     = baudrate;            //波特率为115200bpsUART_HandleStructureure.Init.WordLength   = UART_WORDLENGTH_8B;  //串口字长度为8UART_HandleStructureure.Init.StopBits     = UART_STOPBITS_1;     //串口停止位为1位UART_HandleStructureure.Init.Parity       = UART_PARITY_NONE;    //串口无需奇偶校验UART_HandleStructureure.Init.HwFlowCtl    = UART_HWCONTROL_NONE; //串口无硬件流程控制UART_HandleStructureure.Init.Mode         = UART_MODE_TX_RX;     //串口工作模式为发送和接收模式UART_HandleStructureure.AdvancedInit.AdvFeatureInit=UART_ADVFEATURE_NO_INIT;//不使用自动波特率
//	UART_HandleStructureure.AdvancedInit.AdvFeatureInit=UART_ADVFEATURE_AUTOBAUDRATE_INIT;//使用自动波特率配置
//	UART_HandleStructureure.AdvancedInit.AutoBaudRateEnable=UART_ADVFEATURE_AUTOBAUDRATE_ENABLE;//自动波特率使能
//	UART_HandleStructureure.AdvancedInit.AutoBaudRateMode=UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT;//自动波特率模式HAL_UART_Init(&UART_HandleStructureure);//根据UART_HandleStructureure型结构初始化USART2__HAL_RCC_SYSCFG_CLK_ENABLE();//使能RCC外设时钟HAL_SYSCFG_DMA_Req(0x0807);//配置"SYSCFG配置寄存器3(SYSCFG_CFGR3)"//DMA1_MAP[4:0]=7,将DMA通道1映射到USART2_TX//DMA2_MAP[4:0]=8,将DMA通道2映射到USART2_RXUsart2Send_DMA1_CH1_config();Usart2Receive_DMA1_CH2_config();//  HAL_NVIC_SetPriority(USART2_IRQn, 0x01, 0);//设置串口2中断优先级为0x01,0无意义.USART2_IRQn表示中断源为串口2//	__HAL_UART_ENABLE_IT(&UART_HandleStructureure, UART_IT_RXNE);开启串口接收中断//串口接收数据时,使能"接收数据寄存器不为空"则产生中断(位RXNE=1)//Enable the UART Data Register not empty Interrupt__HAL_UART_DISABLE_IT(&UART_HandleStructureure, UART_IT_RXNE);//关闭串口接收中断//串口接收数据时,不使能"接收数据寄存器不为空"则产生中断(位RXNE=0)__HAL_UART_DISABLE_IT(&UART_HandleStructureure, UART_IT_TXE);//串口发送数据时,不使能"串口发送数据寄存器为空"产生中断(位TXE=0)//Disable the UART Transmit Complete Interrupt__HAL_UART_DISABLE_IT(&UART_HandleStructureure,UART_IT_TC);//串口发送数据时,不使能"串口发送完成"产生中断(位TC=1)
/在串口中断服务函数中发送数据配置结束////  HAL_NVIC_EnableIRQ(USART2_IRQn);//使能串口2中断//USART2_IRQn表示中断源为串口2}
#endif//重定义fputc函数
//函数功能:发送ch的值给USART2串口
int fputc(int ch, FILE *f)
{_HAL_UART_SendByte(USART2, (unsigned char) ch);while( _HAL_UART_GET_FLAG(USART2,USART_SR_TC)!= SET); //等待发送完成标志位被置1	return ch;
}//函数功能:串口2发送一个字节
void USART2_SendByte(  unsigned char ch )
{_HAL_UART_SendByte(USART2, (unsigned char) ch);while( _HAL_UART_GET_FLAG(USART2,USART_SR_TC)!= SET); //等待发送完成标志位被置1
}void Usart2Send_DMA1_CH1_config(void)
{DMA_HandleTypeDef hdma_usart2_tx;__HAL_RCC_SYSCFG_CLK_ENABLE();//使能RCC外设时钟__HAL_RCC_DMA_CLK_ENABLE();   //使能DMA时钟///配置串口DMA发送开始hdma_usart2_tx.DmaBaseAddress = DMA1;                //选择DMA1传输hdma_usart2_tx.Instance = DMA1_Channel1;             //DMA1通道1hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;//DMA传输方向:从内存到外设hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;    //不使能外设地址增量hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;        //使能内存地址增量hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;//外设数据宽度为8位hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;   //存储器数据宽度为8位hdma_usart2_tx.Init.Mode = DMA_NORMAL;                        //DMA普通模式hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;              //DMA通道1优先级为低HAL_DMA_DeInit(&hdma_usart2_tx);HAL_DMA_Init(&hdma_usart2_tx);
///配置串口DMA发送结束//	HAL_DMA_ChannelMap(&hdma_usart2_tx,DMA_CHANNEL_MAP_USART2_TX);//配置"SYSCFG配置寄存器3(SYSCFG_CFGR3)"//DMA1_MAP[4:0]=7,将DMA通道1映射到USART2_TX
}void Usart2Receive_DMA1_CH2_config(void)
{DMA_HandleTypeDef hdma_usart2_rx;__HAL_RCC_SYSCFG_CLK_ENABLE();//使能RCC外设时钟__HAL_RCC_DMA_CLK_ENABLE();   //使能DMA时钟hdma_usart2_rx.DmaBaseAddress = DMA1;                //选择DMA1传输hdma_usart2_rx.Instance = DMA1_Channel2;             //DMA1通道2
//	HAL_DMA_ChannelMap(&hdma_usart2_rx,DMA_CHANNEL_MAP_USART2_RX);//配置"SYSCFG配置寄存器3(SYSCFG_CFGR3)"//DMA2_MAP[4:0]=8,将DMA通道2映射到USART2_RX///配置串口DMA接收开始hdma_usart2_rx.DmaBaseAddress = DMA1;                //选择DMA1传输hdma_usart2_rx.Instance = DMA1_Channel2;             //DMA1通道2hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;//DMA传输方向:从外设到内存hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;    //不使能外设地址增量hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;        //使能内存地址增量hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; //外设数据宽度为8位hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;    //存储器数据宽度为8位hdma_usart2_rx.Init.Mode = DMA_NORMAL;                         //DMA普通模式hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;               //DMA通道2优先级为低HAL_DMA_DeInit(&hdma_usart2_rx);HAL_DMA_Init(&hdma_usart2_rx);
///配置串口DMA接收结束
//	HAL_DMA_ChannelMap(&hdma_usart2_rx,DMA_CHANNEL_MAP_USART2_RX);//配置"SYSCFG配置寄存器3(SYSCFG_CFGR3)"//DMA2_MAP[4:0]=8,将DMA通道2映射到USART2_RX__HAL_DMA_DISABLE(&hdma_usart2_rx);//将"DMA通道x配置寄存器DMA_CCRx"中的EN=0,DMA通道x不使能
//	My_DMA_SetConfig(&hdma_usart2_rx,(uint32_t)&USART2->DR,(uint32_t)&USART2_RX_Buffer,USART2_RX_Buffer_Size);My_DMA1_SetConfig(DMA1_Channel2,(uint32_t)&USART2->DR,(uint32_t)&USART2_RX_Buffer,USART2_RX_Buffer_Size,0);__HAL_DMA_ENABLE(&hdma_usart2_rx);//将"DMA通道x配置寄存器DMA_CCRx"中的EN=1,DMA通道x使能_HAL_UART_CLEAR_FLAG(USART2,UART_FLAG_RXNE);SET_BIT(USART2->CR3, USART_CR3_DMAR);//将"串口控制寄存器3(USART_CR3)中的DMAR位"置1,接收时使能DMAUSART2_RX_Buffer_StartIndex=USART2_RX_Buffer_Size-_HAL_DMA_Transfer_Number_Get(DMA1_Channel2);//读DMA1通道2剩余空间USART2_RX_Buffer_EndIndex=USART2_RX_Buffer_StartIndex;
}//函数功能:将USART2_TX_Buffer[]中的字符串通过"DMA通道1"写入串口发送寄存器
void Usart2Send1(void)
{DMA_HandleTypeDef hdma_usart2_tx;///配置串口DMA发送开始hdma_usart2_tx.DmaBaseAddress = DMA1;                //选择DMA1传输hdma_usart2_tx.Instance = DMA1_Channel1;             //DMA1通道1hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;//DMA传输方向:从内存到外设__HAL_DMA_DISABLE(&hdma_usart2_tx);My_DMA_SetConfig(&hdma_usart2_tx, (uint32_t)&USART2_TX_Buffer,(uint32_t)&USART2->DR,strlen( (char*)USART2_TX_Buffer ));__HAL_DMA_ENABLE(&hdma_usart2_tx);//将"DMA通道x配置寄存器DMA_CCRx"中的EN=1,通道x使能_HAL_UART_CLEAR_FLAG(USART2,UART_FLAG_TC);SET_BIT(USART2->CR3, USART_CR3_DMAT);//将"串口控制寄存器3(USART_CR3)中的DMAT位"置1,发送时使能DMAwhile( __HAL_DMA_GET_FLAG(&hdma_usart2_tx,DMA_FLAG_TC1) == RESET){//等待"DMA通道1"传输完成}__HAL_DMA_CLEAR_FLAG(DMA1_Channel1,DMA_FLAG_TC1);//将"DMA中断标志位清除寄存器DMA_IFCR"中的CTCIF1=0,通道1传输完成标志清零
}//函数功能:将USART2_TX_Buffer[]中的字符串通过"DMA通道1"写入串口发送寄存器
void Usart2Send(void)
{_HAL_DMA_DISABLE(DMA1_Channel1);//将"DMA通道1配置寄存器DMA_CCR1"中EN=0,DMA通道1不使能My_DMA1_SetConfig(DMA1_Channel1,(uint32_t)&USART2_TX_Buffer,(uint32_t)&USART2->DR,strlen( (char*)USART2_TX_Buffer),1);_HAL_DMA_ENABLE(DMA1_Channel1);//将"DMA通道1配置寄存器DMA_CCR1"中的EN=1,通道1使能_HAL_UART_CLEAR_FLAG(USART2,UART_FLAG_TC);SET_BIT(USART2->CR3, USART_CR3_DMAT);//将"串口控制寄存器3(USART_CR3)中的DMAT位"置1,发送时使能DMAwhile( __HAL_DMA_GET_FLAG(DMA1,DMA_FLAG_TC1) == RESET){//等待"DMA通道1"传输完成}__HAL_DMA_CLEAR_FLAG(DMA1_Channel1,DMA_FLAG_TC1);//将"DMA中断标志位清除寄存器DMA_IFCR"中的CTCIF1=0,通道1传输完成标志清零
}//函数功能:
//将"串口接收寄存器"通过"DMA1通道2"写入USART2_RX_Buffer[]
//接收完成后,将接收到的有效数据拷贝到USART2_RX1_Buffer[]中
void Usart2Receive(void)
{uint8_t i;uint8_t len_New;uint8_t len_Old;len_New=_HAL_DMA_Transfer_Number_Get(DMA1_Channel2);//读"DMA1通道2"剩余空间len_Old=len_New;USART2_RX_Buffer_EndIndex=USART2_RX_Buffer_Size-len_Old;if(USART2_RX_Buffer_StartIndex!=USART2_RX_Buffer_EndIndex)//发现新数据{for(i=0;i<10;i++)//查询是否接收完成{delay_us(100);len_New=_HAL_DMA_Transfer_Number_Get(DMA1_Channel2);//读DMA1通道2剩余空间if(len_New!=len_Old)//接收没有完成{len_Old=len_New;i=0;}else//接收超时,表示DMA接收完成{USART2_RX_Buffer_EndIndex=USART2_RX_Buffer_Size-len_Old;//记录尾部for(i=0;USART2_RX_Buffer_StartIndex!=USART2_RX_Buffer_EndIndex;){//将接收到的数据保存到USART2_RX1_Buffer[]中;USART2_RX1_Buffer[i]=USART2_RX_Buffer[USART2_RX_Buffer_StartIndex];i++;USART2_RX_Buffer_StartIndex++;}USART2_RX1_Buffer[i]='\0';i=11;//接收完成}}strcpy((char*)USART2_TX_Buffer,(char*)USART2_RX1_Buffer);Usart2Send();//将接收到的数据回传Usart2Receive_DMA1_CH2_config();//重新初始化串口到DMA接收}
}
#ifndef __USART2_H
#define __USART2_H#include "py32f0xx_hal.h"#define USART2Type  1  //#define _HAL_UART_SendByte(__INSTANCE__, __DATA__) (__INSTANCE__)->DR = ( (__DATA__) & (uint16_t)0x01FF );
//将(__DATA__)写入串口发送缓冲区#define _HAL_UART_ReceiveByte(__INSTANCE__) ( (uint16_t)( (__INSTANCE__)->DR & (uint16_t)0x01FF) )
//读串口接收缓冲区#define _HAL_UART_GET_FLAG(__INSTANCE__, __FLAG__) ( ( (__INSTANCE__)->SR & (__FLAG__) ) == (__FLAG__) )
//读串口中断标志位
//(__FLAG__)=UART_IT_RXNE,读"串口接收寄存器为非空时产生的中断标志位"
//(__FLAG__)=UART_IT_PE,读"串口奇偶校验错误产生的中断标志位"
//(__FLAG__)=UART_IT_ERR,读"帧错误、噪音错误和溢出错误时产生的中断标志位"
//(__FLAG__)=UART_IT_TXE时,读"串口发送寄存器为空产生的中断标志位"
//(__FLAG__)=UART_IT_TC时,读"发送完成产生的中断标志位"#define _HAL_UART_CLEAR_FLAG(__INSTANCE__, __FLAG__) ( (__INSTANCE__)->SR = ~(__FLAG__) )
//清除串口中断标志位
//(__FLAG__)=UART_IT_RXNE,清除"串口接收寄存器为非空时产生的中断标志位"
//(__FLAG__)=UART_IT_PE,清除"串口奇偶校验错误产生的中断标志位"
//(__FLAG__)=UART_IT_ERR,清除"帧错误、噪音错误和溢出错误时产生的中断标志位"
//(__FLAG__)=UART_IT_TXE时,清除"串口发送寄存器为空产生的中断标志位"
//(__FLAG__)=UART_IT_TC时,清除"发送完成产生的中断标志位"#define _HAL_UART_ENABLE_IT(__INSTANCE__, __INTERRUPT__)   ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__INSTANCE__)->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \(((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__INSTANCE__)->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \((__INSTANCE__)->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))
//设置串口中断使能位
//(__INTERRUPT__)=UART_IT_RXNE,设置"串口接收寄存器为非空"时,使其产生中断
//(__INTERRUPT__)=UART_IT_PE,设置"串口奇偶校验错误"时,使其产生中断
//(__INTERRUPT__)=UART_IT_ERR,设置"帧错误、噪音错误和溢出错误"时,使其产生中断
//(__INTERRUPT__)=UART_IT_TXE时,设置"串口发送寄存器为空"时,使其产生中断
//(__INTERRUPT__)=UART_IT_TC时,设置"串口发送寄存器发送完成"时,使其产生中断#define _HAL_UART_DISABLE_IT(__INSTANCE__, __INTERRUPT__)  ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__INSTANCE__)->CR1 &= ~((__INTERRUPT__) & UART_IT_MASK)): \(((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__INSTANCE__)->CR2 &= ~((__INTERRUPT__) & UART_IT_MASK)): \((__INSTANCE__)->CR3 &= ~ ((__INTERRUPT__) & UART_IT_MASK)))
//设置串口中断不使能
//(__INTERRUPT__)=UART_IT_RXNE,设置"串口接收寄存器为非空"时,不使其产生中断
//(__INTERRUPT__)=UART_IT_PE,设置"串口奇偶校验错误"时,不使其产生中断
//(__INTERRUPT__)=UART_IT_ERR,设置"帧错误、噪音错误和溢出错误"时,不使其产生中断
//(__INTERRUPT__)=UART_IT_TXE时,设置"串口发送寄存器为空"时,不使其产生中断
//(__INTERRUPT__)=UART_IT_TC时,设置"串口发送寄存器发送完成"时,不使其产生中断#define USART2_TX_Buffer_Size 		      15
extern uint8_t USART2_TX_Buffer[USART2_TX_Buffer_Size];
extern uint8_t USART2_TX_Buffer_Send_Index;//USART2_TX_Buffer[]的发送索引值;
extern uint8_t USART2_TX_Buffer_Load_Index;//USART2_TX_Buffer[]的装载索引值
extern uint8_t USART2_TX_Completed_Flag;
extern uint8_t USART2_TX_Overtime_Conter;//USART2发送超时计数器#define USART2_RX_Buffer_Size 		      125
extern  uint8_t USART2_RX_Buffer[USART2_RX_Buffer_Size]; //USART2接收缓冲区数组
extern uint8_t USART1_RX_Buffer_StartIndex;//USART1_RX_Buffer[]的装载索引值
extern uint8_t USART1_RX_Buffer_EndIndex;//USART1_RX_Buffer[]的装载索引值#define USART2_RX1_Buffer_Size 		      125
extern uint8_t USART2_RX1_Buffer[USART2_RX1_Buffer_Size]; //USART2接收缓冲区数组extern void USART2_Init(uint32_t baudrate);
extern void Usart2Send(void);
extern void Usart2Receive(void);
#endif /* __USART2_H */
#include "My_DMA.h"void My_DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
void My_DMA1_SetConfig(DMA_Channel_TypeDef *instance, uint32_t srcAddress, uint32_t dstAddress, uint32_t dataLength,uint8_t direction);#define _HAL_DMA_CLEAR_FLAG(__INSTANCE__, __FLAG__) ( (__INSTANCE__)->IFCR |= (__FLAG__) )
//清除串口中断标志位
//(__FLAG__)=0x01,CGIF1=1,清除"通道1全局中断标志"
//(__FLAG__)=0x10,CGIF2=1,清除"通道2全局中断标志"
//(__FLAG__)=0x100,CGIF3=1,清除"通道3全局中断标志"//SrcAddress:源数据地址
//DstAddress:目的数据地址
//DataLength:传输数据长度
void My_DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{/* Clear all flags */if(hdma->Instance==DMA1_Channel1) hdma->ChannelIndex=0x01;if(hdma->Instance==DMA1_Channel2) hdma->ChannelIndex=0x04;if(hdma->Instance==DMA1_Channel3) hdma->ChannelIndex=0x08;hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);//将"DMA中断标志位清除寄存器DMA_IFCR"中的CGIFx设置为1,将DMA通道x全局中断标志清零/* Configure DMA Channel data length */hdma->Instance->CNDTR = DataLength;//传输数据长度/* Memory to Peripheral */if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)//从内存向外设传输{/* Configure DMA Channel destination address */hdma->Instance->CPAR = DstAddress;//目的数据地址/* Configure DMA Channel source address */hdma->Instance->CMAR = SrcAddress;//源数据地址}/* Peripheral to Memory */else//从外设向内存传输{/* Configure DMA Channel source address */hdma->Instance->CPAR = SrcAddress;//源数据地址/* Configure DMA Channel destination address */hdma->Instance->CMAR = DstAddress;//目的数据地址}
}//srcAddress:源数据地址
//dstAddress:目的数据地址
//dataLength:传输数据长度
//direction>0,从内存向外设传输;direction=0,从外设向内存传输
void My_DMA1_SetConfig(DMA_Channel_TypeDef *instance, uint32_t srcAddress, uint32_t dstAddress, uint32_t dataLength,uint8_t direction)
{uint8_t ChannelIndex;/* Clear all flags */if(instance==DMA1_Channel1) ChannelIndex=0x01;if(instance==DMA1_Channel2) ChannelIndex=0x04;if(instance==DMA1_Channel3) ChannelIndex=0x08;DMA1->IFCR = (DMA_ISR_GIF1 << ChannelIndex);//将"DMA中断标志位清除寄存器DMA_IFCR"中的CGIFx设置为1,将DMA通道x全局中断标志清零/* Configure DMA Channel data length */instance->CNDTR = dataLength;//传输数据长度/* Memory to Peripheral */if( direction )//从内存向外设传输{/* Configure DMA Channel destination address */instance->CPAR = dstAddress;//目的数据地址/* Configure DMA Channel source address */instance->CMAR = srcAddress;//源数据地址}/* Peripheral to Memory */else//从外设向内存传输{/* Configure DMA Channel source address */instance->CPAR = srcAddress;//源数据地址/* Configure DMA Channel destination address */instance->CMAR = dstAddress;//目的数据地址}
}
#ifndef __My_DMA_H
#define __My_DMA_H#include "py32f0xx_hal.h"#define _HAL_DMA_ENABLE(__INSTANCE__)        ((__INSTANCE__)->CCR |= DMA_CCR_EN)
//将"DMA通道x配置寄存器DMA_CCRx"中EN=1,DMA通道x使能#define _HAL_DMA_DISABLE(__INSTANCE__)       ((__INSTANCE__)->CCR &= ~DMA_CCR_EN)
//将"DMA通道x配置寄存器DMA_CCRx"中EN=0,DMA通道x不使能#define _HAL_DMA_Transfer_Number_Get(__INSTANCE__)       ( (__INSTANCE__)->CNDTR )
//读DMA1通道x剩余空间extern void My_DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
extern void My_DMA1_SetConfig(DMA_Channel_TypeDef *instance, uint32_t srcAddress, uint32_t dstAddress, uint32_t dataLength,uint8_t direction);
#endif /* __My_DMA_H */
#include "py32f0xx_hal.h"
#include "SystemClock.h"
#include "delay.h"
#include "LED.h"
#include "USART2.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()
#include "SystemClock.h"const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";int main(void)
{HSE_Config();
//	HAL_Init();//systick初始化delay_init();HAL_Delay(1000);USART2_Init(115200);
//PA0是为USART2_TX,PA1是USART2_RX
//中断优先级为0x01
//波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
//	printf("%s",CPU_Reset_REG);strcpy((char*)USART2_TX_Buffer,CPU_Reset_REG);Usart2Send();TIM1_LED_Init();TIM3_LED_Init();TIM_LED_Init();while (1){delay_ms(100);Usart2Receive();
//	  strcpy((char*)USART2_TX_Buffer,"A234567890\r\n");
//	  Usart2Send();}
}

三、测试结果

 四、不用HAL库DMA函数的目的

因为HAL库的DMA传输函数,需要将UART_HandleTypeDef,DMA_HandleTypeDef结构型数据申请为全局变量,才可以使用,太浪费内存了。
UART_HandleTypeDef UART_HandleStructureure;
DMA_HandleTypeDef hdma_usart2_tx;
DMA_HandleTypeDef hdma_usart2_rx;

实在太浪费了。
贴出官方的测试代码,以示如下:

#include "USART2.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()//PA0 ------> USART2_TX
//PA1 ------> USART2_RX
UART_HandleTypeDef UART_HandleStructureure;
DMA_HandleTypeDef hdma_usart2_tx;
DMA_HandleTypeDef hdma_usart2_rx;uint8_t aTxBuffer[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
uint8_t aRxBuffer[12] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};void USART2_Init(uint32_t baudrate);
void USART2_Work(void);void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{GPIO_InitTypeDef  GPIO_InitStructureure;if(huart->Instance==USART2){__HAL_RCC_USART2_CLK_ENABLE();//使能USART2外设时钟__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟__HAL_RCC_SYSCFG_CLK_ENABLE();//使能RCC外设时钟__HAL_RCC_DMA_CLK_ENABLE();   //使能DMA时钟//串口引脚映射开始/GPIO_InitStructureure.Pin = GPIO_PIN_0;     //选择第0脚,PA0是为USART2_TXGPIO_InitStructureure.Mode = GPIO_MODE_AF_PP;            //复用功能推挽模式GPIO_InitStructureure.Pull = GPIO_PULLUP;                //引脚上拉被激活GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速GPIO_InitStructureure.Alternate = GPIO_AF9_USART2;       //将引脚复用为USART2HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);//根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器//将PA0初始化为USART2_TXGPIO_InitStructureure.Pin = GPIO_PIN_1;     //选择第1脚,PA1是USART2_RXGPIO_InitStructureure.Mode = GPIO_MODE_AF_PP;            //复用功能推挽模式GPIO_InitStructureure.Pull = GPIO_PULLUP;                //引脚上拉被激活GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速GPIO_InitStructureure.Alternate = GPIO_AF9_USART2;       //将引脚复用为USART2HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);//根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器//将PA1初始化为USART2_RX
//串口引脚映射结束/HAL_NVIC_SetPriority(USART2_IRQn, 0, 1);//设置串口2中断优先级为0x00,1无意义HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 1);//设置DMA1通道1中断优先级为0x00,1无意义HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 1, 0);//设置DMA1通道2和通道3中断优先级为0x01,0无意义}
}//函数功能:
//PA0是为USART2_TX,PA1是USART2_RX
//中断优先级为0x01
//波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
void USART2_Init(uint32_t baudrate)
{UART_HandleStructureure.Instance          = USART2;              //接口为USART2UART_HandleStructureure.Init.BaudRate     = baudrate;            //波特率为115200bpsUART_HandleStructureure.Init.WordLength   = UART_WORDLENGTH_8B;  //串口字长度为8UART_HandleStructureure.Init.StopBits     = UART_STOPBITS_1;     //串口停止位为1位UART_HandleStructureure.Init.Parity       = UART_PARITY_NONE;    //串口无需奇偶校验UART_HandleStructureure.Init.HwFlowCtl    = UART_HWCONTROL_NONE; //串口无硬件流程控制UART_HandleStructureure.Init.Mode         = UART_MODE_TX_RX;     //串口工作模式为发送和接收模式UART_HandleStructureure.AdvancedInit.AdvFeatureInit=UART_ADVFEATURE_NO_INIT;//不使用自动波特率
//	UART_HandleStructureure.AdvancedInit.AdvFeatureInit=UART_ADVFEATURE_AUTOBAUDRATE_INIT;//使用自动波特率配置
//	UART_HandleStructureure.AdvancedInit.AutoBaudRateEnable=UART_ADVFEATURE_AUTOBAUDRATE_ENABLE;//自动波特率使能
//	UART_HandleStructureure.AdvancedInit.AutoBaudRateMode=UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT;//自动波特率模式HAL_UART_Init(&UART_HandleStructureure);//根据UART_HandleStructureure型结构初始化USART2//	HAL_SYSCFG_DMA_Req(0x0807);//配置"SYSCFG配置寄存器3(SYSCFG_CFGR3)"//DMA1_MAP[4:0]=7,将DMA通道1映射到USART2_TX//DMA2_MAP[4:0]=8,将DMA通道2映射到USART2_RXhdma_usart2_tx.DmaBaseAddress = DMA1;                //选择DMA1传输hdma_usart2_tx.Instance = DMA1_Channel1;             //DMA1通道1hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;//DMA传输方向:从内存到外设hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;    //不使能外设地址增量hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;        //使能内存地址增量hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;//外设数据宽度为8位hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;   //存储器数据宽度为8位hdma_usart2_tx.Init.Mode = DMA_NORMAL;                        //DMA普通模式hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;              //DMA通道1优先级为低HAL_DMA_Init(&hdma_usart2_tx);__HAL_LINKDMA(&UART_HandleStructureure, hdmatx, hdma_usart2_tx);//这里必须要连接DMA句柄//令UART_HandleStructureure.hdmatx=&hdma_usart2_tx;//记录//令hdma_usart2_tx.Parent=&UART_HandleStructureure;//记录hdma_usart2_rx.DmaBaseAddress = DMA1;                //选择DMA1传输hdma_usart2_rx.Instance = DMA1_Channel2;             //DMA1通道2hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;//DMA传输方向:从外设到内存hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;    //不使能外设地址增量hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;        //使能内存地址增量hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; //外设数据宽度为8位hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;    //存储器数据宽度为8位hdma_usart2_rx.Init.Mode = DMA_NORMAL;                         //DMA普通模式hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;               //DMA通道2优先级为低HAL_DMA_Init(&hdma_usart2_rx);__HAL_LINKDMA(&UART_HandleStructureure, hdmarx, hdma_usart2_rx);//连接DMA句柄//令UART_HandleStructureure.hdmarx=&hdma_usart2_rx;//记录//令hdma_usart2_rx.Parent=&UART_HandleStructureure;//记录
HAL_DMA_ChannelMap(&hdma_usart2_tx,DMA_CHANNEL_MAP_USART2_TX);
HAL_DMA_ChannelMap(&hdma_usart2_rx,DMA_CHANNEL_MAP_USART2_RX);//	HAL_SYSCFG_DMA_Req(0x0807);//配置"SYSCFG配置寄存器3(SYSCFG_CFGR3)"//DMA1_MAP[4:0]=7,将DMA通道1映射到USART2_TX//DMA2_MAP[4:0]=8,将DMA通道2映射到USART2_RXHAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);HAL_NVIC_EnableIRQ(USART2_IRQn);//使能串口2中断//USART2_IRQn表示中断源为串口2
}//重定义fputc函数
//函数功能:发送ch的值给USART2串口
int fputc(int ch, FILE *f)
{_HAL_UART_SendByte(USART2, (unsigned char) ch);while( _HAL_UART_GET_FLAG(USART2,USART_SR_TC)!= SET); //等待发送完成标志位被置1	return ch;
}//函数功能:串口2发送一个字节
void USART2_SendByte(  unsigned char ch )
{_HAL_UART_SendByte(USART2, (unsigned char) ch);while( _HAL_UART_GET_FLAG(USART2,USART_SR_TC)!= SET); //等待发送完成标志位被置1
}void USART2_Work(void)
{/* 通过DMA方式接收数据 */if (HAL_UART_Receive_DMA(&UART_HandleStructureure, (uint8_t *)aRxBuffer, 12) != HAL_OK){}/* 等待接收数据完成 */while(HAL_UART_GetState(&UART_HandleStructureure) != HAL_UART_STATE_READY){}/* 通过DMA方式发送数据 */if (HAL_UART_Transmit_DMA(&UART_HandleStructureure, (uint8_t *)aRxBuffer, 12) != HAL_OK){}/* 等待发送数据完成 */while(HAL_UART_GetState(&UART_HandleStructureure) != HAL_UART_STATE_READY){}
}//DMA通道1负责串口发送
void DMA1_Channel1_IRQHandler(void)
{HAL_DMA_IRQHandler(&hdma_usart2_tx);
//若为"DMA通道x半传输中断",则清除“DMA通道x半传输中断”标志位
//若为“DMA通道x传输完成中断”,则清除“DMA通道x传输完成中断”标志位
//若为"DMA通道x传输错误中断",则不使能"DMA通道x传输完成中断"、"DMA通道x半传输中断"和"通道x传输错误中断",清除通道x全局中断标志
//  HAL_DMA_IRQHandler(UART_HandleStructureure.hdmatx);
}//DMA通道2负责串口接收
void DMA1_Channel2_3_IRQHandler(void)
{HAL_DMA_IRQHandler(&hdma_usart2_rx);
//若为"DMA通道x半传输中断",则清除“DMA通道x半传输中断”标志位
//若为“DMA通道x传输完成中断”,则清除“DMA通道x传输完成中断”标志位
//若为"DMA通道x传输错误中断",则不使能"DMA通道x传输完成中断"、"DMA通道x半传输中断"和"通道x传输错误中断",清除通道x全局中断标志
//  HAL_DMA_IRQHandler(UART_HandleStructureure.hdmarx);
}void USART2_IRQHandler(void)
{HAL_UART_IRQHandler(&UART_HandleStructureure);
}

耗内存,占用FLASH较小。FLASH那么大,节省没啥用。思绪再三,还是修改掉。

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

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

相关文章

Vue页面快速使用阿里巴巴矢量图标库

前面我已经写个一篇文章 阿里巴巴矢量图标如何使用_turbo夏日漱石的博客-CSDN博客 这篇文章非常详细地讲解了在html页面中如何使用阿里巴巴矢量图标库 下面我们讲解在vue页面中引入阿里巴巴矢量图标库icon的几种方法 目录 一、引入在线链接 1、 第九步链接引入在vue中应该是在…

安卓备份基带分区 备份字库 步骤解析 以免误檫除分区或者“格机” 后悔莫及

玩机搞机---安卓机型mtk和高通芯片查看分区 导出分区 备份分区的一些工具分析 修复基带 改串码 基带qcn 改相关参数 格机危害 手机基带的重要性前面几期博文我都有相关的说明。他区别于别的分区。而且目前手机的安全性越来越高。基带分区基本都是专机专用。而不像早期机型一…

【AI语言大模型】文心一言功能使用介绍

一、前言 文心一言是一个知识增强的大语言模型&#xff0c;基于飞桨深度学习平台和文心知识增强大模型&#xff0c;持续从海量数据和大规模知识中融合学习具备知识增强、检索增强和对话增强的技术特色。 最近收到百度旗下产品【文心一言】的产品&#xff0c;抱着试一试的心态体…

java服务内存说明及配置详解

java进程内存 JVM内存分布图: 【java进程内存】【堆外内存】 【jvm堆内存】 【堆外内存】 【Metaspace】 【Direct Memory】【JNI Memory】【code_cache】 … 堆外内存泄漏的排查在于【本地内存&#xff08;Native Memory&#xff09;】【Direct Memory】【JNI Memory】 一般…

期刊分类一览

分区情况 jcr分区 中科院分区 EI 理工科 一般是SCI的都是EI 国内的分区

网络安全深入学习第三课——热门框架漏洞(RCE—Struts2远程代码执行)

文章目录 一、Struts2框架介绍二、Struts2远程代码执行漏洞三、Struts2执行代码的原理四、Struts2框架特征五、漏洞手工POC六、漏洞工具复现 一、Struts2框架介绍 ------ Struts2是apache项目下的一个web 框架&#xff0c;普遍应用于阿里巴巴、京东等互联网、政府、企业门户网…

2023-09-20 Android CheckBox 让文字显示在选择框的左边

一、CheckBox 让文字在选择框的左边 &#xff0c;在布局文件里面添加下面一行就可以。 android:layoutDirection"rtl" 即可实现 android:paddingStart"10dp" 设置框文间的间距 二、使用的是left to right <attr name"layoutDirection">&…

一文掌握CodiMD安装与使用

简介&#xff1a;CodiMD 是一个基于 Markdown 语言的实时协作文档编辑器&#xff0c;它允许多个用户在同一个文档上进行实时编辑。CodiMD 的前身是 HackMD&#xff0c;但为了满足更开放的开源社区需求&#xff0c;CodiMD 作为其社区版本独立出来。 优势&#xff1a; 1. 开源且…

【Godot】解决游戏中的孤立/孤儿节点及分析器性能问题的分析处理

Godot 4.1 因为我在游戏中发现&#xff0c;越运行游戏变得越来越卡&#xff0c;当你使用 Node 节点中的 print_orphan_nodes() 方法打印信息的时候&#xff0c;会出现如下的孤儿节点信息 孤儿节点信息是以 节点实例ID - Stray Node: 节点名称(Type: 节点类型) 作为格式输出&a…

关于JPA +SpringBoot 遇到的一些问题及解决方法

关于JPA SpringBoot 遇到的一些问题及解决方法&#xff08;可能会有你正在遇到的&#xff09; 一、JpaRepository相关 1.1 org.springframework.dao.InvalidDataAccessResourceUsageException: Named parameter not bound : id; nested exception is org.hibernate.QueryEx…

【从0学习Solidity】33. 发送空投

【从0学习Solidity】 33. 发送空投 博主简介&#xff1a;不写代码没饭吃&#xff0c;一名全栈领域的创作者&#xff0c;专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构&#xff0c;分享一些项目实战经验以及前沿技术的见解。关注我们的主页&#xff0c;探索全栈…

day03_基础语法

今日内容 零、复习昨日 一、Idea安装&#xff0c;配置 二、Idea使用 三、输出语句 四、变量 五、数据类型 附录: 单词 零、 复习昨日 1 装软件(typora,思维导图) 2 gpt(学会让他帮你解决问题) 3 java发展(常识) 4 HelloWorld程序 5 编码规范 6 安装jdk,配置环境变量 电脑常识 任…

vuex如何安装、报错、安装版本注意事项

npm i vuex报错&#xff0c;为什么呢&#xff1f; 在2022.2.7&#xff0c;Vue3就变成了默认版本&#xff0c; Vue2中&#xff0c;必须要用Vuex的3版本 Vue3中&#xff0c;必须要用Vuex的4版本&#xff0c;否则会报错 npm i vuex 安装的就是4版本 如果我们需要安装3版本&…

LaTex打出上大下小的公式

想要在latex中打出如下word公式 首先使用 \atop符号 使用如下语句 d_{H(A,B)} max\{{sup\, inf \atop {a \in A\,b \in B}}\,d(a,b), {sup\, inf\,\atop {b\in B\,a\in\,A}}d(b,a)\}. ![在这里插入图片描述](https://img-blog.csdnimg.cn/0c842594716a4693b1124523d53bfcad…

Unity实现角色受到攻击后屏幕抖动的效果

文章目录 实现效果摄像机抖动脚本 玩家受伤其他文章 实现效果 首先看一下实现效果。 摄像机 我们要使用屏幕抖动&#xff0c;使用的是CinemachineVirtualCamera这个组件&#xff0c;这个组件需要在包管理器中进行导入。 导入这个组件之后&#xff0c;创建一个Chinemachine-…

【Spring】Spring Security学习笔记

基本概念 概念定义认证判断一个用户身份是否合法的过程(登录过程)会话为了避免用户的每次操作都进行认证, 将用户的信息保存在会话中. 常见的会话有基于session的模式和基于token的模式授权校验用户是否有权限访问某个资源 认证是为了验证用户的身份; 授权是为了验证用户是否有…

大范围XSS扫描工具:XSS-Freak,BurpSuite随机用户代理,Hades 静态代码审核系统

大范围XSS扫描工具&#xff1a;XSS-Freak&#xff0c;BurpSuite随机用户代理&#xff0c;Hades 静态代码审核系统。 #################### 免责声明&#xff1a;工具本身并无好坏&#xff0c;希望大家以遵守《网络安全法》相关法律为前提来使用该工具&#xff0c;支持研究学习…

【新版】系统架构设计师 - 案例分析 - 架构设计<Web架构>

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 案例分析 - 架构设计&#xff1c;Web架构&#xff1e;Web架构知识点单台机器 到 数据库与Web服务器分离应用服务器集群负载均衡负载均衡技术静态与动态算法Session共享机制有状态与无状态 持久化技…

postman几种常见的请求方式

1、get请求直接拼URL形式 对于http接口&#xff0c;有get和post两种请求方式&#xff0c;当接口说明中未明确post中入参必须是json串时&#xff0c;均可用url方式请求 参数既可以写到URL中&#xff0c;也可写到参数列表中&#xff0c;都一样&#xff0c;请求时候都是拼URL 2&am…

Vue Grid Layout -️ 适用Vue.js的栅格布局系统,在vue3+上使用

文章目录 1、官网简介2、在vue3中使用1)、需要导入vue3支持的版本插件2)、在mian.js里引入&#xff1a;3)、在组件中使用 3、layout布局的计算逻辑4、 gridLayout 的属性 该栅格系统目前对 vue2 的支持是最好的&#xff0c;vue3 是需要用插件支持的&#xff0c;会在小节详细讲解…