STM32F4系列单片机的定时器讲解和计数器,PWM信号输出,PWM信号捕获的实现对电机进行控制和监测功能

1.定时器功能介绍:

在控制领域里面,我们可以用信号输出定时器,进行PWM的控制,从而达到控制电机的目的,通过输入捕获功能可以用来接收外部的数字信号,用于测量脉冲宽度、频率或周期等。在这里给大家介绍下,具体用定时器做计数,输出和捕获的功能实现。

STM32F4一共有三种14个定时器。(12个16位的,2个32位的),STM32F1系列只有8个16位的。

高级定时器:TIM1、TIM8。通常用于特定领域和专业需求用户使用的精密计时工具,通常适用于需要精度更高的领域。通常可以精确到毫秒或更小的时间单位,并具有更复杂的逻辑和算法。

通用定时器:TIM2、TIM5、TIM3、TIM4,TIM9~TIM14。 

基本定时器:TIM6、TIM7,没有捕获等通道,用作简单定时。

STM32通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)等。

2.计数定时器配置

在STM32F429上实现TIM6的计时,可以通过以下步骤进行:

  1. 使能TIM6时钟。

  2. 初始化TIM6时基单元,设置时钟分频系数和计数周期。

  3. 使能更新中断(如果需要)。

  4. 使能TIM6。

  5. 等待中断处理(如果使能了中断)。

以下是一个简单的示例代码,展示如何使用HAL库函数来配置TIM6作为一个简单的计时器:

/* 注意:1. 中断相关名称。注意基本定时器TIM6 的中断名为 TIM6_DAC_IRQn,< TIM6 global and DAC1&2 underrun error  interrupts>,其他一些定时器为 TIMx_IRQn(x=2,3,4,7 etc)	*/
/* 中断函数名为 TIM6_DAC_IRQHandler(),而不是 TIM6_IRQHandler()		*/
/* 3. 基本定时器(TIM6, TIM7),通用定时器,高级定时器(TIM1, TIM8),功能越来越多,此处只做个简单计时,基本定时器足够了	*/#include "timer.h"uint32_t tim = 0;						// 全局变量,每0.1ms加1
TIM_HandleTypeDef TIM6_Handler;      	//定时器句柄 /* 基本定时器6初始化						*/
/* 实现 0.1ms 计时中断					*/
/* 90M/90=1M,1M/100 = 10kHz = 0.1ms	*/
void TIM6_Init(void)
{  TIM_MasterConfigTypeDef sMasterConfig = {0};TIM6_Handler.Instance			= TIM6;                  		// 基本定时器TIM6_Handler.Init.Prescaler		= 180-1;                 		// 分频系数 180MHz,得到 180M/180=1M 时钟TIM6_Handler.Init.CounterMode	= TIM_COUNTERMODE_UP;    		// 向上计数器TIM6_Handler.Init.Period		= 100-1;                  		// 自动装载值 100,每 100/1M = 100us=0.1ms中断一次htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;HAL_TIM_Base_Init(&TIM6_Handler);sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK){Error_Handler();}HAL_TIM_Base_Start_IT(&TIM6_Handler); //使能定时器3和定时器3更新中断:TIM_IT_UPDATE   
}
/* 定时器底册驱动,开启时钟,设置中断优先级	*/
/* 此函数会被HAL_TIM_Base_Init()函数调用		*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM6){__HAL_RCC_TIM6_CLK_DISABLE();    						// 使能TIM6时钟,HAL_NVIC_SetPriority(TIM6_IRQn,1,3);    					// 中断优先级:抢占优先级1,子优先级3。HAL_NVIC_EnableIRQ(TIM6_IRQn);        					// 开启ITM6中断  }
}/*** @brief  定时器比较中断* @param  htim:定时器句柄指针*	@note 		无* @retval 无*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(__HAL_TIM_GET_IT_SOURCE(&TIM6_Handler, TIM_IT_UPDATE) !=RESET){__HAL_TIM_CLEAR_IT(&TIM6_Handler, TIM_IT_UPDATE);				// 清除中断标志位}tim ++; 														// 又是0.1ms,全局时间计数加1
}

3.TIM3输出4路PWM波

与定时不同,配置输出PWM波需要配置I/O口,相应地需要配置相应通道;输出PWM波时可不配置中断。步骤如下:

初始化配置。选择时钟、配置分频系数、计数模式、自动重装值、分频因子。
通道配置。配置PWM模式、默认占空比、输出比较极性并且开启对应的通道。
底层配置。开启时钟、配置相关引脚。
此处,航模电机驱动频率选择常用的 400Hz,定时器重装值选择 5000-1。为了方便实际中调节各个电机的占空比,编写设置于获取占空比的函数,占空比调节精度为 1/1000。

对于I/O选择,使用了TIM3 CH1~CH3,对应引脚参考核心板原理图:

#define PWM_PIN			GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_0 | GPIO_PIN_1
#define PWM_GPIO		GPIOB
#define PWM_ENCLK()		__HAL_RCC_TIM3_CLK_ENABLE();	\__HAL_RCC_GPIOB_CLK_ENABLE();	// 使能定时器3,开启GPIOB时钟						/* 四个电机枚举	*/
typedef enum
{MOTOR1 = 0,MOTOR2 = 1,MOTOR3 = 2,MOTOR4 = 3
};/* TIM3 4路 PWM波输出初始化 		*/
void TIM3_PWM_Init(void)
{ TIM3_Handler.Instance			= TIM3;            		//定时器3TIM3_Handler.Init.Prescaler		= 45-1;       			//定时器分频 45,得到 90M/45=2M 时钟TIM3_Handler.Init.CounterMode	= TIM_COUNTERMODE_UP;	//向上计数模式TIM3_Handler.Init.Period		= 5000-1;          		//自动重装载值 5000,得到PWM频率 2M/5k=400HzTIM3_Handler.Init.ClockDivision	= TIM_CLOCKDIVISION_DIV1;HAL_TIM_PWM_Init(&TIM3_Handler);       					//初始化PWMTIM3_CHxHandler.OCMode			= TIM_OCMODE_PWM1; 		//模式选择PWM1TIM3_CHxHandler.Pulse			= 0;           			//设置比较值,此值用来确定占空比,默认为0TIM3_CHxHandler.OCPolarity		= TIM_OCPOLARITY_HIGH; 	//输出比较极性为高HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CHxHandler,TIM_CHANNEL_1);	//配置TIM3通道1HAL_TIM_PWM_Start(&TIM3_Handler, TIM_CHANNEL_1);		//开启PWM通道1HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CHxHandler,TIM_CHANNEL_2);	//配置TIM3通道2HAL_TIM_PWM_Start(&TIM3_Handler, TIM_CHANNEL_2);		//开启PWM通道2HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CHxHandler,TIM_CHANNEL_3);	//配置TIM3通道3HAL_TIM_PWM_Start(&TIM3_Handler, TIM_CHANNEL_3);		//开启PWM通道3HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CHxHandler,TIM_CHANNEL_4);	//配置TIM3通道4HAL_TIM_PWM_Start(&TIM3_Handler, TIM_CHANNEL_4);		//开启PWM通道4}/* 定时器底层驱动,时钟使能,引脚配置	*/
/* 此函数会被HAL_TIM_PWM_Init()调用	*/
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{GPIO_InitTypeDef GPIO_Initure;PWM_ENCLK();GPIO_Initure.Pin		= PWM_PIN; GPIO_Initure.Mode		= GPIO_MODE_AF_PP;  			// 复用推完输出GPIO_Initure.Pull		= GPIO_PULLUP;          		// 上拉GPIO_Initure.Speed		= GPIO_SPEED_HIGH;     			// 高速GPIO_Initure.Alternate	= GPIO_AF2_TIM3;				// 引脚复用HAL_GPIO_Init(PWM_GPIO, &GPIO_Initure);
}/* 设置电机占空比										*/
/* motor: 选择电机,可填MOTOR1, MOTOR2, MOTOR3, MOTOR4	*/
/* duty: 占空比为千分之 duty								*/
void SetMotorDuty(uint8_t motor, uint16_t duty)
{if (duty > 1000)duty = 1000;else if (duty < 0)duty = 0;if (motor == MOTOR1)TIM3->CCR1 = duty * 5 - 1;	// 由于计数器重装值ARR为 5000,精度为千分之一,故此处乘以5,减一是因为从0开始计数else if (motor == MOTOR2)TIM3->CCR2 = duty * 5 - 1;else if (motor == MOTOR3)TIM3->CCR3 = duty * 5 - 1;else if (motor == MOTOR4) TIM3->CCR4 = duty * 5 - 1;
}/* 获取电机占空比														*/
/* motor选择电机,可填MOTOR1, MOTOR2, MOTOR3, MOTOR4,占空比为千分之返回值	*/
uint16_t GetMotorDuty(uint8_t motor)
{uint32_t cap_value;if (motor == MOTOR1)cap_value = HAL_TIM_ReadCapturedValue(&TIM3_Handler,TIM_CHANNEL_1);		// 读取比较寄存器的值else if (motor == MOTOR2)cap_value = HAL_TIM_ReadCapturedValue(&TIM3_Handler,TIM_CHANNEL_1);else if (motor == MOTOR3)cap_value = HAL_TIM_ReadCapturedValue(&TIM3_Handler,TIM_CHANNEL_1);else if (motor == MOTOR4) cap_value = HAL_TIM_ReadCapturedValue(&TIM3_Handler,TIM_CHANNEL_1);return (cap_value+1) / 5;
}				

4.TIM5输入捕获

输入捕获也需要配置对应的 I/O 口于通道,而且需要在中断服务函数里实现定时中断、高/低电平时间的测量。步骤如下:

1.初始化配置:选择时钟、配置分配系数、计数模式、自动重装值、时钟分频因子。
2.通道配置:配置上升/下降沿捕获、引脚对应寄存器、分频因子、滤波效果。
3.底层配置:配置引脚、使能时钟、中断优先级与是能。
4.中断服务函数:思想很简单,分别读取下降沿、上升沿、下降沿时寄存器数据,计算得到正脉宽、周期等参数。

#define CAP_PIN			GPIO_PIN_0
#define CAP_GPIO		GPIOA
#define CAP_ENCLK()		__HAL_RCC_TIM5_CLK_ENABLE();	\__HAL_RCC_GPIOA_CLK_ENABLE(); 	//使能TIM5时钟,开启GPIOA时钟TIM_HandleTypeDef TIM5_Handler;         							//定时器5句柄uint32_t cap_value1 = 0;			// 检测到上升沿时的计数
uint32_t cap_value2 = 0;			// 检测到下降沿时的计数, cap_value2 - cap_value1 即为正脉冲时间
uint32_t cap_value3 = 0;			// 再次检测到上升沿时的计数, cap_value3 - cap_value1 即为周期uint8_t cap_sta = 0;				// 输入捕获状态, 0:没有完成捕获,去捕获边沿吧  1:捕获边沿完成,去计算周期吧
uint8_t cap_times = 0;				// 捕获次数/* 定时器5通道1输入捕获配置 	*/
/* 频率:90M/90/1 = 1MHz		*/
void TIM5_CH1_Cap_Init(void)
{  TIM_IC_InitTypeDef TIM5_CH1Config;  TIM5_Handler.Instance			= TIM5;                         // 通用定时器5TIM5_Handler.Init.Prescaler		= 90-1;                     	// 分频系数TIM5_Handler.Init.CounterMode	= TIM_COUNTERMODE_UP;    		// 向上计数器TIM5_Handler.Init.Period		= 0XFFFFFFFF;                   // 自动装载值TIM5_Handler.Init.ClockDivision	= TIM_CLOCKDIVISION_DIV1;		// 时钟分频银子HAL_TIM_IC_Init(&TIM5_Handler);									// 初始化输入捕获时基参数TIM5_CH1Config.ICPolarity		= TIM_ICPOLARITY_RISING;    	// 上升沿捕获TIM5_CH1Config.ICSelection		= TIM_ICSELECTION_DIRECTTI;		// 设置引脚与寄存器关系。CH1、CH2用TI1,CH3、CH4用TI2TIM5_CH1Config.ICPrescaler		= TIM_ICPSC_DIV1;          		// 配置输入分频,不分频TIM5_CH1Config.ICFilter=0;                          			// 配置输入滤波器,不滤波HAL_TIM_IC_ConfigChannel(&TIM5_Handler,&TIM5_CH1Config,TIM_CHANNEL_1);//配置TIM5通道1HAL_TIM_IC_Start_IT(&TIM5_Handler,TIM_CHANNEL_1);   			// 开启TIM5的捕获通道1,并且开启捕获中断__HAL_TIM_ENABLE_IT(&TIM5_Handler,TIM_IT_UPDATE);   			// 使能更新中断
}/* 定时器5底层驱动,时钟使能,引脚配置	*/
/* 此函数会被HAL_TIM_IC_Init()调用	*/
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{GPIO_InitTypeDef GPIO_Initure;CAP_ENCLK();GPIO_Initure.Pin		= CAP_PIN;            					// 引脚GPIO_Initure.Mode		= GPIO_MODE_AF_PP;      				// 复用推挽输出GPIO_Initure.Pull		= GPIO_PULLDOWN;        				// 下拉GPIO_Initure.Speed		= GPIO_SPEED_HIGH;     					// 高速GPIO_Initure.Alternate	= GPIO_AF2_TIM5;   						// PA0复用为TIM5通道1HAL_GPIO_Init(CAP_GPIO,&GPIO_Initure);HAL_NVIC_SetPriority(TIM5_IRQn,2,0);    						// 设置中断优先级,抢占优先级2,子优先级0HAL_NVIC_EnableIRQ(TIM5_IRQn);          						// 开启ITM5中断通道  
}/* 定时器5中断服务函数			*/
void TIM5_IRQHandler(void)
{HAL_TIM_IRQHandler(&TIM5_Handler);								//定时器共用处理函数
}/* 定时器输入捕获中断处理回调函数,该函数在HAL_TIM_IRQHandler中会被调用	*/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)			//更新中断(溢出)发生时执行
{if (cap_sta == 0){switch (cap_times){case 0: 				// 清空一切,准备捕获cap_value1 = 0;cap_value2  = 0;cap_value3  = 0;__HAL_TIM_DISABLE(&TIM5_Handler);        									//关闭定时器5__HAL_TIM_SET_COUNTER(&TIM5_Handler,0);		TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   					//一定要先清除原来的设置!!TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//定时器5通道1设置为下降沿捕获__HAL_TIM_ENABLE(&TIM5_Handler);cap_times = 1;break;case 1:					// 捕获了一次cap_value1 = HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_1);		// 读数一次TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   					//一定要先清除原来的设置!!TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//定时器5通道1设置为上升沿捕获		cap_times = 2;break;case 2:					// 捕获了两次cap_value2 = HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_1);		// 读数一次TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   					//一定要先清除原来的设置!!TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//定时器5通道1设置为下降沿捕获		cap_times = 3;break;case 3:					// 捕获了三次cap_value3 = HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_1);		// 读数一次TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   					//一定要先清除原来的设置!!TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);	//定时器5通道1设置为上升沿捕获cap_times = 0;			cap_sta = 1;		// 所有捕获完成,可以去计算了break;}}
}

测试捕获和输出:

void TestPwmTask(void *arg)
{const uint16_t test_postime = 100;	// 正常时间为 test_postime / 1000 * 2500 = test_postime * 2.5uint32_t pos_time;				// 高电平时间uint32_t cycle;					// 周期uint32_t freq;					// 频率float pos_duty;					// 正占空比SetMotorDuty(MOTOR1, test_postime);						// 电机PWM 400Hz = 2500 us,占空比 100/1000,高电平时间 250us		SetMotorDuty(MOTOR2, test_postime);SetMotorDuty(MOTOR3, test_postime);SetMotorDuty(MOTOR4, test_postime);while(1){if (cap_sta == 1)      		//成功捕获到了一次高电平{pos_time = cap_value3 - cap_value2;cycle = cap_value3 - cap_value1;freq = (uint32_t)1000000 / cycle;pos_duty = (float) pos_time / (float) cycle;printf("周期:%d us\t  正脉冲宽:%d us  \r\n", cycle, pos_time);printf("频率:%d Hz\t  正占空比:%.2f %%\r\n\r\n", freq, pos_duty*100);cap_sta = 0;          		// 搞完事情,开启下一次捕获}delay_ms(200);}
}

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

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

相关文章

缺省参数

缺省参数 缺省参数概念 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时&#xff0c;如果没有指定实 参则采用该形参的缺省值&#xff0c;否则使用指定的实参。 void Func(int a 0) {cout<<a<<endl; } int main() {Func(); // 没有传…

Rust所有权和Move关键字使用和含义讲解,以及Arc和Mutex使用

Rust 所有权规则 一个值只能被一个变量所拥有&#xff0c;这个变量被称为所有者。 一个值同一时刻只能有一个所有者&#xff0c;也就是说不能有两个变量拥有相同的值。所以对应变量赋值、参数传递、函数返回等行为&#xff0c;旧的所有者会把值的所有权转移给新的所有者&#…

共襄盛举!400+组织携手发布「2024集成光子学路线图」

3月25日&#xff0c;麻省理工学院微光子中心与PhotonDelta基金会联合领导&#xff0c;携手全球400余家科技、学术及工业界组织&#xff0c;共同发布了2024年版集成光子学路线图。 该路线图被称为IPSR-I&#xff08;Integrated Photonics System Roadmap – International&#…

某眼实时票房接口获取

某眼实时票房接口获取 前言解决方案1.找到veri.js2.找到signKey所在位置3.分析它所处的这个函数的内容4.index参数的获取5.signKey参数的获取运行结果关键代码另一种思路票房接口:https://piaofang.maoyan.com/dashboard-ajax https://piaofang.maoyan.com/dashboard 实时票房…

Docker实例

华子目录 docker实例1.为Ubuntu镜像添加ssh服务2.Docker安装mysql docker实例 1.为Ubuntu镜像添加ssh服务 (1)访问https://hub.docker.com&#xff0c;寻找合适的Ubuntu镜像 (2)拉取Ubuntu镜像 [rootserver ~]# docker pull ubuntu:latest latest: Pulling from library/ub…

课程设计项目1.3:双音多频(DTMF)通信设计仿真

01.课程设计内容 02.代码效果图 %参考程序&#xff1a;DTMF信号的产生 kcsj131s.m 差分方程法产生DTMF信号 clear clc fs8000; w2*pi/8000*[941 1336;697 1209;697 1336;697 1477; ...770 1209;770 1336;770 1477;852 1209;852 1336;852 1477];%各信号对应的数字频率 tab[2*co…

iOS开发进阶(十三):脚手架创建iOS项目

文章目录 一、前言二、xcode-select 命令三、拓展阅读 一、前言 项目初期&#xff0c;需要搭建项目基本框架&#xff0c;为此离不开辅助工具&#xff0c;即脚手架。当然&#xff0c;IDE也可以实现新建空白项目&#xff0c;但是其新建后的项目结构可能不符合预期设计&#xff0…

权限问题(Windows-System)

方法&#xff1a;用命令来写一个注册表的脚本 &#xff1f;System是最高级用户&#xff0c;但不拥有最高级权限 编写两文档&#xff1a;system.reg 和 remove.reg,代码如下&#xff1a; system.reg&#xff1a; Windows Registry Editor Version 5.00[-HKEY_CLASSES_ROOT\*…

【Qt 学习笔记】认识QtSDK中的重要工具

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 认识QtSDK中的重要工具 文章编号&#xff1a;Qt 学习笔记 / 03 文章目…

图论基础(python蓝桥杯)

图的基本概念 图的种类 怎么存放图呢&#xff1f; 优化 DFS 不是最快/最好的路&#xff0c;但是能找到一条连通的道路。&#xff08;判断两点之间是不是连通的&#xff09; 蓝桥3891 import os import sys sys.setrecursionlimit(100000) # 请在此输入您的代码 n, m map(int,…

什么是工业协议转换软件?

在现代工业自动化领域&#xff0c;随着技术的不断革新和智能化水平的提升&#xff0c;各种工业设备和系统之间的通信变得日益重要。然而&#xff0c;由于历史、技术差异和标准多样化等原因&#xff0c;不同的工业设备和系统往往采用各自独特的通信协议&#xff0c;导致它们之间…

Android Studio 打开Local Changes界面

在编写代码的过程中&#xff0c;经常要回顾本地仓库做了那些修改。打开Local Changes界面&#xff0c;能做到一目了然&#xff0c;不用再去使用git命令查看。 File->Settings->Version control->Commit 把Use non-modal commit interface 选项 取消勾选 即可

如何使用VNC+Cpolar实现Windows电脑公网远程控制Ubuntu系统桌面

文章目录 前言1. VisualSVN安装与配置2. VisualSVN Server管理界面配置3. 安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4. 固定公网地址访问 前言 SVN 是 subversion 的缩写&#xff0c;是一个开放源代码的版本控制系统…

官宣!一文掌握2024百度CreateAI开发者大会最新议程

4月16日上午9:00&#xff0c;以“创造未来”为主题的2024百度Create AI开发者大会将在深圳国际会展中心&#xff08;宝安&#xff09;开幕。此次大会将是近十年来&#xff0c;粤港澳大湾区规格最高的AI大会&#xff0c;将聚焦炙手可热的AI话题&#xff0c;在大会主论坛、分论坛…

卡尔曼滤波笔记

资料&#xff1a;https://www.zhihu.com/question/47559783/answer/2988744371 https://www.zhihu.com/question/47559783 https://blog.csdn.net/seek97/article/details/120012667 一、基本思想 在对一个状态值进行估计的时候&#xff0c;如果想测量值更准&#xff0c;很自然…

Windows搭建Lychee图片管理系统结合内网穿透实现公网访问本地图床

文章目录 1.前言2. Lychee网站搭建2.1. Lychee下载和安装2.2 Lychee网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 图床作为图片集中存放的服务网站&#xff0c;可以看做是云存储的一部分&#xff0c;既可…

【机器学习】科学库使用第3篇:机器学习概述,学习目标【附代码文档】

机器学习&#xff08;科学计算库&#xff09;完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;机器学习&#xff08;常用科学计算库的使用&#xff09;基础定位、目标&#xff0c;机器学习概述定位,目标,学习目标,学习目标,1 人工智能应用场景,2 人工智能小…

计算机网络|谢希仁版|数据链路层

数据链路层 数据链路层研究的是什么&#xff1f;数据链路层的几个共同问题数据链路与链路帧通信规程 三个基本问题封装成帧透明传输差错检测可靠传输 点对点协议PPPPPP协议应满足的需求PPP协议的组成PPP协议帧的格式各字段的意义字节填充零比特填充PPP协议的工作状态 使用广播信…

三电源切换电路。

一个三电源切换电路 电路描述 1、Q1、Q2为NMOS&#xff0c;Q3、Q4和Q5为PMOS管&#xff0c;D1为二极管。 2、BAT1和BAT2为电池&#xff0c;BAT2的容量比BAT1大&#xff0c;VIN_5V为外部电源&#xff0c;VOUT为输出&#xff0c;给系统供电。 3、VOUT会从优先级高的电源取电&a…

黑盒测试—等价分类法

等价分类法是把程序的输入域划分成若干部分&#xff08;子集&#xff09;&#xff0c;然后从每个部分中选取少数代表性数据作为测试用例。每一类的代表性数据在测试中的作用等价于这一类中的其他值。测试时把有效类与无效类相互组合&#xff0c;得到测试结果。 例题如下&#x…