MSP432自主开发笔记6:定时器多通道捕获多条编码器线脉冲数

所用开发板:MSP432P401R

今日在此更新一下编码器测速的定时器捕获写法,之前学习时竟然忘记更新了~~

本文讲如何用定时器的通道来 捕获编码器的脉冲信号数量,不提供速度路程的计算方式,

文章提供源码,测试工程下载;

实践内容:

1.使用定时器TA2捕获四个轮子编码器的信号

2.上升下降沿都捕获

3.串口定时反馈捕获值

程序编写:

程序设计方面十分简单,分为以下步骤,每个步骤有一些注意点:

一、初始化定时器:

            1.关闭定时溢出中断,开启捕获事件的中断

            2.选择合适的定时器频率,略高于编码器最大频率即可

            3.四个通道除了引脚不同,初始化基本一样,结构体名称改改就行

            4.设置为上升沿、下降沿、上升下降沿,三种捕获模式之一,(本文设置为上升下降都捕获    )

二、捕获事件中断服务函数:

            1.因为之前关闭了 定时溢出中断,所以void TA2_N_IRQHandler(void)的进入条件只有捕获事件到来时:(本文捕获事件为:上升下降都是捕获事件    ),就会进一次中断

             2.定时器配置捕获后,可以通过读取TAxIV寄存器来判断是哪个通道传来的捕获事件,借此对其计数。(本文是定时器2,因此读取TA2IV)

             3.     

 有关TAxIV寄存器介绍在801页

 1.初始化定时器TA2四条通道的捕获:

注意点在之前说过了:

开启定时器计时,但关闭计时溢出中断

选择合适的计时溢出频率,这决定了捕获的采样率,比编码器脉冲频率快就行,当然,直接定时器48M也是没有问题的

四条通道初始化相同的

开启TA2端口中断     MAP_Interrupt_enableInterrupt(INT_TA2_N);

//定时器TA2捕获初始化:
void TA2_CAP_init(void)
{//四个通道初始化输入MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN6,GPIO_PRIMARY_MODULE_FUNCTION);	MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN7,GPIO_PRIMARY_MODULE_FUNCTION);	MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,GPIO_PIN6,GPIO_PRIMARY_MODULE_FUNCTION);	MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,GPIO_PIN7,GPIO_PRIMARY_MODULE_FUNCTION);	//定时器连续计数模式初始化,关闭定时溢出中断const Timer_A_ContinuousModeConfig continuousModeConfig ={TIMER_A_CLOCKSOURCE_SMCLK,TIMER_A_CLOCKSOURCE_DIVIDER_1,  //1分频,分辨率最高48MTIMER_A_TAIE_INTERRUPT_DISABLE, TIMER_A_SKIP_CLEAR};
//初始化通道1:const Timer_A_CaptureModeConfig captureModeConfig_1 ={TIMER_A_CAPTURECOMPARE_REGISTER_1, TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE,TIMER_A_CAPTURE_INPUTSELECT_CCIxA,TIMER_A_CAPTURE_SYNCHRONOUS,TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE,TIMER_A_OUTPUTMODE_OUTBITVALUE};
//初始化通道2:const Timer_A_CaptureModeConfig captureModeConfig_2 ={TIMER_A_CAPTURECOMPARE_REGISTER_2, TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE,TIMER_A_CAPTURE_INPUTSELECT_CCIxA,TIMER_A_CAPTURE_SYNCHRONOUS,TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE,TIMER_A_OUTPUTMODE_OUTBITVALUE};
//初始化通道3:const Timer_A_CaptureModeConfig captureModeConfig_3 ={TIMER_A_CAPTURECOMPARE_REGISTER_3, TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE,TIMER_A_CAPTURE_INPUTSELECT_CCIxA,TIMER_A_CAPTURE_SYNCHRONOUS,TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE,TIMER_A_OUTPUTMODE_OUTBITVALUE};
//初始化通道4:const Timer_A_CaptureModeConfig captureModeConfig_4 ={TIMER_A_CAPTURECOMPARE_REGISTER_4, TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE,TIMER_A_CAPTURE_INPUTSELECT_CCIxA,TIMER_A_CAPTURE_SYNCHRONOUS,TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE,TIMER_A_OUTPUTMODE_OUTBITVALUE};		MAP_Timer_A_initCapture(TIMER_A2_BASE, &captureModeConfig_1);MAP_Timer_A_initCapture(TIMER_A2_BASE, &captureModeConfig_2);MAP_Timer_A_initCapture(TIMER_A2_BASE, &captureModeConfig_3);MAP_Timer_A_initCapture(TIMER_A2_BASE, &captureModeConfig_4);MAP_Timer_A_configureContinuousMode(TIMER_A2_BASE, &continuousModeConfig);MAP_Interrupt_enableInterrupt(INT_TA2_N);MAP_Timer_A_startCounter(TIMER_A2_BASE, TIMER_A_CONTINUOUS_MODE);
}

 2.编写定时器 中断服务函数:

代码中的 Wheel[x].CAPTURE 无须在意,是我给每个轮子定义的结构体,换成普通变量一样用的,这种高速计数脉冲,需要大家时刻注意溢出问题,以下代码段的意思就是防止数据溢出不被记录:

if(Wheel[1].CAPTURE==62700){Wheel[1].CAPTURE=0;Wheel[1].CAT_OUT_TIME++;}

 


//这是捕获事件中断服务函数(因为定时器溢出中断已关闭)
//注意对照引脚看通道,这里通道情况与PWM控制不一样
void TA2_N_IRQHandler(void)
{uint16_t captureSource = TA2IV;
// 根据捕获通道来源进行适当的处理
//脉冲计数到62700时刚好车轮转95圈
//大电机减速比30编码器11线switch (captureSource) {case 0x02:// 处理TA2 CCR1通道的捕获中断Wheel[1].CAPTURE++;if(Wheel[1].CAPTURE==62700){Wheel[1].CAPTURE=0;Wheel[1].CAT_OUT_TIME++;}break;case 0x04:// 处理TA2 CCR2通道的捕获中断Wheel[2].CAPTURE++;if(Wheel[2].CAPTURE==62700){Wheel[2].CAPTURE=0;Wheel[2].CAT_OUT_TIME++;}		break;case 0x06:// 处理TA2 CCR3通道的捕获中断Wheel[3].CAPTURE++;if(Wheel[3].CAPTURE==62700){Wheel[3].CAPTURE=0;Wheel[3].CAT_OUT_TIME++;}					break;case 0x08:// 处理TA2 CCR4通道的捕获中断Wheel[4].CAPTURE++;if(Wheel[4].CAPTURE==62700){Wheel[4].CAPTURE=0;Wheel[4].CAT_OUT_TIME++;}					break;default: break;	
}
}			

3.32定时器初始化为1s周期,通过串口反馈捕获情况:

//此句放在初始化,主函数开头,初始化32定时器为1s周期Tim32_0_Int_Init(47999999,1);//32定时器初始化函数,传入的aar psc决定了其周期
void Tim32_0_Int_Init(uint32_t aar, uint8_t psc)
{MAP_Timer32_initModule(TIMER32_0_BASE, psc, TIMER32_32BIT, TIMER32_PERIODIC_MODE);MAP_Timer32_setCount(TIMER32_0_BASE, aar);MAP_Timer32_enableInterrupt(TIMER32_0_BASE);MAP_Timer32_startTimer(TIMER32_0_BASE, false); //连续计数模式 falseMAP_Interrupt_enableInterrupt(INT_T32_INT1);
}/* Timer32 ISR 中断服务函数,1s进一次*/
void T32_INT1_IRQHandler(void)
{MAP_Timer32_clearInterruptFlag(TIMER32_0_BASE);printf("W1_CAP=%d\r\n",Wheel[1].CAPTURE);printf("W2_CAP=%d\r\n",Wheel[2].CAPTURE);printf("W3_CAP=%d\r\n",Wheel[3].CAPTURE);printf("W4_CAP=%d\r\n",Wheel[4].CAPTURE);
}

整体代码:

#include "main.h"//单个车轮状态与参数结构体:
Wheel_dat Wheel[5];int main(void)
{inint_all();   //初始化所有模块while (1){  }
}/* Timer32 ISR */
void T32_INT1_IRQHandler(void)
{MAP_Timer32_clearInterruptFlag(TIMER32_0_BASE);printf("W1_CAP=%d\r\n",Wheel[1].CAPTURE);printf("W2_CAP=%d\r\n",Wheel[2].CAPTURE);printf("W3_CAP=%d\r\n",Wheel[3].CAPTURE);printf("W4_CAP=%d\r\n",Wheel[4].CAPTURE);
}//初始化所有模块
void inint_all(void)
{SysInit();                                  //时钟配置    delay_init();								 								//delay_ms函数配置uart_init(115200);	TA2_CAP_init();Tim32_0_Int_Init(47999999,1);printf("Hello,MSP432!\r\n");								//串口打印测试字符MAP_Interrupt_enableMaster();               // 开启总中断
}//串口0服务函数
//串口0接收命令,存在数组中
void EUSCIA0_IRQHandler(void)
{uint32_t status = UART_getEnabledInterruptStatus(EUSCI_A0_BASE);if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)      //接收中断{USART0_save[USART0_xb++]=MAP_UART_receiveData(EUSCI_A0_BASE);if(USART0_xb== 20){USART0_xb=0;	}							      //下标最大不超过20if(USART0_save[USART0_xb-1]=='\0'){USART0_flag=1;}  //命令以\0结尾}
}//这是捕获事件中断服务函数(因为定时器溢出中断已关闭)
//注意对照引脚看通道,这里通道情况与PWM控制不一样
void TA2_N_IRQHandler(void)
{uint16_t captureSource = TA2IV;
// 根据捕获通道来源进行适当的处理
//脉冲计数到62700时刚好车轮转95圈
//大电机减速比30编码器11线switch (captureSource) {case 0x02:// 处理TA2 CCR1通道的捕获中断Wheel[1].CAPTURE++;if(Wheel[1].CAPTURE==62700){Wheel[1].CAPTURE=0;Wheel[1].CAT_OUT_TIME++;}break;case 0x04:// 处理TA2 CCR2通道的捕获中断Wheel[2].CAPTURE++;if(Wheel[2].CAPTURE==62700){Wheel[2].CAPTURE=0;Wheel[2].CAT_OUT_TIME++;}		break;case 0x06:// 处理TA2 CCR3通道的捕获中断Wheel[3].CAPTURE++;if(Wheel[3].CAPTURE==62700){Wheel[3].CAPTURE=0;Wheel[3].CAT_OUT_TIME++;}					break;case 0x08:// 处理TA2 CCR4通道的捕获中断Wheel[4].CAPTURE++;if(Wheel[4].CAPTURE==62700){Wheel[4].CAPTURE=0;Wheel[4].CAT_OUT_TIME++;}					break;default: break;	
}
}			//定时器TA2捕获初始化:
void TA2_CAP_init(void)
{//四个通道初始化输入MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN6,GPIO_PRIMARY_MODULE_FUNCTION);	MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN7,GPIO_PRIMARY_MODULE_FUNCTION);	MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,GPIO_PIN6,GPIO_PRIMARY_MODULE_FUNCTION);	MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,GPIO_PIN7,GPIO_PRIMARY_MODULE_FUNCTION);	//定时器连续计数模式初始化,关闭定时溢出中断const Timer_A_ContinuousModeConfig continuousModeConfig ={TIMER_A_CLOCKSOURCE_SMCLK,TIMER_A_CLOCKSOURCE_DIVIDER_1,  //1分频,分辨率最高48MTIMER_A_TAIE_INTERRUPT_DISABLE, TIMER_A_SKIP_CLEAR};
//初始化通道1:const Timer_A_CaptureModeConfig captureModeConfig_1 ={TIMER_A_CAPTURECOMPARE_REGISTER_1, TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE,TIMER_A_CAPTURE_INPUTSELECT_CCIxA,TIMER_A_CAPTURE_SYNCHRONOUS,TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE,TIMER_A_OUTPUTMODE_OUTBITVALUE};
//初始化通道2:const Timer_A_CaptureModeConfig captureModeConfig_2 ={TIMER_A_CAPTURECOMPARE_REGISTER_2, TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE,TIMER_A_CAPTURE_INPUTSELECT_CCIxA,TIMER_A_CAPTURE_SYNCHRONOUS,TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE,TIMER_A_OUTPUTMODE_OUTBITVALUE};
//初始化通道3:const Timer_A_CaptureModeConfig captureModeConfig_3 ={TIMER_A_CAPTURECOMPARE_REGISTER_3, TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE,TIMER_A_CAPTURE_INPUTSELECT_CCIxA,TIMER_A_CAPTURE_SYNCHRONOUS,TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE,TIMER_A_OUTPUTMODE_OUTBITVALUE};
//初始化通道4:const Timer_A_CaptureModeConfig captureModeConfig_4 ={TIMER_A_CAPTURECOMPARE_REGISTER_4, TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE,TIMER_A_CAPTURE_INPUTSELECT_CCIxA,TIMER_A_CAPTURE_SYNCHRONOUS,TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE,TIMER_A_OUTPUTMODE_OUTBITVALUE};		MAP_Timer_A_initCapture(TIMER_A2_BASE, &captureModeConfig_1);MAP_Timer_A_initCapture(TIMER_A2_BASE, &captureModeConfig_2);MAP_Timer_A_initCapture(TIMER_A2_BASE, &captureModeConfig_3);MAP_Timer_A_initCapture(TIMER_A2_BASE, &captureModeConfig_4);MAP_Timer_A_configureContinuousMode(TIMER_A2_BASE, &continuousModeConfig);MAP_Interrupt_enableInterrupt(INT_TA2_N);MAP_Timer_A_startCounter(TIMER_A2_BASE, TIMER_A_CONTINUOUS_MODE);
}
#ifndef _main_h_
#define _main_h_#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include "string.h"				   	//C标准库、字符串处理库
#include "sysinit.h"			   	//时钟配置
#include "delay.h"				   	//滴答定时器初始化(提供delay_ms延时)
#include "Public.h"
#include "DATA.h"//单个车轮状态与参数结构体:
typedef struct wheel_data
{uint16_t Sta;            //正反转状态,0不转,2正,1反uint16_t PWM_DIV;        //车轮电机占空比6 - 99uint32_t CAT_OUT_TIME;   //编码器 脉冲溢出次数,溢出一次就加一,记录有几个65530uint32_t CAPTURE;        //编码器 外部中断次数记录最大65530次脉冲,溢出后CAT_OUT_TIME会加一,CAPTURE归零uint32_t CAPTURE_LAST;   //上一次外部中断次数记录uint32_t CAPTURE_NEW;    //最新外部中断次数记录uint32_t DISTANCE;       //单轮行驶总路程长度单位cm,最大65535cmuint32_t SPEED;          //瞬时速度值存储,单位cm/s
}Wheel_dat;void inint_all(void);               //初始化所有模块
//定时器TA2捕获初始化:
void TA2_CAP_init(void);#endif

 测试工程下载:

https://download.csdn.net/download/qq_64257614/88214201?spm=1001.2014.3001.5503

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

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

相关文章

积木报表集成前端加载js文件404

项目场景&#xff1a; 在集成积木报表和shiro时候&#xff1a; 集成积木报表&#xff0c;shrio&#xff0c;shrio是定义在另一个模块下的&#xff0c;供另一个启动类使用&#xff0c;积木报表集成shrio的时候&#xff0c;需要依赖存放shrio的核心包&#xff0c;该核心包除了存…

android 如何分析应用的内存(十七)——使用MAT查看Android堆

android 如何分析应用的内存&#xff08;十七&#xff09;——使用MAT查看Android堆 前一篇文章&#xff0c;介绍了使用Android profiler中的memory profiler来查看Android的堆情况。 如Android 堆中有哪些对象&#xff0c;这些对象的引用情况是什么样子的。 可是我们依然面临…

【ArcGIS】经纬度数据转化成平面坐标数据

将点位置导入Gis中&#xff0c;如下&#xff08;经纬度表征位置&#xff09;&#xff1a; 如何利用Gis将其转化为平面坐标呢&#xff1f; Step1 坐标变换 坐标变换&#xff0c;打开ArcToolbox&#xff0c;找到“数据管理工具”->“投影和变换”->“要素”->“投影”…

MySQL—缓存

目录标题 为什么要有Buffer Poolbuffer pool有多大buffer pool缓存什么 如何管理Buffer Pool如何管理空闲页如何管理脏页如何提高缓存命中率预读失效buffer pool污染 脏页什么时候会被刷入到磁盘 为什么要有Buffer Pool 虽然说MySQL的数据是存储在磁盘中&#xff0c;但是也不能…

抖音关键词搜索小程序排名怎么做

抖音关键词搜索小程序排名怎么做 1 分钟教你制作一个抖音小程序。 抖音小程序就是我的视频&#xff0c;左下方这个蓝色的链接&#xff0c;点进去就是抖音小程序。 如果你有了这个小程序&#xff0c;发布视频的时候可以挂载这个小程序&#xff0c;直播的时候也可以挂载这个小…

Express 实战(一):概览

在正式学习 Express 内容之前&#xff0c;我们有必要从大的方面了解一下 Node.js 。 在很长的一段时间里&#xff0c;JavaScript 一门编写浏览器中运行脚本的语言。不过近些年&#xff0c;随着互联网的发展以及技术进步&#xff0c;JavaScript 迎来了一个集中爆发的时代。一个…

谷歌关闭跨域限制.(生成一个开发浏览器),Chrome关闭跨域

(一)、首先找到浏览器在电脑磁盘中的位置,并复制 (二)、复制一个浏览器的快捷方式到桌面(不影响正常浏览器) (三)、chrom鼠标右键属性&#xff0c;修改快捷方式的目标 &#xff08;四&#xff09;chrome.exe 后面添加 --disable-web-security --user-data-dir 复制的Chrome浏览…

JUC并发编程(JUC核心类、TimeUnit类、原子操作类、CASAQS)附带相关面试题

目录 1.JUC并发编程的核心类 2.TimeUnit&#xff08;时间单元&#xff09; 3.原子操作类 4.CAS 、AQS机制 1.JUC并发编程的核心类 虽然java中的多线程有效的提升了程序的效率&#xff0c;但是也引发了一系列可能发生的问题&#xff0c;比如死锁&#xff0c;公平性、资源管理…

【100天精通python】Day34:使用python操作数据库_ORM(SQLAlchemy)使用

目录 专栏导读 1 ORM 概述 2 SQLAlchemy 概述 3 ORM&#xff1a;SQLAlchemy使用 3.1 安装SQLAlchemy&#xff1a; 3.2 定义数据库模型类&#xff1a; 3.3 创建数据表&#xff1a; 3.4 插入数据&#xff1a; 3.5 查询数据&#xff1a; 3.6 更新数据&#xff1a; 3.7 删…

【Git】 git push origin master Everything up-to-date报错

hello&#xff0c;我是索奇&#xff0c;可以叫我小奇 git push 出错&#xff1f;显示 Everything up-to-date 那么看看你是否提交了message 下面是提交的简单流程 git add . git commit -m "message" git push origin master 大多数伙伴是没写git commit -m "…

AI自动驾驶

AI自动驾驶 一、自动驾驶的原理二、自动驾驶的分类三、自动驾驶的挑战四、自动驾驶的前景五、关键技术六、自动驾驶的安全问题七、AI数据与自动驾驶八、自动驾驶的AI算法总结 自动驾驶技术是近年来备受关注的热门话题。它代表了人工智能和机器学习在汽车行业的重要应用。本文将…

UML之四种事物

目录 结构事物 行为事物 分组事物&#xff1a; 注释事物 结构事物 1.类(Class) -类是对一组具有相同属性、方法、关系和语义的对象的描述。一个类实现一个或多个接口 2.接口(interface) -接口描述 了一个类或构件的一个服务的操作集。接口仅仅是定义了一组操作的规范&…

案例16 基于Spring Boot实现学生新增案例

基于Spring Boot实现学生新增。 1. 创建Spring Boot项目 创建Spring Boot项目&#xff0c;项目名称为case16-springboot-student01。 ​ 2. 设置项目信息 ​ 3. 选择依赖 选择Lombok ​ 选择Spring Web ​ 4. 设置项目名称 ​ 5. Maven依赖 <?xml version"1.0&qu…

Nature子刊 |肠道宏病毒组揭示百岁老人长寿秘诀

发表期刊&#xff1a;nature microbiology 发表时间&#xff1a;2023 影响因子&#xff1a;28.3 DOI: 10.1038/s41564-023-01370-6 研究背景 衰老是一种不可逆转的自然过程&#xff0c;随着年龄的增长&#xff0c;机体诸多方面出现功能性下降&#xff0c;与衰老相关的疾病&a…

生成式AI颠覆传统数据库的十种方式

对于生成式AI的所有闪光点&#xff0c;这个新时代最大的转变可能深埋在软件堆栈中。AI算法正在不易觉察地改变一个又一个数据库。他们正在用复杂、自适应且看似更直观的AI新功能颠覆传统数据库。 目录 1、向量和嵌入 2、查询模型 3、建议 4、索引范例 5、数据分类 6、更…

Unity 框架学习--1

由浅入深&#xff0c;慢慢演化实现框架 两个类的实现代码完全一样&#xff0c;就只有类名或类型不一样的时候&#xff0c;而且还需要不断扩展&#xff08;未来会增加各种事件&#xff09;的时候&#xff0c;这时候就用 泛型 继承 来提取&#xff0c;继承解决扩展的问题&#…

【RabbitMQ与SpringBoot集成测试收发消息】

【RabbitMQ与SpringBoot集成测试收发消息】 一、环境说明二、实验步骤三、小结 一、环境说明 安装环境&#xff1a;虚拟机VMWare Centos7.6 Maven3.6.3 JDK1.8RabbitMQ版本&#xff1a;rabbitmq-server-3.8.8-1.el7.noarch.rpm编程工具Idea 运行JDK为17 二、实验步骤 在Rab…

List和数组互转方法以及踩坑点

一、数组转List 1. 使用for循环逐个添加 String[] arr {"A", "B", "C"}; List<String> list new ArrayList<>(); for (String element : arr) {list.add(element); }2. 使用Arrays.asList(arr) String[] arr {"A", …

智能驾驶系列报告之一:智能驾驶 ChatGPT时刻有望来临

原创 | 文 BFT机器人 L3 功能加速落地&#xff0c;政策标准有望明确 L2 发展日益成熟&#xff0c;L3 功能加速落地。根据市场监管总局发布的《汽车驾驶自动化分级》与 SAE发布的自动驾驶分级标准&#xff0c;自动驾驶主要分为 6 个级别&#xff08;0 级到 5 级&#xff0c;L0 …

Tomcat多实例部署及nginx+tomcat的负载均衡和动静分离

Tomcat多实例部署 安装 jdk、tomcat&#xff08;流程可看之前博客&#xff09; 配置 tomcat 环境变量 [rootlocalhost ~]# vim /etc/profile.d/tomcat.sh#tomcat1 export CATALINA_HOME1/usr/local/tomcat/tomcat1 export CATALINA_BASE1/usr/local/tomcat/tomcat1 export T…