MM32F0020 UART1硬件自动波特率的使用
目录:
1.MM32F0020简介
2.UART自动波特率校准应用场景
3.MM32F0020 UART自动波特率校准原理简介
4.MM32F0020 UART1 NVIC硬件自动波特率配置以及初始化
5.编写MM32F0020 UART1发送数据函数
6.编写MM32F0020 UART1中断接收函数以及自动波特率校准的实现
7.编写MM32F0020 UART1处理中断接收数据函数
8.验证MM32F0020 UART1自动波特率校准功能
提要:
学习MM32F0020 UART自动波特率校准功能的使用。例如:上位机串口调试助手UART通信波特率为19200,往下位机UART1波特率为9600的MM32F0020 发送一帧数据:
0xF8 0x55 0x2 0x03 0x04 0x05 0x06 0x07;下位机通过UART内部硬件自动检测接收到数据帧的首字节的位宽的波特率时间来识别上位机的波特率,并重置下位机MCU的波特率
寄存器使得下位机MCU的波特率与上位机的通信波特率一致,从而实现数据帧的正常收发(注意:上位机与下位机的通信波特率不应相差太大,否则无法自动检测识别)。
本博客为原创文章,转载请注明出处!!!
内容:
1、MM32F0020简介:
(1)MM32F0020微控制器是基于Arm Cortex-M0内核,最高工作频率可达48MHz;
(2)供电电压支持:2.0V - 5.5V;
(3)多达32KB的Flash,2KB的SRAM;
(4)1个I2C;
(5)2个UART;
(6)1个12位的共8通道的ADC;
(7)1个I2C或I2S;
(8)1个16位高级定时,1个16位通用定时器,1个16位基本定时器;
(9)1个IWDG和一个WWDG看门狗。
2.UART自动波特率校准应用场景
嵌入式软件工程师在开发产品时,经常会用到MCU的UART串口模块做产品功能方面的调试或主从机通信,当产品的主从机通信波特率有偏差时,或经过TTL电平转换电路转换后波特率出现
偏差或产品的工作环境相对比较恶劣时也会出现UART的主从机通信波特率偏差,这时如果MCU的UART内部集成了自动波特率检测校准功能,就能通过自动波特率检测校准从而维持MCU的UART
主从机的正常通信功能。
3.MM32F0020 UART自动波特率校准原理简介
MM32F0020系列MCU的UART内部集成了硬件自动波特率检测电路,自动检测接收到数据帧的首字节的位宽波特率时间来识别通信方的波特率参数,并重置MCU的UART波特率寄存器,使得通信双方保存通信波特率一致。
4.MM32F0020 UART1 NVIC硬件自动波特率配置以及初始化
MM32F0020 UART1的GPIO初始化,根据MM32F0020的DS数据手册选择PA12:UART1_TX,PA3:UART1_RX做为UART1的发送和接收数据的引脚,具体配置步骤,及其初始化如下所示:
(1)使能GPIOA外设时钟;
(2)配置IO管脚GPIO_AFx复用为UART1功能;
(3)配置UARTx IO的管脚;
(4)配置GPIO的输出速度;
(5)配置IO管脚的工作模式;
(6)根据GPIOA配置的参数整体初始化GPIO各管脚的成员参数。
void Bsp_UART1_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//Enable GPIOA Clock
RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
//PA3 AF UART1_RX
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1);
//PA12 AF UART1_TX
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_1); //PA12:UART1_TX
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct); //PA3:UART1_RX
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
MM32F0020 UART1 NVIC硬件自动波特率配置以及初始化步骤如下所示:
(1)使能UART1外设时钟;
(2)调用之前配置的UART1GPIO初始化函数;
(3)配置UART1通信波特率为9600;
(4)配置UART1字长为8位;
(5)配置UART1收发数据为1位停止位;
(6)配置UART1收发数据为无奇偶校验位;
(7)配置UART1允许串口收发数据;
(8)根据以上配置参数初始化UART1结构体成员;
(9)配置UART1硬件自动波特率检测首字节的位宽(包含起始位宽)的长度和检测的边缘模式,可从UM手册UART_ABRCR自动波特率寄存器相关位查询到如下图1所示,本实例检测首字节的
边缘选择前一个边沿为下降沿(包含起始位)后一个边沿为上升沿,符合这个条件的字节为0xF8(b:1111 1000)等。

图1
(10)使能UART1接收数据中断、接收帧错误中断、自动波特率结束中断、自动波特率错误中断、空闲中断;
(11)配置UART1的NVIC中断优先级为0,并使能和初始化NVIC中断(优先级为0-3均可,参数越小优先级越高)。
MM32F0020 UART1 NVIC硬件自动波特率配置以及初始化代码如下所示:
void Bsp_UART1_NVIC_Init(u32 baudrate)
{
UART_InitTypeDef UART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//Enable UART1 Clock
RCC_APB1PeriphClockCmd(RCC_APB1ENR_UART1, ENABLE);
//UART1 GPIO Init
Bsp_UART1_GPIO_Init(); UART_StructInit(&UART_InitStruct);
//Baud rate
UART_InitStruct.BaudRate = baudrate;
//The word length is in 8-bit data format.
UART_InitStruct.WordLength = UART_WordLength_8b;
//One stop bit
UART_InitStruct.StopBits = UART_StopBits_1;
//No even check bit.
UART_InitStruct.Parity = UART_Parity_No;
//No hardware data flow control.
UART_InitStruct.HWFlowControl = UART_HWFlowControl_None;
UART_InitStruct.Mode = UART_Mode_Rx | UART_Mode_Tx;
UART_Init(UART1, &UART_InitStruct); //___ _______
// |_ _ _ _|1 x x x x| = Binary:xxxx 1000 Fall to Rise -> 1 start bit
//AutoBaudRate Mode Fall to Rise 4bit width,the first byte is 0xF8 use test
UART_AutoBaudRateSet(UART1, ABRMODE_FALLING_TO_RISINGEDGE4BIT, ENABLE); //接收数据中断、接收帧错误中断、自动波特率结束中断、自动波特率错误中断、空闲中断、
//Enable Receive data interrupt、Receive frame error interrupt、Automatic baud rate end interrupt、
//Automatic baud rate error interrupt、Idle interrupt
UART_ITConfig(UART1,UART_IT_RXIEN | UART_IER_RXFERR | UART_IER_ABREND_IEN | \
UART_IER_ABRERR_IEN | UART_IER_RXIDLE,ENABLE); //UART1 NVIC IRQ Channel
NVIC_InitStruct.NVIC_IRQChannel = UART1_IRQn;
//UART1 Priority
NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
//Enable UART1_IRQn
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(& NVIC_InitStruct);
//Enable UART1
UART_Cmd(UART1, ENABLE);
}
5.编写MM32F0020 UART1发送数据函数
(1)MM32F0020 UART1发送字节函数如下所示:
void Bsp_UART_SendByte(UART_TypeDef* uart,u8 data)
{
UART_SendData(uart,data);
while(!UART_GetFlagStatus(uart, UART_FLAG_TXEPT));
}
(2)MM32F0020 UART1发送多字节函数如下所示:
void Bsp_UART_SendBytes(UART_TypeDef* uart,u8 *buf, u16 len)
{
while(len--)
{
Bsp_UART_SendByte(uart,*buf++);
}
}
(3)MM32F0020 UART1发送ASCII字符串函数如下所示:
void Bsp_UART_SendString(UART_TypeDef* uart,char *str)
{
while(*str)
{
Bsp_UART_SendByte(uart,*str++);
}
}
6.编写MM32F0020 UART1中断接收函数以及自动波特率校准的实现
(1)定义与MM32F0020 UART1相关的变量,缓存,以及头文件变量、函数声明,代码如下所示:
//UART1 Receive count
u8 gUART1_Rx_Cnt = 0;
//UART1 Receive Buffer
u8 gUART1_Rx_Buf[UART1_REC_LEN];
//UART1 Receiving Flag
bool gUART1_Rx_Flag = false;
//Hardware automatic baud rate error flag
u8 Auto_BaudRate_FraErr_Flag = 0;
//注:上位机串口助手发送如下数据帧格式第1字节为波特率检测位宽,第2字节之后为可变字节方便观察收发数据帧
/***************************************************************************************************
--------------Falling edge to rising edge(including start bit)--------------------------------------
//The first byte is 0xF8 use test
//___ _______
// |_ _ _ _|1 x x x x| = Binary:xxxx 1000 Fall to Rise -> 1 start bit
//AutoBaudRate Mode Fall to Rise 4bit width,the first byte is 0xF8 use test
串口上位机发送数据格式:
0xF8 0x55 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x02 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x03 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
下位机分别给串口上位机原样回复收到的数据命令:
0xF8 0x55 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x02 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x03 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
***************************************************************************************************/ //UART1 Baud Rate
#define UART1_BAUDRATE (9600)
//UART1 maximum receiving length 200
#define UART1_REC_LEN (200) //UART1 Receive Buffer
extern u8 gUART1_Rx_Buf[UART1_REC_LEN];
//UART1 Receive count
extern u8 gUART1_Rx_Cnt;
//UART1 Receive Timing
//extern u8 UART1_Rx_TimeCnt;
//UART1 Receiving Flag
extern bool gUART1_Rx_Flag; //UART1 NVIC Init
void Bsp_UART1_NVIC_Init(u32 baudrate);
//Process UART1 Recv Task
void Bsp_UART1_Recv_Task(void);
//UART sends a byte data
void Bsp_UART_SendByte(UART_TypeDef* uart,u8 data);
//Send ASCII characters
void Bsp_UART_SendString(UART_TypeDef* uart,char *str);
//UART sends multi-byte data
void Bsp_UART_SendBytes(UART_TypeDef* uart,u8 *buf, u16 len);
(2)MM32F0020 UART1中断接收函数以及自动波特率校准代码如下所示:
void Bsp_UART1_NVIC_Init(u32 baudrate)
{
UART_InitTypeDef UART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//Enable UART1 Clock
RCC_APB1PeriphClockCmd(RCC_APB1ENR_UART1, ENABLE);
//UART1 GPIO Init
Bsp_UART1_GPIO_Init(); UART_StructInit(&UART_InitStruct);
//Baud rate
UART_InitStruct.BaudRate = baudrate;
//The word length is in 8-bit data format.
UART_InitStruct.WordLength = UART_WordLength_8b;
//One stop bit
UART_InitStruct.StopBits = UART_StopBits_1;
//No even check bit.
UART_InitStruct.Parity = UART_Parity_No;
//No hardware data flow control.
UART_InitStruct.HWFlowControl = UART_HWFlowControl_None;
UART_InitStruct.Mode = UART_Mode_Rx | UART_Mode_Tx;
UART_Init(UART1, &UART_InitStruct); //___ _______
// |_ _ _ _|1 x x x x| = Binary:xxxx 1000 Fall to Rise -> 1 start bit
//AutoBaudRate Mode Fall to Rise 4bit width,the first byte is 0xF8 use test
UART_AutoBaudRateSet(UART1, ABRMODE_FALLING_TO_RISINGEDGE4BIT, ENABLE); //接收数据中断、接收帧错误中断、自动波特率结束中断、自动波特率错误中断、空闲中断、
//Enable Receive data interrupt、Receive frame error interrupt、Automatic baud rate end interrupt、
//Automatic baud rate error interrupt、Idle interrupt
UART_ITConfig(UART1,UART_IT_RXIEN | UART_IER_RXFERR | UART_IER_ABREND_IEN | \
UART_IER_ABRERR_IEN | UART_IER_RXIDLE,ENABLE); //UART1 NVIC IRQ Channel
NVIC_InitStruct.NVIC_IRQChannel = UART1_IRQn;
//UART1 Priority
NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
//Enable UART1_IRQn
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(& NVIC_InitStruct);
//Enable UART1
UART_Cmd(UART1, ENABLE);
}
7.编写MM32F0020 UART1处理中断接收数据函数
MM32F0020 UART1处理中断接收数据函数代码如下所示:
void UART1_IRQHandler(void)
{
u8 Recbyte; //UART1 receive interrupt,receive valid data interrupt flag bit
if(UART_GetITStatus(UART1,UART_ISR_RX) != RESET)
{
//Clear UART1 receive interrupt flag
UART_ClearITPendingBit(UART1,UART_ICR_RX); //Read the data received by UART1
Recbyte = UART_ReceiveData(UART1); //UART1 receive data buffered
gUART1_Rx_Buf[gUART1_Rx_Cnt] = Recbyte; //Determine whether the received data of UART1 overflows
if(gUART1_Rx_Cnt < UART1_REC_LEN-1)
{
//UART1 Receive count
gUART1_Rx_Cnt++;
}
else
{
gUART1_Rx_Cnt = 0;
}
}
//Receive data frame error interrupt flag
if(UART_GetITStatus(UART1, UART_ISR_RXFERR_INTF) != RESET)
{
//Hardware automatic baud rate error flag
Auto_BaudRate_FraErr_Flag = 1;
UART_ClearITPendingBit(UART1,UART_ICR_RXFERRCLR);
}
//Idle interrupt hardware automatic baud rate self-calibration
if(UART_GetITStatus(UART1, UART_ISR_RXIDLE) != RESET)
{
UART_ClearITPendingBit(UART1,UART_ICR_RXIDLE); //Hardware automatic baud rate error flag
if(Auto_BaudRate_FraErr_Flag == 1)
{
Auto_BaudRate_FraErr_Flag = 0;
//-------------------------------------Check MM32F0140 UART_AutoBaudRateHard---------------------------------------------------------
//Configure MM32F013x hardware automatic baud rate self-calibration,Falling edge to rising edge(including start bit)
//___ _______
// |_ _ _ _|1 x x x x| = Binary:xxxx 1000 Fall to Rise -> 1 start bit
//AutoBaudRate Mode Fall to Rise 4bit width,the first byte is 0xF8 use test
UART_AutoBaudRateSet(UART1, ABRMODE_FALLING_TO_RISINGEDGE4BIT, ENABLE);
}
//UART1 Receiving Flag
gUART1_Rx_Flag = true;
}
//Automatic baud rate error clear bit
if(UART_GetITStatus(UART1, UART_ISR_ABRERR_INTF) != RESET)
{ //Auto baud rate error clear bit
UART_ClearITPendingBit(UART1,UART_ICR_ABRERRCLR);
}
//Automatic baud rate end interrupt clear bit
if(UART_GetITStatus(UART1, UART_ISR_ABREND_INTF) != RESET)
{
//Auto baud rate end clear bit
UART_ClearITPendingBit(UART1,UART_ICR_ABRENDCLR);
}
}
8.验证MM32F0020 UART1自动波特率校准功能
(1)在main函数初始化中调用UART1 NVIC硬件自动波特率检测初始化函数即Bsp_UART1_NVIC_Init(UART1_BAUDRATE);调用LED初始化函数用于指示收到数据后做状态翻转,在while(1)
主循环中循环检测MM32F0020 UART1处理中断接收数据函数,代码如下所示:
int main(void)
{
//LED Init
LED_Init();
//UART1 NVIC Init Baudrate 115200
Bsp_UART1_NVIC_Init(UART1_BAUDRATE); while(1)
{
//Test UART1 Recv IDLE
Bsp_UART1_Recv_Task();
}
}
(2)验证MM32F0020 UART1自动波特率校准功能
验证说明:
以上MCU的UART默认初始化的通信波特率为9600,通过改变上位机串口调试助手的通信波特率分别设置为:19200,38400,57600,115200并分别发送如下数据帧:
//注:上位机串口助手发送如下数据帧格式第1字节为波特率检测位宽,第2字节之后为可变字节方便观察收发数据帧
/***************************************************************************************************
--------------Falling edge to rising edge(including start bit)--------------------------------------
//The first byte is 0xF8 use test
//___ _______
// |_ _ _ _|1 x x x x| = Binary:xxxx 1000 Fall to Rise -> 1 start bit
//AutoBaudRate Mode Fall to Rise 4bit width,the first byte is 0xF8 use test
串口上位机发送数据格式:
0xF8 0x55 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x02 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x03 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
下位机分别给串口上位机原样回复收到的数据命令:
0xF8 0x55 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x02 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0xF8 0x03 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
***************************************************************************************************/
如果下位机MCU检测到数据帧的首字节前一个边沿为下降沿,后一个边沿为上升沿的4个位宽的数据,例如0xF8(含起始位b:1111 1000)芯片内部波特率自动检测电路识别首字节的波特率位宽,
并重置MCU的UART波特率寄存器,以达到MCU的通信波特率与上位机的通信分别一致,并原样回复收到的数据给上位机串口助手显示出来,测试结果如下图2,图3,图4,图5所示:

图1 如上串口助手显示MM32F0020的UART1已自动检测到19200波特率并打印出收到的正确数据

图2 如上串口助手显示MM32F0020的UART1已自动检测到38400波特率并打印出收到的正确数据

图3 如上串口助手显示MM32F0020的UART1已自动检测到57600波特率并打印出收到的正确数据

图4 如上串口助手显示MM32F0020的UART1已自动检测到115200波特率并打印出收到的正确数据
总结:
学习MM32F0020 UART自动波特率校准功能的使用。例如:上位机串口调试助手UART通信波特率为19200,往下位机UART1波特率为9600的MM32F0140 发送一帧数据:
0xF8 0x55 0x2 0x03 0x04 0x05 0x06 0x07;下位机通过UART内部硬件自动检测接收到数据帧的首字节的位宽波特率的时间来识别上位机的波特率,并重置下位机MCU的波特率
寄存器使得下位机MCU的波特率与上位机的通信波特率一致,从而实现数据帧的正常收发(注意:上位机与下位机的通信波特率不应相差太大,否则无法自动检测识别)。
注意事项:
(1)MM32F0020每个外设都有自己独立的时钟,需使能UART1 发送和接收引脚的GPIO时钟;
(2)使能UART1外设时钟;
(3)配置GPIOA的 PA3和PA12复用成UART1功能
(4)接收数据中断、接收帧错误中断、自动波特率结束中断、自动波特率错误中断、空闲中断;
(5)使能UART1自动波特率检测数据帧首字节的边缘模式前一个边沿为下降沿,后一个边沿为上升沿(具体组合可查看UM手册)并设置检测首字节的检测位宽(可设置1,2,4或8位宽)
本实例4位宽检测的首字节为0xF8;
(6)使能UART1 NVIC中断;
(7)验证MM32F0020 UART1自动波特率校准功能时记得切换上位机助手的通信波特率,记得设置首字节为0xF8(本实例);
(8)UART2操作方法与UART1的方法一样,可参考以上UART1把对应的UART1参数改成UART2,使能相应外设时钟编写对应中断函数即可。
MM32F0020 UART1硬件自动波特率的使用的更多相关文章
- MM32F0140 UART1硬件自动波特率校准功能的使用
目录: 1.MM32F0140简介 2.UART自动波特率校准应用场景 3.MM32F0140 UART自动波特率校准原理简介 4.MM32F0140 UART1 NVIC硬件自动波特率配置以及初始化 ...
- 痞子衡嵌入式:嵌入式里串口(UART)自动波特率识别程序设计与实现
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是嵌入式里串口(UART)自动波特率识别程序设计与实现. 串口(UART)是嵌入式里最基础最常用也最简单的一种通讯(数据传输)方式,可以说 ...
- MM32F0020 UART1中断接收
目录: 1.MM32F0020简介 2.初始化MM32F0020 UART1和NVIC中断 3.编写MM32F0020 UART1中断接收函数 4.编写MM32F0020 UART1发送字节和ASCI ...
- MM32F0020 UART1中断接收和UART1中断发送
目录: 1.MM32F0020简介 2.初始化MM32F0020 UART1和NVIC中断 3.编写MM32F0020 UART1使能中断发送函数 4.编写MM32F0020 UART1中断接收和中断 ...
- MM32F0020 UART1空闲中断接收
目录: 1.MM32F0020简介 2.初始化MM32F0020 UART1空闲中断和NVIC中断 3.编写MM32F0020 UART1中断接收和空闲中断函数 4.编写MM32F0020 UART1 ...
- 灵动微电子ARM Cortex M0 MM32F0010 UART1和UART2中断接收数据
灵动微电子ARM Cortex M0 MM32F0010 UART1和UART2中断接收数据 目录: 1.MM32F0010UART简介 2.MM32F0010UART特性 3.MM32F0010使用 ...
- Air722UG_模块硬件设计手册_V1.1
下载PDF版本: Air722UG_模块硬件设计手册_V1.1.pdf @ 目录 1. 绪论 2.综述 2.1 型号信息 2.2 主要性能 2.3 功能框图 3.应用接口 3.1 管脚描述 3.2 工 ...
- USART波特率 vs SPI速率--学习笔记
本篇文章将与大家探讨USART波特率 vs SPI速率.这里提出一个问题,为什么USART的波特率是内核时钟的1/8或者1/16,而SPI最快的频率可以是内核时钟的1/2. 请大家带着这个问题来阅读本 ...
- MM32F0140 UART1空闲中断接收
目录: 1.MM32F0140简介 2.初始化MM32F0140 UART1空闲中断和NVIC中断 3.编写MM32F0140 UART1中断接收和空闲中断函数 4.编写MM32F0140 UART1 ...
随机推荐
- vue--前端路由及vue-router两种模式
前言 路由这个概念最早在后端出现,随后前后端分离,直至当今的单页面应用,路由也在一直发生变化.本文来总结一下路由变化和vue-router中的路由模式区别相关知识点. 正文 1.什么是前端路由 (1) ...
- 微信小程序获取经纬度所在城市
小程序的wx.getLocation()获得是经纬度并不包含地名,所以要通过经纬度用相应的地图转换出地名(本文使用的是百度地图) // 获取坐标 onLoad: function (options) ...
- kubebuilder operator的运行逻辑
kubebuilder 的运行逻辑 概述 下面是kubebuilder 的架构图.可以看到最外层是通过名为Manager的组件驱动的,Manager中包含了多个组件,其中Cache中保存了gvk和in ...
- C# HttpRequest 请求
public static string Post(string Url, string postDataStr, string cookies) { HttpWebRequest request = ...
- C#控制台窗口禁用关闭按钮
1 public class Program 2 { 3 #region 禁用控制台黑窗口的关闭按钮 part1 4 5 private const int MF_BYCOMMAND = 0x0000 ...
- think php 图像加水印
1.将下载好的字体引入至 thinkPHP 框架的public/static 下(这里我建了一个文件夹叫font) (1.) (2.) 2.将字体路径写入config.php中 'font'=&g ...
- pandas常用操作详解——数据运算(一)
表与表之间的数据运算 #构建数据集df1=pd.DataFrame(np.random.random(32).reshape(8,4),columns=list('ABCD')) df2=pd.Dat ...
- [树]LeetCode589 N叉树的前序遍历
LeetCode N叉树的前序遍历 前言:树的前中后序遍历已经是很经典的题目的,要么递归要么迭代,不过还是比较习惯于递归的写法 TITLE 给定一个 n 叉树的根节点 root ,返回 其节点值的 前 ...
- [动态规划] 适合DJ银行的日子
[动态规划] 适合DJ银行的日子 前言:开始的时候用常规模拟做的超时了,然后看官方题解,大致意思就是连续n天单调可以用动态规划的思想 你和一群强盗准备打劫银行.给你一个下标从 0 开始的整数数组 se ...
- 关于二维DP————站上巨人的肩膀
意匠惨淡经营中ing, 语不惊人死不休........ 前几天学了DP,做了个简单的整理,记录了关于DP的一些概念之类的,今天记录一下刚学的一个类型 ----关于二维DP 那建立二维数组主要是干嘛用的 ...