STM32裸机串口接收方案

2023-11-13

在这里插入图片描述

[--------------点击下面,进入总目录索引--------------]
STM32系列精品Demo集 - 总目录


一、UART接收方案汇总

在这里插入图片描述
在这里插入图片描述

补充说明
上述接收方案中有协议帧,本协议帧指的是有帧头帧尾这种协议,不包含类似AT指令这种协议方案

二、UART丢包问题分析

2.1 、裸跑机制

  • 裸跑时上述UART接收方案中的方法一 、二分析
  1. 主任务能够及时轮询处理,fifo空间写入与读取能够满足,都不会丢包。
  2. 两个接口在主任务不能及时轮询处理,fifo被中断写满,都会导致丢包:
    2.1. 上述UART接收方案中的情形一 :存在单字节数据丢失,导致ffifo中后续的数据已经不是完整帧,全部错乱。(!!所以不建议采用这种方式!!)
    2.2. 上述UART接收方案中的情形二 :存在丢整帧数据,但是如果丢也是整帧数据,不会扰乱fifo中其它的完整帧。

  • 裸机情况下,如果主任务其它工作耗时特别大,等轮询到读取fifo并处理时,fifo早都被uart中断填满,丢掉了好多数据,所以裸机跑应该注意一下几点:
  1. 尽可能代码优化,减少耗时,这样轮询时间就快一点读取到fifo,不至于fifo满掉。
  2. 可以把fifo空间调大,以匹配该项目的时间轮序机制。

  • 裸机情况下如何尽可能保证不丢包?

说明:为何说尽可能,因为fifo不是无限大的,定义大了,很有可能栈错误。所以fifo大小也是有限的,而如果主任务不能及时读取fifo,数据又不断的发过来填充到fifo,必然导致丢数据。

  1. 多个fifo实现乒乓操作或者把一个fifo缓冲区调节的足够大**,其目的是让fifo缓冲尽可能大**:
    1.1. 一个fifo缓冲区调节的足够大,大到满足项目需求。
    1.2. 多个fifo实现乒乓操作,以满足项目需求(有弊端,主任务不能把控先写入fifo的先处理)。

  2. DMA+空闲中断+fifo的环形缓冲。 (如果系统资源够,那就把dma用上无妨)
    目的:让cpu尽可能高效率的执行,减少时间开销能尽快的轮询到uart读取fifo,这样就可以让fifo内存重复利用不至于填满。


2.2 、跑OS分析

  • os下,单个线程中读取fifo处理,问题不大,数据能及时的从fifo读出,使得fifo内存一直有可用空间,不至于fifo填满,导致数据丢包。

三、UART DEMO示例

3.1 、定长数据接收(无所谓有无协议)

采用方案:UART接收方案->数据定长->情形一->方法一
定长数据接收:无所谓有无协议都可以用下述示例去接收,如果有协议当然亦可以按照协议去解析完整包。

/***********************************************************************
 * 函数名称: CreatRingBuffer
 * 功能描述: 创建环形缓冲FIFO
 * 输入参数: 
 * 输出参数: 
 * 返 回 值: 
 *  其   它: 
 ***********************************************************************/
int  CreatRingBuffer()
{
	int iRet = 0;
	//初始化RingBuffer操作句柄,绑定缓冲区数组;
	iRet = Ring_Buffer_Init(&g_stRingBuff, g_aucUartRepBuff, RING_BUFFER_SIZE);
	if (iRet <= 0)
	{
		return -1;
	}
	return 0;
}
unsigned char g_ucTmpCnt = 0;
unsigned char g_aucTmpValue[RECV_FIX_DATA_LEN];
unsigned int   g_uiLostPackNum = 0;   

/***********************************************************************
* 函数名称: USART3_IRQRecvFixDataLenWithOutProtocolF1
* 功能描述: 每接收到一包完整的数据帧,写环形缓冲FIFO,并统计丢包数
* 输入参数: 
* 输出参数: 
* 返 回 值: 
*  其   它: 
***********************************************************************/
void  USART3_IRQRecvFixDataLenWithOutProtocolF1(void)
{
  unsigned char RepData = 0;
  int iRet = 0;
  RepData = USART_ReceiveData(USART3);	
  g_aucTmpValue[g_ucTmpCnt] = RepData;
  g_ucTmpCnt++;
  if(g_ucTmpCnt==RECV_FIX_DATA_LEN)
  {
      g_ucTmpCnt = 0;
      iRet = Ring_Buffer_Write_String(&g_stRingBuff, g_aucTmpValue,RECV_FIX_DATA_LEN);
  	if(iRet == RING_BUFFER_ERROR)
  	{
  		g_uiLostPackNum++;
  	}
  }
}
/***********************************************************************
* 函数名称: Uart3_IRQHandler
* 功能描述: Uart3中断服务函数
* 输入参数:
* 输出参数:
* 返 回 值:
*  其   它:
***********************************************************************/
void  USART3_IRQHandler (void)
{
  unsigned char RepData = 0;
  if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
  {
  	//USART3_IRQRecvFixDataLenWithOutProtocolF0();
  	USART3_IRQRecvFixDataLenWithOutProtocolF1();
  }
}
unsigned int g_uiProcessPackageNum = 0;
/***********************************************************************
* 函数名称: PrintfUartRecvPackage
* 功能描述:打印接收的数据包与丢包数
* 输入参数:
* 输出参数:
* 返 回 值:
*  其   它:
***********************************************************************/
void  PrintfUartRecvPackage()
{
   int    ix;
   int    iRet;
   unsigned int  uiBuffLen = 0;
   unsigned char  pucBuf[RECV_FIX_DATA_LEN];
   static  unsigned int  uiTmpRecord = 0;

   uiBuffLen = Ring_Buffer_Get_Lenght(&g_stRingBuff);
   //环形缓冲数据已经有完整包
   if (uiBuffLen >= RECV_FIX_DATA_LEN)
   {
       Ring_Buffer_Read_String(&g_stRingBuff, pucBuf, RECV_FIX_DATA_LEN);
   	for(ix = 0;ix < RECV_FIX_DATA_LEN; ix++)
   	{
   		printf("  0x%x",pucBuf[ix]);
   	}
   	g_uiProcessPackageNum++;
   	//printf("\r\nLost Package Num = %d.\r\n",g_uiLostDataLen);
   	 printf("\r\nLost Package Num = %d.\r\n",g_uiLostPackNum);
   	printf("\r\nProcess PackageNum  = %d.\r\n",g_uiProcessPackageNum);
   }
}
int main(void)
{
  int iRet = 0;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  delay_init();
  ControlUartInit(UART0_CHANNEL, 115200);
  ControlUartInit(UART3_CHANNEL, 115200);
  iRet = CreatRingBuffer();
  if(iRet < 0)
  {
  	printf("Ring Buffer Init fail.\r\n");
  	return 0;
  }
  printf("system is runing.\r\n");
  while (1)
  {
  	PrintfUartRecvPackage();
      delay_ms(10);  //用Delay方式来模拟主机在执行其它功能任务
  }
}

100ms间隔测试无丢包
在这里插入图片描述
7ms间隔定时测试就已经开始丢包:
丢包原因就是主任务没有及时轮询到读fifo,导致fifo满了,数包丢失
在这里插入图片描述

3.2 、非定长有协议帧数据接收

数据通信中协议帧的包头包尾一般有两种体现形式

帧格式1:包头包尾各一个字节:如0xc0 xxx xxx xxx xxx… 0xc0

帧格式2:包头包尾各两个字节:如0xeb 0x90 … 0xed 0x03

  • 帧格式1分析:

  包头包尾有仅一个字节,那么很有可中间的数据段也是0xc0与包头包尾一致,此时就需要就行转译与反转译

  • 帧格式2分析:

  包头包尾各两个字节,中间连续数据段的某两个字节与包头或包尾一致,此概率还是较小的,所以一般通信协议的制定建议包头包尾各两个字节

  • 重点重点
  1. 对于非定长 、非阻塞式(需要做数据缓存)、有协议帧数据类型的接收方案,主机任务处理端建议一次性把fifo读空,这样不管是本次读到的数据还是后续fifo填充后的整体数据都能保证是完整的帧
  2. 如果是按某一长度去读,由于数据非定长,会导致读到的数据以及fifo余下的数据不是完整帧
/***********************************************************************
 * 函数名称: FrameDataUnpack
 * 功能描述: 解析单字节数据流,输出一个完整的数据帧
 * 输入参数: 
 			data:单字节流数据
 			frame:此处作为输出参数
 * 输出参数:
 * 返 回 值:
 			 1:数据帧解析成功
 			 0:数据帧解析失败
 *  其   它:
           包头包尾单字节,带转义功能
           0xc0 xx xx 0xc0
 ***********************************************************************/
int FrameDataUnpack(ST_FRAME *frame, unsigned char data)
{
    int ret = FRAME_PARSER_ERROR;
    switch (frame->recvFlag)
    {
        case RecvNothing:
            if (0xC0 == data)
        	{
	            frame->recvFlag = RecvHeader; 
				//如果不想把包头数据整进去,此处可以去掉
			    frame->buffer[frame->len++] = 0xC0;
        	}
            break;
        case RecvHeader:
            if (0xC0 == data)
            {
                if (frame->len < 2)
                {
                    frame->recvFlag = RecvHeader;
                }
                else
                {
                	/* [add by jiangfeng.zhang, 2021-07-08] :整帧数据接收完成,直接返回*/
				   //如果不想把包尾数据整进去,此处可以去掉
					frame->buffer[frame->len++] = 0xC0;
					return FRAME_PARSER_SUCCESS;
                }
            }
            else
            {
                if (frame->len >= frame->bufSize)
                {
                    //溢出
                    ResetFrame(frame);
                    ret = FRAME_PARSER_ERROR;
                    break;
                }
                //在线即时转义
                if (frame->escape)
                {
                    if (0xDC == data)
                    {
                        frame->buffer[frame->len++] = 0xC0;
                    }
                    else if (0xDD == data)
                    {
                        frame->buffer[frame->len++] = 0xDB;
                    }
                    else
                    {
                        //非法转义字符,忽略转义
                        frame->buffer[frame->len++] = data;
                    }
                    frame->escape = EscapeDisEnable;
                }
                else
                {
                    if (0xDB == data)
                    {
                        frame->escape = EscapeEnable;
                    }
                    else
                    {
                        frame->buffer[frame->len++] = data;
                    }
                }
            }
            break;
        default:
            ResetFrame(frame);
            break;
    }
    return ret;
}
/***********************************************************************
 * 函数名称: FrameDataUnpackDoubleWithoutEsc
 * 功能描述: 解析单字节数据流,输出一个完整的数据帧
 * 输入参数: 
 			data:单字节流数据
 			frame:此处作为输出参数
 * 输出参数:
 * 返 回 值:
 			 1:数据帧解析成功
 			 0:数据帧解析失败
 *  其   它:
 			 包头包尾双字节+不带转译功能,不考虑中间数据字段出现连续0xeb 0x90
 			 0xeb 0x90 ... 0xed 0x03
 ***********************************************************************/
int FrameDataUnpackDoubleWithoutEsc(ST_FRAME *frame, unsigned char data)
{
    int ret = FRAME_PARSER_ERROR;
    switch (frame->recvFlag)
    {
        case RecvNothing:
            if (0xeb == data)
        	{
			    frame->buffer[frame->len++] = data;
				frame->recvFlag = RecvFirstHeader; 
        	}
            break;
		case RecvFirstHeader:
			//检测到0xeb前提下,紧接着检测到0x90,则认为检测到了包头。
			if(0x90==data)
			{
				frame->buffer[frame->len++] = data;
				frame->recvFlag = RecvHeader; 
			}
			//已经检测到0xeb,但是下一个数据检测到的不是0x90,认为数据有问题,重新找包头包尾。
			else
			{
				 ResetFrame(frame);
			}
            break;
        case RecvHeader:
		    //0xed有可能只是数据段,有可能是包尾
            if (0xed == data)
            {
            	frame->recvFlag = RecvSubTail; 
			    frame->buffer[frame->len++] = data;
            }
            else
            {
                if (frame->len >= frame->bufSize)
                {
                    //溢出
                    ResetFrame(frame);
                    ret = FRAME_PARSER_ERROR;
                    break;
                }
                else
                {
                    frame->buffer[frame->len++] = data;
                }
            }
            break;
		case RecvSubTail:	
			//检测到0xed的前提下,仅接着看这次数据是否是帧尾的最后一个字节0x03
			if (0x03 == data)
			{
				/* [add by jiangfeng.zhang, 2021-07-08] :整帧数据接收完成,直接返回*/
				frame->buffer[frame->len++] = data;
				return FRAME_PARSER_SUCCESS;
			}
			if(0xed !=data)
			{
				frame->recvFlag = RecvHeader;
				frame->buffer[frame->len++] = data;
			}
			//else分支主要考虑此种情况:eb 90 11 22 33 44 55 66 77 ed ed 03
			else
			{
				frame->buffer[frame->len++] = data;
			}
			break;
        default:
            ResetFrame(frame);
            break;
    }
    return ret;
}
/***********************************************************************
 * 函数名称: Uart3_IRQHandler
 * 功能描述: Uart3中断服务函数
 * 输入参数:
 * 输出参数:
 * 返 回 值:
 *  其   它:
 ***********************************************************************/
void  USART3_IRQHandler (void)
{
    unsigned char RepData = 0;
	int iRet = 0;
    if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
    {
	    RepData = USART_ReceiveData(USART3);	
//		iRet = FrameDataUnpack(&g_stFrame,RepData);
		iRet = FrameDataUnpackDoubleWithoutEsc(&g_stFrame,RepData);
		//此处认为解析到一组完整的数据帧
		if(iRet == FRAME_PARSER_SUCCESS)
		{
			iRet = Ring_Buffer_Write_String(&g_stRingBuff, g_stFrame.buffer,g_stFrame.len);
			if(iRet == RING_BUFFER_ERROR)
			{
				g_uiLostPackNum++;
			}
			//数据处理完成后,所有的转态进行复位
			ResetFrame(&g_stFrame);
		}
    }
	USART_ClearITPendingBit(USART3, USART_IT_RXNE);
}

unsigned int g_uiProcessPackageNum = 0;
/***********************************************************************
 * 函数名称: PrintfUartRecvAll
 * 功能描述: 将fifo中所有的数据一次读空进行处理
 * 输入参数:
 * 输出参数:
 * 返 回 值:
 *  其   它:
 ***********************************************************************/
void  PrintfUartRecvAll()
{
	int    ix;
    int    iRet;
    unsigned int  uiBuffLen = 0;
    unsigned char  pucBuf[RING_BUFFER_SIZE];
	static  unsigned int  uiTmpRecord = 0;

    uiBuffLen = Ring_Buffer_Get_Lenght(&g_stRingBuff);
	if(uiBuffLen>0)
	{
	    Ring_Buffer_Read_String(&g_stRingBuff, pucBuf, uiBuffLen);
		for(ix = 0;ix < uiBuffLen; ix++)
		{
			printf("  0x%x",pucBuf[ix]);
		}
		g_uiProcessPackageNum++;
		//printf("\r\nLost Package Num = %d.\r\n",g_uiLostDataLen);
		printf("\r\nLost Package Num = %d.\r\n",g_uiLostPackNum);
		printf("\r\nProcess PackageNum  = %d.\r\n",g_uiProcessPackageNum);
	}
}
/***********************************************************************
 * 函数名称: main
 * 功能描述:
 * 输入参数:
 * 输出参数:
 * 返 回 值:
 *  其   它:
 ***********************************************************************/
int main(void)
{
	int iRet = 0;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    delay_init();
    ControlUartInit(UART0_CHANNEL, 115200);
    ControlUartInit(UART3_CHANNEL, 115200);
	iRet = CreatRingBuffer();
	if(iRet < 0)
	{
		printf("Ring Buffer Init fail.\r\n");
		return 0;
	}

	iRet = CreateFrameBufferFun1(&g_stFrame,20);
	if(iRet <= 0)
	{
		printf("FrameBuffer Init fail.\r\n");
		return 0;
	}
	printf("system is runing.\r\n");
    while (1)
    {
    	PrintfUartRecvAll();
        delay_ms(10);  //用Delay方式来模拟主机在执行其它功能任务
    }
}

1000包协议帧测试无丢包
在这里插入图片描述

附录:Demo源码

https://gitee.com/jiangfengzhang/stm32-f4-uart-recv-demo
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32裸机串口接收方案 的相关文章

  • 电子信息工程考研:12大专业方向解读

    导读 模式识别与智能系统专业解读 通信与信息系统专业解读 电路与系统专业解读 信号与信息处理专业解读 电子与通信工程专业解读 电力电子与电力传动专业解读 光电信息工程专业解读 物理电子学专业解读 控制工程专业解读 集成电路工程专业解读 精密
  • mysql row()函数_详解mysql数据库binlog三种模式的区别(row,statement,mixed)

    概述 Mysql binlog日志有三种格式 分别为Statement MiXED 以及ROW 这三种格式之间有什么区别呢 下面先介绍下各自的优缺点 ROW 日志中会记录成每一行数据被修改的形式 然后在slave端再对相同的数据进行修改 只
  • 5.12 树和森林的遍历

    一 树的遍历 1 先根遍历 根左右 深度优先遍历 若树非空 先访问根节点 再依次对每棵子树进行先根遍历 树的先根遍历 void PreOrder TreeNode R if R NULL visit R 访问根结点 while R还有下一棵
  • 动态图分类:DySAT算法及其Python实现

    动态图分类 DySAT算法及其Python实现 动态图分类是计算机视觉领域的一个重要任务 其目标是对动态图像序列进行分类 DySAT算法是一种基于结构Self Attention和时域Self Attention的深度学习模型 用于解决动态
  • 在阿里云里面服务器怎么样可以更好的链接数据库

    环境 阿里云ubuntu服务器 阿里云RDS数据库 问题 如何在阿里云服务器的终端使用shell命令连接RDS云数据库 解决方法 1 阿里云服务器安装MySQL sudo apt get install mysql server 如果出现u
  • 非标准包 game.rgss3a 的打开方法

    写在前面 最近在玩 RPG 游戏 想拆一个 Game rgss3a 包 在网上找了很久的拆包方法 感觉写的比较凌乱 我来给大家整理一下吧 不过我本人的技术能力也很差 不确定说的是不是对的 就当是给大家提供几个方法 大家都自己试一下吧 先说
  • 近源渗透学习

    一 近源渗透 近源渗透测试是网络空间安全领域逐渐兴起的一种新的安全评估手段 它是一种集常规网络攻防 物理接近 社会工程学及无线电通信攻防等能力于一体的高规格网络安全评估行动 网络安全评估小组在签订渗透测试授权协议后 通过乔装 社工等方式实地
  • git 常用命令---修改Git默认编辑器为vim

    1 配置 git config global user email you example com 配置git用户名 git config global user name Your Name 配置git邮件 git config glob
  • C++类使用未定义类型 use undefined class

    a h file include
  • [论文笔记]AutoAssign 阅读笔记

    AutoAssign 阅读笔记 AutoAssign Differentiable Label Assignment for Dense Object Detection 摘要 1 引言 2 相关工作 固定标签分配 Fixed Label
  • Vue.js 生命周期函数

    系列文章目录 Vue js基础简答题 文章目录 系列文章目录 前言 一 创建阶段 1 beforeCreate 2 created 3 beforeMount 4 mounted 二 运行阶段 1 beforeUpdate 2 update
  • 字符设备驱动详解(主次设备号、注册/卸载字符设备驱动、创建设备节点、地址映射)

    1 主次设备号 1 主次设备号是内核用来索引设备的 每个主次设备号在内核中都是唯一的 每个注册的设备都有一个分配的主次设备号 2 同一个主设备号可以有多个从设备号 主设备是对应的驱动程序 次设备号对应设备文件所指的设备 一个Soc可能接同样
  • Odoo进销存(采购、销售、仓库)入门教程 - 上

    运行环境 Ubuntu14 04 Odoo8 0 作者 苏州 微尘 0 前言 Odoo OpenERP 作为一款优秀的开源ERP软件 开发历史已有10年之久 随着系统的发展成熟 已有越来越多的公司借助Odoo管理日常业务的方方面面 本文以一
  • undo表空间故障特殊恢复(一)

    author skate time 2010 09 09 undo表空间故障特殊恢复 一 这个测试的是instance recover 单实例里就是crash recovery 的恢复不需要故障undo里的数据 一般的情况instance
  • python修改字典内key对应的值的代码

    下面代码段是关于python修改字典内key对应的值的代码 希望对码农有用 d2 spam 2 ham 1 eggs 3 make a dictionary print d2 order is scrambled d2 ham grill
  • python爬虫网页编码问题——网页gbk编码

    爬虫的时候遇到一个网页的编码是有问题 添加了这句 没问题了 20210124 21 34 response encoding gbk
  • 基于Linux开发python项目

    在某些公司要求中 我们不会直接在Windows系统上做项目的开发 有时候会采用在linux系统上开发 而这分为两种情况 1 直接在本地搭建虚拟机 虚拟机上面装centos镜像 项目运行在本地虚拟机上 大部分原因都是项目的某些依赖包在Wind
  • 4 业务分析师

    在每个软件项目中 都有人在显式或隐式地扮演业务分析师 BA 的角色 业务分析师是能够在组织中促进变化的人 他们通过定义需求和向干系人推荐有价值的解决方案来促进这些变化 分析师获取和分析他人的观点 将收集到的信息转换为需求规范说明 并于其他干
  • 如何从无序链表中移除重复项--Java版

    题目描述 给定一个没有排序的链表 去掉其重复项 并保留原顺序 如链表1 gt 3 gt 1 gt 5 gt 5 gt 7 去掉重复项变为1 gt 3 gt 5 gt 7 方法一 顺序删除 思路 通过双重循环直接在链表上执行删除操作 外层循环

随机推荐

  • 对习乐app的某课程的所有题目爬取

    这学期就想把习乐题库刷空 一直没时间弄 期末来了 课少了 搞起来 习乐好像是一个一个学长写的app 但是对不住了 增加了点垃圾数据 23333 思路 1 手机或模拟器抓包 分析提交自测数据包 查看试卷数据包 2 模拟上面的数据包 3 清洗数
  • Linux下ntpdate时间同步

    原文地址 http gaoxingf blog 51cto com 612518 121959 作者 高兴F Linux下ntpdate时间同步 Ntp服务器安装配置 RedHat服务器可以下载rpm安装包 然后执行 rpm ivh ntp
  • Linux安装MySQL

    Linux安装MySQL 链接 MySQL官网9 7 18的下载 查看是否已经安装了mariadb 检查linux是否安装了mariadb数据库 mariadb数据库是mysql的分支 是免费开源的 mariadb和msyql会有冲突 首先
  • vue中用echart写饼状图

    用echart饼状图实现男女比例 效果图如下 实现代码如下
  • 静态代码扫描工具汇总

    一 概述 在软件开发过程中 开发团队往往要花费大量的时间和精力发现并修改代码缺陷 传统的代码评审 同事复审 通过人工方式来检查缺陷仍然是一件耗时耗力的事情 而静态代码扫描工具能够在代码构建过程中帮助开发人员快速 有效的定位代码缺陷并及时纠正
  • Qt 设置窗口背景图片的几种方法

    1 在paintEvent事件中绘制图片 void Widget paintEvent QPaintEvent ev QPainter painter this painter drawPixmap rect QPixmap bg jpg
  • k8s集群中部署微服务项目前端代理服务 Nginx

    k8s集群中部署微服务项目前端代理服务 Nginx 一 微服务项目静态资源准备 mkdir sangomall proxy cd sangomall proxy root k8s master01 sangomall proxy ls co
  • 记录开发遇到的问题

    这里写目录标题 一 React 1 ref和wrappedComponentRef使用区别 https blog csdn net weixin 38009285 article details 119420763 2 umi中其他页面跳转
  • ctfshow web 练习记录(1,2)

    web1 查看源代码 base64解码 web2 sql注入 使用万能公式username 1 or 1 1 passwd 123 有回显 再使用order by 查询列数 username 1 or 1 1 order by 1 到4没有
  • 国内访问github速度过慢的问题解决

    1 在浏览器上输入网址 http tool chinaz com dns 2 查询http github com 3 找到TTL值最低的响应IP 比如IP20 32 253 113的TTL值最低你就选这个IP 4 打开我的电脑 进入到C W
  • 粒子群算法组卷_CVRP问题求解(一)整数编码的粒子群算法

    CVRP问题求解 一 整数编码的粒子群算法 粒子群算法概述 粒子群算法 Particle Swarm Optimization 是由鸟群捕食得到启发的一种算法 在鸟类觅食过程中 每只鸟都会利用自身经验和群体信息来寻找食物 在觅食过程中 每只
  • 跳槽季到了,Linux运维跳槽40道面试精华题

    1 什么是运维 什么是游戏运维 1 运维是指大型组织已经建立好的网络软硬件的维护 就是要保证业务的上线与运作的正常 在他运转的过程中 对他进行维护 他集合了网络 系统 数据库 开发 安全 监控于一身的技术 运维又包括很多种 有DBA运维 网
  • C++寻找数组中的最大值

    include
  • OpenCV——高斯滤波

    目录 一 高斯滤波 二 C 代码 三 python代码 四 结果展示 1 原始图像 2 5x5卷积 3 9x9卷积 一 高斯滤波 高斯滤波是一种线性平滑滤波 适用于消除高斯噪声 广泛应用于图像处理的减噪过程 1 通俗的讲 高斯滤波就是对整幅
  • PC端页面适应不同的分辨率的方法

    上周完成一个PC端的项目 对于我这样的小白来说 这个项目里面最大的问题就是 如何做到让HTML页面适应电脑的不同分辨率 通过师傅的指导和自己查阅资料 最终成功适配不同的分辨率 完成了这个项目 现在回头再来看这个项目 突然发现适配不同的分辨率
  • js弹出窗口总结6种弹窗方法

    关闭 父窗口弹出对话框 子窗口直接关闭 this Response Write 关闭 父窗口和子窗口都不弹出对话框 直接关闭 this Response Write 弹出窗口刷新当前页面width 200 height 200菜单 菜单栏
  • 【图像处理】OpenCV截图小工具

    还存在一些小Bug 需要改进 include
  • 查询表结构信息sql

    select DQMS 库名 A Table Name 表名 C comments 表中文名 A column name 字段名 B comments 备注 A data type 数据类型 A data length 长度 A data
  • 基于SpringBoot左岸小区车位管理系统的设计与实现

    随着信息化时代的到来 管理系统都趋向于智能化 系统化 小区车位管理系统也不例外 但目前不少小区车位的管理仍都使用人工管理 小区规模越来越大 入住率越高 小区车辆信息量也越来越庞大 人工管理显然已无法应对时代的变化 而小区车位管理系统能很好地
  • STM32裸机串口接收方案

    点击下面 进入总目录索引 STM32系列精品Demo集 总目录 一 UART接收方案汇总 补充说明 上述接收方案中有协议帧 本协议帧指的是有帧头帧尾这种协议 不包含类似AT指令这种协议方案 二 UART丢包问题分析 2 1 裸跑机制 裸跑时