当前位置: 首页 > news >正文

Stm32-使用TB6612驱动电机及编码器测速

这里写目录标题

    • 起因
    • 一、电机及编码器的参数
    • 二、硬件
    • 三、接线
    • 四、驱动电机
      • 1、TB6612电机驱动
      • 2、定时器的PWM模式驱动电机
    • 五、编码器测速
      • 1、定时器的编码器接口模式
      • 2、定时器编码器模式测速的原理
      • 3、编码器模式的配置
      • 4、编码器模式相关代码
      • 5、测速方法
    • 六、相关问题以及解答
      • 1、编码器模式下的自动重装值ARR和预分频PSC应该如何设置
      • 2、如何判断正反转
      • 3、圈数如何计算
      • 4、转速如何计算
      • 5、为什么我的编码器没有输出,获取到的脉冲数是0
    • 七、测速硬件展示及测速现象
    • 八、总结
    • 九、大家可以参考
      • 参考链接1
      • 参考链接2
      • 参考链接3
      • 参考链接4

起因

最近在学习编码电机以及尝试使用编码电机测速。遇到了很多问题,花费了很多时间,在这里做一个记录,对自己学习到的知识进行一个总结

找了很多资料,看了很多视频,这些太多了,以至于让我不知道究竟哪一个是正确的,今天看这个,明天看这个,导致自己的学习效率低下

当然,有很多大佬的文章和资料给了我很大的启发

这个电机我玩了四天,把自己觉得重要的东西和大家分享一下

现在一般都是用编码器电机,参加比赛啥的,编码电机常用于测速,所以编码电机就成了一个必须学习的知识点

编码器被广泛应用于电机测速,实现电机闭环控制。

相关的知识点有:定时器的输出比较(输出PWM)、定时器的输入捕获,定时器的编码器接口、速度控制


一、电机及编码器的参数

编码电机其实就是一个带有编码器的电机,我的这个电机是一个增量式的带霍尔传感器的电机

电机的型号是JGB37-520电机

下方是电机的参数
主要关注的就是电机的额定电压 12V
电机的减速比 30(这个很重要)

编码器的参数
主要关注编码器的线数 11线 (也就是说电机转一圈会产生11个脉冲)
供电电压 5V
输出类型 方波
在这里插入图片描述

编码器的连接

一般这种编码器都有六根线
两边靠外的两根线是电机电源线
往里两根是编码器的电源线
中间两根是编码器的A,B相
在这里插入图片描述

具体大概是啥意思呢?
就是电机转动的时候编码器会通过编码电机的A相和B相输出两个正交的方波

通过输出的两个方波就可以对电机进行测速识别电机的方向


二、硬件

整体结构采用洞洞板+TB6612+Stm32C8T6+编码电机(起初采用的是这种结构)

后面采用Stm32ZET6+TB6612+洞洞板+编码电机+12V电源(原因是C8T6烧坏了,哭😥)

主控Stm32C8T6 or Stm32ZET6
电机驱动 TB6612(由于上一个L298N烧了)
520霍尔编码电机
12V电源


三、接线

这里展示驱动一个编码电机的示例,毕竟先从一个电机玩起,弄懂后后面就会使用的更加得心应手啦

主要使用到了定时器的PWM模式(输出比较)功能

大家一定要认真接线,看清出每根线的作用,不要随便接线,一不小心电机驱动就烧了,或者是单片机烧了(在学习的时候就烧了一个单片机,人民币-15)

注意这个是我实现的接线,大家可以根据自己单片机的片上资源合理选择,选择合适的IO口

电机驱动

TB6612C8T6
STBY高电平(+3.3V)
AIN1PB14
AIN2PB15
PWMAPA8 (TIM1-CH1)
AO1电机电源+
AO2电机电源-
VM12V
VCC3.3V
GND和单片机共地

编码器

编码器的A、B相C8T6
A相PA0 (TIM2-CH1)
B相PA1 (TIM2-CH2)

四、驱动电机

1、TB6612电机驱动

首先了解一下TB6612

下图是TB6612驱动模块
原理图
在这里插入图片描述
STBY接高电平 清零电机全部停止
置 1 通过 AIN1 AIN2, BIN1,BIN2 引脚来控制正反转
PWM引脚控制占空比
VM: 接 12V 以内电源
VCC: 接 5V 电源
GND: 接电源负极

下图是驱动逻辑
可以看出IN引脚控制正反转,PWM引脚控制速度

2、定时器的PWM模式驱动电机

使用定时器的PWM模式 生成一个需要的 占空比可调的 频率 符合要求的方波信号。

方波信号的频率不宜过高或者过低,过高容易导致电机驱动的晶闸管经常处于开关状态–发热巨大过低则容易产生噪音,对电机也低频的冲击

这里输出PWM信号的定时器是TIM1-CH1

设置成PWM模式,频率和占空比可调

有关定时器PWM模式,可以看其他大佬的文章和资料,看看手册

可以看看江科大的教学视频,比我讲的详细多了,也很好理解

我贴出视频链接,大家学习32的时候可以跟他
TIM输出比较,PWM模式

下方的PWM模式的代码作为一个参考

Motor.h

#ifndef __MOTOR_H
#define __MOTOR_H
#include "sys.h"	 #define PWMA   TIM1->CCR1  //PA8  PWMA  TIM1_CH1
#define AIN2   PBout(15)
#define AIN1   PBout(14)void Motor_PWM_Init(u16 arr,u16 psc);
void Motor_SetSpeed(u8 mode ,u16 speed);#endif

Motor.c

void Motor_Init(void)	//IN引脚初始化
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_15;	//端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //50MGPIO_Init(GPIOB, &GPIO_InitStructure);				 //根据设定参数初始化GPIOB
}
void Motor_PWM_Init(u16 arr,u16 psc)	//PWM引脚初始化
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;TIM_OCInitTypeDef  TIM_OCInitStructure;Motor_Init();RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO,ENABLE);//开启时钟//输出TIM1 CH1 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM_CH1 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);//初始化定时器。TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  不分频TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能TIM_OCInitStructure.TIM_Pulse = 0;                            //设置待装入捕获比较寄存器的脉冲值TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;     //输出极性:TIM输出比较极性高TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMxTIM_CtrlPWMOutputs(TIM1,ENABLE);	//MOE 主输出使能		高级定时器一定要写这个语句TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器TIM_Cmd(TIM1, ENABLE);  //使能TIM1
}void Motor_SetSpeed(u8 mode ,u16 speed)		//mode 代表正反转 speed PWM占空比即速度
{PWMA = speed;if(mode==1){AIN1 = 1;AIN2 = 0;}else {AIN1 = 0;AIN2 = 1;}
}

五、编码器测速

编码器一般应用于电机控制,使用PWM驱动电机,然后再使用编码器测量速度,再使用PID算法进行闭环控制

记住下面这句话

在一定的时间内,电机转动一圈,通过霍尔传感器的A、B两相输出一定数量的脉冲,我们可以根据一定时间内的脉冲数计算出电机的瞬时速度。

1、定时器的编码器接口模式

采用的是定时器的编码器接口模式,Stm32中的定时器只有TIM1-5和TIM8才有编码器接口功能,而且只有CH1通道和CH2通道有用。

2、定时器编码器模式测速的原理

原理:接收编码器的A、B相产生的正交信号,根据编码器产生的正交信号脉冲,自动控制CNT自增或自减,根据计数方向和编码器的信号关系来指示编码器的位置、旋转方向和旋转速度利用脉冲值来计算电机的转动位移

这个可以参考手册里定时器的编码器模式,比我讲的清楚多了
定时器的编码器接口托管了输入捕获的前两个接口

还有一句话记住,编码器模式下就相当于一个带有方向选择的外部时钟

3、编码器模式的配置

具体配置流程就是

时钟–>GPIO–>时基单元配置–>编码器接口配置–>开启定时器–>读取一个时间段内的脉冲–>计算电机旋转轴转速

使用这个函数把定时器设置为编码器接口模式

TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

采用的是编码器模式3,在TI1和TI2边沿都计数,也就是在一个周期内对A相和B相的上升沿下降沿都计数一个周期内计4次,所以采用这种模式后,相应的计数值(CNT)就会变成4倍,这就是很多资料里说的四倍频计数

4、编码器模式相关代码

采用的是定时器2的编码器接口模式,通道1和通道2捕获
encoder.c

/*** @brief 把TIM2初始化为编码器接口模式* @param psc 预分频系数* @param arr 自动重装载值* @retval None*/
void Encoder_Init_TIM2(uint16_t psc,uint16_t arr)	
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;GPIO_InitTypeDef GPIO_InitStructure;//NVIC_InitTypeDef  NVIC_InitStructure;//使能定时器2的时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能PB端口时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//端口配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;//浮空输入GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//根据设定参数初始化GPIOBGPIO_Init(GPIOA, &GPIO_InitStructure);TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);// 预分频器TIM_TimeBaseStructure.TIM_Prescaler = psc;//设定计数器自动重装值TIM_TimeBaseStructure.TIM_Period = arr;//选择时钟分频:不分频TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//TIM向上计数TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//使用编码器模式3TIM_EncoderInterfaceConfig(TIM2, \TIM_EncoderMode_TI12, \TIM_ICPolarity_Rising, \TIM_ICPolarity_Rising);TIM_ICStructInit(&TIM_ICInitStructure);TIM_ICInitStructure.TIM_ICFilter = 10;TIM_ICInit(TIM2, &TIM_ICInitStructure);//清除TIM的更新标志位TIM_ClearFlag(TIM2, TIM_FLAG_Update);TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//Reset counterTIM_SetCounter(TIM2,0);TIM_Cmd(TIM2, ENABLE);
}/*** @brief 单位时间读取编码器计数* @param TIMX 定时器* @retval 速度值	是编码器返回的脉冲*/
int Read_Encoder()
{int Encoder_TIM;Encoder_TIM= (short)TIM2 -> CNT;//Encoder_TIM= (int)((int16_t)(TIM4->CNT));;TIM2 -> CNT=0;return Encoder_TIM;
}

encoder.h

#ifndef __ENCODER_H
#define __ENCODER_H#include "sys.h"void Encoder_Init_TIM2(uint16_t psc,uint16_t arr);
int Read_Encoder();#endif

5、测速方法

在一个时间周期T0内,定时的读取编码器产生的脉冲,以我的编码器为例(11线,减速比30),转一圈会产生1320个脉冲(因为采用的是编码模式3)
这个1320 = 11 * 30 * 4

通过在固定的周期T0内,产生的脉冲就相当于路程,而这个固定的周期就相当于时间

所以速度就等于 在T0这段时间获取到的脉冲总数/(编码器单圈产生的总脉冲数*T0)

对于我的电机就是

T0这段时间获取到的脉冲总数/(1320*T0)

六、相关问题以及解答

在看了前面之后,应该对编码器模式和编码器测速有了一个大概的认识,知道了它测速的原理,但肯定有好多疑问,我把我学习过程中遇到的问题和解决方法做一个总结,你肯定也有这些疑问,不要着急,看下去。

1、编码器模式下的自动重装值ARR和预分频PSC应该如何设置

ARR,自动重装值,指的是CNT计数自增或自减到ARR就会溢出,(可以产生中断),然后继续从0开始计数。

PSC,预分频系数,(前面不是说过编码器相当于一个外部时钟吗),PSC相当于外部时钟的频率,如果分频(假设PSC=2)的话,就会(比如电机转一圈产生100个脉冲),此时编码器模式下只能计数50个脉冲。

所以我们应该如何设置?

PSC呢? PSC没有必要设置,因为我要计数的本来就是电机转动一圈产生的真实脉冲,所以PSC给0就好啦

ARR呢? 目前在各种论坛和博客和资料中有两种版本。

第一种,根据电机的线数和减速比来设置,比如我的电机是11线,减速比30,转动一圈的脉冲数是1320,这个值就可以设置为1320。

产生的脉冲数恰好是你定时器溢出的时候,溢出一次记录一次,这个的次数就是电机的圈数(当然这种误差很大)

也就是说电机转一圈正好是1320,当CNT计数到ARR时,计数器就会清零并且重新计数,所以这个ARR就是电机转一圈产生的脉冲数的最大值。

第二种,直接设置成定时器ARR的最大值,也就是65535(2^16-1),这样设置的目的就是无论你电机产生多少脉冲,都可以记录,且不会溢出。

不过使用65535的话,就要在最开始的时候初始化编码器模式提前把CNT清零,然后再开始计数。再在一个周期内定时读取脉冲数,再清零,这个脉冲也是周期内读取到的脉冲值。

电机旋转一圈能产生脉冲,那么我们就能记录一段时间产生的脉冲数来计算速度

2、如何判断正反转

可以通过判断CR1寄存器中的DIR位,这个位是计数方向位

在这里插入图片描述

正转就是CNT向上计数(DIR==0)

反转就是CNT向下计数(DIR==1)

3、圈数如何计算

就是上方说的,把ARR设置为电机旋转一周产生的脉冲数

电机转一圈,CNT达到ARR,溢出,进中断,设置一个变量++(正转),–(反转)

4、转速如何计算

规定某个某个时钟周期内,读取有多少脉冲,从而计算转速

这里采用的是M法测速,测出的是电机是多少转/s

脉冲相当于路程,某个时钟周期相当于时间

这个上方有描述,可以往上翻翻

5、为什么我的编码器没有输出,获取到的脉冲数是0

检查一下接线,从硬件开始,一步一步排查,对应的引脚是否正确

检查电源,编码器的电源是否打开,相应的PWM波是否有效

硬件确认没有错误,检查软件,编码器接口是否打开,PWM模式是否输出,电机IN引脚是否配置

七、测速硬件展示及测速现象

硬件展示
在这里插入图片描述
测速展示
可以看到当转速为1的时候,产生的脉冲是66-68,而我设置的闸门时间是50ms,结合电机转一圈是1320个脉冲,也就是说测量的脉冲数几乎正确。

(66*2=132) 和编码器的线数完全吻合,测速成功!!!
在这里插入图片描述

八、总结

这个编码器花费了我几乎四天的时间,也可能是自己比较小白,不懂得如何通过电机转一圈产生的脉冲数来计算速度,第一天就实现了读取脉冲

但是后面几天执着于测速,没有采取正确的方法,导致自己无线内耗,浪费了大量时间。

由于网上资料繁杂,找不到自己想要的,浪费了很多时间,很多只是一笔带过,没有系统的讲解原理和方法,我也不知道自己这篇文章是否正解

所以将这个学习总结分享给大家

当然,这都是在借鉴了前人的肩膀下,谢谢各位大佬和优秀的文章,我会在下方贴出自己觉得值得一看大佬们的链接,大家可以一看

欢迎大家指错,看到了就会修改,大家一起共同进步

九、大家可以参考

参考链接1

带霍尔传感器编码器的直流减速电机测速原理讲解(附源码)-OpenEdv-开源电子网

参考链接2

编码器分类及原理和测速应用(含代码) - 古月居

参考链接3

stm32平衡小车(2)-----编码器电机驱动

参考链接4

带编码器的直流减速电机——基于STM32F407_编码器直流减速电机磁极数目_谁还不是个程序猿的博客

谢谢各位大佬的文章,让我受益匪浅,站在前人的肩膀下才能看的更远

相关文章:

Stm32-使用TB6612驱动电机及编码器测速

这里写目录标题起因一、电机及编码器的参数二、硬件三、接线四、驱动电机1、TB6612电机驱动2、定时器的PWM模式驱动电机五、编码器测速1、定时器的编码器接口模式2、定时器编码器模式测速的原理3、编码器模式的配置4、编码器模式相关代码5、测速方法六、相关问题以及解答1、编码…...

【JS】常用js方法

1、判断是否是数组、字符串等方法a instanceof ba是你需要判断的数据b是判断的类型//直接判断原型 var a [1,5,8] var b 123456console.log(a instanceof Array)//true console.log(a instanceof String)//falseconsole.log(b instanceof String)//true2、分割字符串a.split(…...

Android---动态权限申请

目录 权限分类 动态权限核心函数 简易实现案例 完整代码 Google 在 Android 6.0 开始引入了权限申请机制,将所有权限分成了正常权限和危险权限。App 每次在使用危险权限时需要动态的申请并得到用户的授权才能使用。 权限分类 系统权限分为两类:正常…...

【Linux】环境变量(基本概念 常见环境变量 测试PATH 环境变量相关命令)

文章目录环境变量基本概念常见环境变量测试PATH别的环境变量通过系统调用获取或设置环境变量环境变量相关命令export: 设置一个新的环境变量set: 显示本地定义的shell变量和环境变量unset: 清除环境变量通过代码如何获取环境变量环境变量 基本概念 环境变量(environment vari…...

安全牛+瑞数信息:《数据安全管控平台应用指南》报告共同发布

随着《中华人民共和国网络安全法》《中华人民共和国数据安全法》《中华人民共和国个人信息保护法》和《关键信息基础设施安全保护条例》“三法一条例”的陆续发布,从国家、社会与个人已经逐步形成了加强数据安全保护的态势。 2023年1月中旬,工业和信息化…...

【洛谷刷题】蓝桥杯专题突破-深度优先搜索-dfs(6)

目录 写在前面: 题目:P1683 入门 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述: 输入格式: 输出格式: 输入样例: 输出样例: 解题思路: 代码: AC &a…...

论文解读TCPN

一、简要介绍视觉信息提取(VIE)近年来受到了越来越多的关注。现有的方法通常首先将光学字符识别(OCR)结果组织成纯文本,然后利用标记级实体注释作为监督来训练序列标记模型。但是,它花费大量的注释成本&…...

性能优化之防抖与节流

(一)防抖 (1)定义:单位事件内,频繁触发,只执行最后一次(像王者荣耀的回城操作) (2)使用场景:搜索输入框、手机号邮箱输入检测 &…...

数组模拟单链表

实现一个单链表,链表初始为空,支持三种操作: 向链表头插入一个数; 删除第 k个插入的数后面的数; 在第 k个插入的数后插入一个数。 现在要对该链表进行 M次操作,进行完所有操作后,从头到尾输出整…...

蓝桥杯刷题第十四天

第二题:不同子串题目描述本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。一个字符串的非空子串是指字符串中长度至少为 1 的连续的一段字符组成的串。例如,字符串aaab 有非空子串 a, b, aa, ab, aaa, aa…...

面试了8家软件公司测试岗位,面试题大盘点,我真的尽力了

包含的模块:本文分为十九个模块,分别是:软件测试 基础、liunx、MySQL、web测试、接口测试、APP测试 、管理工具、Python、性能测试、selenium、lordrunner、计算机网络、组成原理、数据结构与算法、逻辑题、人力资源需要的可以看文末获取方式…...

Activiti 工作流简介

1、什么是工作流 工作流(Workflow),就是通过计算机对业务流程自动化执行管理。它主要解决的是“使在多个参与者之间按照某种预定义的规则自动进行传递文档、信息或任务的过程,从而实现某个预期的业务目标,或者促使此目标的实现”。 1.2、工作…...

【华为机试真题详解 Python实现】统计差异值大于相似值二元组个数【2023 Q1 | 100分】

文章目录 前言题目描述输入描述输出描述题目解析参考代码前言 《华为机试真题详解》专栏含牛客网华为专栏、华为面经试题、华为OD机试真题。 如果您在准备华为的面试,期间有想了解的可以私信我,我会尽可能帮您解答,也可以给您一些建议! 本文解法非最优解(即非性能最优)…...

【C++】Google编码风格学习

Google规范线上地址:https://zh-google-styleguide.readthedocs.io/en/latest/ 文章目录1. 头文件2. 作用域3. 类4. 函数5. 其他C特性6. 命名约定7. 注释8. 格式1. 头文件 每个cpp/cc文件都对应一个h头文件,除单元测试代码和只包含main()的文件外。 所…...

JavaScript 中的Promise 函数

JavaScript 中的Promise 函数 目录JavaScript 中的Promise 函数1 创建Promise2 Promise的方法3 Promises的状态4 Promise的使用5 返回 Promise 类型6 Promise级联使用在现在的前端开发中我们常常会使用到 JavaScript Promise 函数,但是很多人都不能正确理解Promise …...

学校教的Python,找工作没企业要,太崩溃了【大四真实求职经历】

如果只靠学校学的东西去找工作,能找到工作吗? 今天给大家看一个粉丝的真实求职案例,想做Python方面的工作,投了二十几个简历却没人要,心态崩了。为什么没人要?我来告诉你答案。 然后我还会结合我的这些年的…...

快看!这只猫两次登上 Github Trending !!!

前几天我在逛 Github Trending,无意间发现这个Postcat 登上榜单 !好奇心驱使我去了解这个 Postcat。近期它上新了几个有意思的插件,其中 ChatGPT 插件,用户可以直接省去复杂的流程,直接体验 ChatGPT,懂的都懂&#xff…...

Linux->文件系统初识

目录 前言: 1 认识文件 2 文件使用 2.1 文件加载 2.2 外设文件使用 3 文件接口和文件描述符 3.1 文件系统调用接口 open: 3.2 文件描述符 4 缓冲区 前言: 在大家看这篇文章之前,我得提出几个问题: 1. 我们有多…...

InfluxDB和IotDB介绍与性能对比

InfluxDB简介 InfluxDB 是用Go语言编写的一个开源分布式时序、事件和指标数据库,无需外部依赖。用于存储和分析时间序列数据的开源数据库。 适合存储设备性能、日志、物联网传感器等带时间戳的数据,其设计目标是实现分布式和水平伸缩扩展。 InfluxDB 包括用于存储和…...

计算机体系结构(校验码+总线)

校验码计算机系统运行时,为了确保数据在传送过程中正确无误,一是提高硬件电路的可靠性;二就是是提高代码的校验能力,包括查错和纠错。通常使用校验码的方法检测传送的数据是否出错。这里的校验码主要是指循环冗余校验码&#xff0…...

JavaWeb《三》Request请求转发与Response响应

🍎道阻且长,行则将至。🍓 本文是javaweb的第三篇,介绍了Request请求转发与Response响应。 上一篇:JavaWeb《二》Servlet、Request请求 下一篇:敬请期待 目录一、Request请求转发🍏二、Response对…...

断言assert

assert作用&#xff1a;我们使用assert这个宏来调试代码语法&#xff1a;assert&#xff08;bool表达式&#xff09;如果表达式为false&#xff0c;会调用std::cout<<abort函数&#xff0c;弹出对话框&#xff0c;#include<iostream> #include<cassert> void…...

【Java项目】完善基于Java+MySQL+Tomcat+maven+Servlet的博客系统

目录一、准备工作二、引入依赖三、创建必要的目录四、编写代码五/六、打包部署(直接基于 smart tomcat)七、验证代码正式编写服务器代码编写数据库相关的操作代码创建数据库/表结构(数据库设计)数据库代码封装数据库操作封装针对数据的增删改查&#xff01;博客列表页约定前后端…...

详解结构体内存对齐

目录 前言 一、内存大小的计算 1.规则 2.练习 二、为什么要有内存对齐 1.移植原因 2.性能原因 三、修改默认对齐数 总结 前言 本文针对结构体大小的计算进行深度剖析。结构体的大小要遵守内存对齐&#xff0c;在绝大数情况下&#xff0c;会浪费空间。但是有其的价值&…...

指针:程序员的望远镜

指针&#xff1a;程序员的望远镜一、什么是指针1.1 指针的定义1.2 指针和普通变量的区别1.3 指针的作用1.4 指针的优点和缺点二、指针的基本操作2.1 取地址运算符"&"2.2 指针的声明与定义2.3 指针的初始化2.4 指针的解引用2.5 指针的赋值2.6 指针的运算2.7 指针的…...

【python实现学生选课系统】

一、要求&#xff1a; 选课系统 管理员&#xff1a; 创建老师&#xff1a;姓名、性别、年龄、资产 创建课程&#xff1a;课程名称、上课时间、课时费、关联老师 使用pickle保存在文件 学生&#xff1a; 学生&#xff1a;用户名、密码、性别、年龄、选课列表[]、上课记录{课程…...

备受青睐的4D毫米波成像雷达,何以助力高阶自动驾驶落地?

近日&#xff0c;海外媒体曝出特斯拉已向欧洲监管机构提交车辆变更申请&#xff0c;并猜测特斯拉最新的自动驾驶硬件HW4.0或将很快量产上车。据爆料&#xff0c;HW4.0最大的变化是马斯克放弃的毫米波雷达又加了回来&#xff0c;根据国外知名博主Greentheonly的拆解分析&#xf…...

3.20算法题(一) LeetCode 合并两个有序数组

题目链接&#xff1a;算法面试题汇总 - LeetBook - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台 题目描述&#xff1a;给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元…...

QT | 编写一个简单的上位机

QT | 编写一个简单的上位机 时间&#xff1a;2023-03-19 参考&#xff1a; 1.易懂 | 手把手教你编写你的第一个上位机 2.QT中修改窗口的标题和图标 3.图标下载 1.打开QT Creator 2.新建工程 Qt Creator 可以创建多种项目&#xff0c;在最左侧的列表框中单击“Application”&am…...

DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(2/5)

目录3、IBL 数学原理3.1、基于微平面理论的 “Cook-Torrance” 模型回顾3.2、 ksk_sks​ 项与菲涅尔项等价消除3.3、拆分“漫反射项”和“镜面反射项”3、IBL 数学原理 接下来&#xff0c;就让我们正式进入整个 IBL 的数学原理的旅程。请注意&#xff0c;前方高能&#xff01; …...