stm32单片机开发二、定时器-内部时钟中断和外部时钟中断、编码器

定时器本质就是一个计数器
在这里插入图片描述在这里插入图片描述在这里插入图片描述
案例:定时器定时中断
在这里插入图片描述

内部时钟中断

Timer_Init(); //定时中断初始化

/*** 函    数:定时中断初始化* 参    数:无* 返 回 值:无*/
void Timer_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//开启TIM2的时钟/*配置时钟源*/TIM_InternalClockConfig(TIM2);		//选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;		//时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	//计数器模式,选择向上计数//定时一秒TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;				//计数周期,即ARR的值  ,在10K的频率下计10000个数,就是1S的时间TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;				//预分频器,即PSC的值 ,这里是对72M进行7200分频,得到的就是10K的频率,在10K的频率下计10000个数,就是1S的时间TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;			//重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);				//将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元	/*中断输出配置*/TIM_ClearFlag(TIM2, TIM_FLAG_Update);						//清除定时器更新标志位//TIM_TimeBaseInit函数末尾,手动产生了更新事件//若不清除此标志位,则开启中断后,会立刻进入一次中断//如果不介意此问题,则不清除此标志位也可TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);					//开启TIM2的更新中断/*NVIC中断分组*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);				//配置NVIC为分组2//即抢占优先级范围:0~3,响应优先级范围:0~3//此分组配置在整个工程中仅需调用一次//若有多个中断,可以把此代码放在main函数内,while循环之前//若调用多次配置分组的代码,则后执行的配置会覆盖先执行的配置/*NVIC配置*/NVIC_InitTypeDef NVIC_InitStructure;						//定义结构体变量NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;				//选择配置NVIC的TIM2线NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//指定NVIC线路使能NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	//指定NVIC线路的抢占优先级为2NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			//指定NVIC线路的响应优先级为1NVIC_Init(&NVIC_InitStructure);								//将结构体变量交给NVIC_Init,配置NVIC外设/*TIM使能*/TIM_Cmd(TIM2, ENABLE);			//使能TIM2,定时器开始运行
}

在这里插入图片描述

/*** 函    数:TIM2中断函数* 参    数:无* 返 回 值:无* 注意事项:此函数为中断函数,无需调用,中断触发后自动执行*           函数名为预留的指定名称,可以从启动文件复制*           请确保函数名正确,不能有任何差异,否则中断函数将不能进入*/
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)		//判断是否是TIM2的更新事件触发的中断{Num ++;												//Num变量自增,用于测试定时中断TIM_ClearITPendingBit(TIM2, TIM_IT_Update);			//清除TIM2更新事件的中断标志位//中断标志位必须清除//否则中断将连续不断地触发,导致主程序卡死}
}
TIM_GetCounter(TIM2);   //获取当前TIM2计数器的值

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"uint16_t Num;			//定义在定时器中断里自增的变量int main(void)
{/*模块初始化*/OLED_Init();		//OLED初始化Timer_Init();		//定时中断初始化/*显示静态字符串*/OLED_ShowString(1, 1, "Num:");			//1行1列显示字符串Num:while (1){OLED_ShowNum(1, 5, Num, 5);			//不断刷新显示Num变量}
}/*** 函    数:TIM2中断函数* 参    数:无* 返 回 值:无* 注意事项:此函数为中断函数,无需调用,中断触发后自动执行*           函数名为预留的指定名称,可以从启动文件复制*           请确保函数名正确,不能有任何差异,否则中断函数将不能进入*/
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)		//判断是否是TIM2的更新事件触发的中断{Num ++;												//Num变量自增,用于测试定时中断TIM_ClearITPendingBit(TIM2, TIM_IT_Update);			//清除TIM2更新事件的中断标志位//中断标志位必须清除//否则中断将连续不断地触发,导致主程序卡死}
}

外部时钟中断

/*** 函    数:定时中断初始化* 参    数:无* 返 回 值:无* 注意事项:此函数配置为外部时钟,定时器相当于计数器*/
void Timer_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//开启TIM2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);						//将PA0引脚初始化为上拉输入/*外部时钟配置,这部分采用了外部时钟*/TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);//选择外部时钟模式2,时钟从TIM_ETR引脚输入//注意TIM2的ETR引脚固定为PA0,无法随意更改//最后一个滤波器参数加到最大0x0F,可滤除时钟信号抖动/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;		//时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	//计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;					//计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;				//预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;			//重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);				//将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元	/*中断输出配置*/TIM_ClearFlag(TIM2, TIM_FLAG_Update);						//清除定时器更新标志位//TIM_TimeBaseInit函数末尾,手动产生了更新事件//若不清除此标志位,则开启中断后,会立刻进入一次中断//如果不介意此问题,则不清除此标志位也可TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);					//开启TIM2的更新中断/*NVIC中断分组*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);				//配置NVIC为分组2//即抢占优先级范围:0~3,响应优先级范围:0~3//此分组配置在整个工程中仅需调用一次//若有多个中断,可以把此代码放在main函数内,while循环之前//若调用多次配置分组的代码,则后执行的配置会覆盖先执行的配置/*NVIC配置*/NVIC_InitTypeDef NVIC_InitStructure;						//定义结构体变量NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;				//选择配置NVIC的TIM2线NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//指定NVIC线路使能NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	//指定NVIC线路的抢占优先级为2NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			//指定NVIC线路的响应优先级为1NVIC_Init(&NVIC_InitStructure);								//将结构体变量交给NVIC_Init,配置NVIC外设/*TIM使能*/TIM_Cmd(TIM2, ENABLE);			//使能TIM2,定时器开始运行
}
/*** 函    数:返回定时器CNT的值* 参    数:无* 返 回 值:定时器CNT的值,范围:0~65535*/
uint16_t Timer_GetCounter(void)
{return TIM_GetCounter(TIM2);	//返回定时器TIM2的CNT
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"uint16_t Num;			//定义在定时器中断里自增的变量int main(void)
{/*模块初始化*/OLED_Init();		//OLED初始化Timer_Init();		//定时中断初始化/*显示静态字符串*/OLED_ShowString(1, 1, "Num:");			//1行1列显示字符串Num:OLED_ShowString(2, 1, "CNT:");			//2行1列显示字符串CNT:while (1){OLED_ShowNum(1, 5, Num, 5);			//不断刷新显示Num变量OLED_ShowNum(2, 5, Timer_GetCounter(), 5);		//不断刷新显示CNT的值}
}/*** 函    数:TIM2中断函数* 参    数:无* 返 回 值:无* 注意事项:此函数为中断函数,无需调用,中断触发后自动执行*           函数名为预留的指定名称,可以从启动文件复制*           请确保函数名正确,不能有任何差异,否则中断函数将不能进入*/
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)		//判断是否是TIM2的更新事件触发的中断{Num ++;												//Num变量自增,用于测试定时中断TIM_ClearITPendingBit(TIM2, TIM_IT_Update);			//清除TIM2更新事件的中断标志位//中断标志位必须清除//否则中断将连续不断地触发,导致主程序卡死}
}

编码器

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

/*** 函    数:定时中断初始化* 参    数:无* 返 回 值:无*/
void Timer_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//开启TIM2的时钟/*配置时钟源*/TIM_InternalClockConfig(TIM2);		//选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;		//时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	//计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;				//计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;				//预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;			//重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);				//将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元	/*中断输出配置*/TIM_ClearFlag(TIM2, TIM_FLAG_Update);						//清除定时器更新标志位//TIM_TimeBaseInit函数末尾,手动产生了更新事件//若不清除此标志位,则开启中断后,会立刻进入一次中断//如果不介意此问题,则不清除此标志位也可TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);					//开启TIM2的更新中断/*NVIC中断分组*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);				//配置NVIC为分组2//即抢占优先级范围:0~3,响应优先级范围:0~3//此分组配置在整个工程中仅需调用一次//若有多个中断,可以把此代码放在main函数内,while循环之前//若调用多次配置分组的代码,则后执行的配置会覆盖先执行的配置/*NVIC配置*/NVIC_InitTypeDef NVIC_InitStructure;						//定义结构体变量NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;				//选择配置NVIC的TIM2线NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//指定NVIC线路使能NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	//指定NVIC线路的抢占优先级为2NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			//指定NVIC线路的响应优先级为1NVIC_Init(&NVIC_InitStructure);								//将结构体变量交给NVIC_Init,配置NVIC外设/*TIM使能*/TIM_Cmd(TIM2, ENABLE);			//使能TIM2,定时器开始运行
}
/*** 函    数:编码器初始化* 参    数:无* 返 回 值:无*/
void Encoder_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);			//开启TIM3的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);							//将PA6和PA7引脚初始化为上拉输入/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;               //计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;                //预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);             //将结构体变量交给TIM_TimeBaseInit,配置TIM3的时基单元/*输入捕获初始化*/TIM_ICInitTypeDef TIM_ICInitStructure;							//定义结构体变量TIM_ICStructInit(&TIM_ICInitStructure);							//结构体初始化,若结构体没有完整赋值//则最好执行此函数,给结构体所有成员都赋一个默认值//避免结构体初值不确定的问题TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;				//选择配置定时器通道1TIM_ICInitStructure.TIM_ICFilter = 0xF;							//输入滤波器参数,可以过滤信号抖动TIM_ICInit(TIM3, &TIM_ICInitStructure);							//将结构体变量交给TIM_ICInit,配置TIM3的输入捕获通道TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;				//选择配置定时器通道2TIM_ICInitStructure.TIM_ICFilter = 0xF;							//输入滤波器参数,可以过滤信号抖动TIM_ICInit(TIM3, &TIM_ICInitStructure);							//将结构体变量交给TIM_ICInit,配置TIM3的输入捕获通道/*编码器接口配置*/TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//配置编码器模式以及两个输入通道是否反相//注意此时参数的Rising和Falling已经不代表上升沿和下降沿了,而是代表是否反相//此函数必须在输入捕获初始化之后进行,否则输入捕获的配置会覆盖此函数的部分配置/*TIM使能*/TIM_Cmd(TIM3, ENABLE);			//使能TIM3,定时器开始运行
}/*** 函    数:获取编码器的增量值* 参    数:无* 返 回 值:自上此调用此函数后,编码器的增量值*/
int16_t Encoder_Get(void)
{/*使用Temp变量作为中继,目的是返回CNT后将其清零*/int16_t Temp;Temp = TIM_GetCounter(TIM3);TIM_SetCounter(TIM3, 0);return Temp;
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"
#include "Encoder.h"int16_t Speed;			//定义速度变量int main(void)
{/*模块初始化*/OLED_Init();		//OLED初始化Timer_Init();		//定时器初始化Encoder_Init();		//编码器初始化/*显示静态字符串*/OLED_ShowString(1, 1, "Speed:");		//1行1列显示字符串Speed:while (1){OLED_ShowSignedNum(1, 7, Speed, 5);	//不断刷新显示编码器测得的最新速度}
}/*** 函    数:TIM2中断函数* 参    数:无* 返 回 值:无* 注意事项:此函数为中断函数,无需调用,中断触发后自动执行*           函数名为预留的指定名称,可以从启动文件复制*           请确保函数名正确,不能有任何差异,否则中断函数将不能进入*/
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)		//判断是否是TIM2的更新事件触发的中断{Speed = Encoder_Get();								//每隔固定时间段读取一次编码器计数增量值,即为速度值TIM_ClearITPendingBit(TIM2, TIM_IT_Update);			//清除TIM2更新事件的中断标志位//中断标志位必须清除//否则中断将连续不断地触发,导致主程序卡死}
}

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

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

相关文章

纯血鸿蒙APP实战开发——Navigation实现多设备适配案例

介绍 在应用开发时,一个应用需要适配多终端的设备,使用Navigation的mode属性来实现一套代码,多终端适配。 效果图预览 使用说明 将程序运行在折叠屏手机或者平板上观看适配效果。 实现思路 本例涉及的关键特性和实现方案如下&#xff1a…

HTML5(2)

目录 一.列表、表格、表单 1.列表标签 2.表格 4.无语义的布局标签 5.字符实体 6.综合案例--1 7.综合案例--表单 一.列表、表格、表单 1.列表标签 1.1 无序列表 1.2 有序列表 1.3 定义列表 定义列表一般用于网页底部的帮助中心 2.表格 2.1 2.2 表格结构标签 shiftaltf 格…

创建基于时间的 UUID

概述 在本文中,我们将会 对 UUIDs 和基于时间的 UUIDs(time-based UUIDs) 进行一些探讨。 当我们在对基于时间的 UUIDs 进行选择的时候,总会遇到一些好的方面和不好的方面,如何进行选择,也是我们将要简要…

2路模拟音频光端机 JR-CA02

概述 JR-CA02光端机由发送机JR-CA02 Tansmitter和接收机JR-CA02 Receiver组成,通过一定距离长度的光纤相连接,传输2路Audio模拟音频(即1路立体声)。且每路音频分配输出。 JR-CA02光端机具有运行主要技术参数的监测功能&#xff…

【AGX】Ubuntu20.04 + ROS_ noetic+ 大疆Mid360激光 雷达评测

大家好,我是虎哥,最近组装机器人,使用到了大疆孵化的圳市览沃科技有限公司(简称Livox览沃科技)推出的觅道系列全新混合固态激光雷达Mid-360,顺便试试效果,也记录一下使用入门过程。 "觅道M…

MATLAB : interp1()用法介绍

目录 一、基本语法: 二、实例: 1.样条拟合减振器阻尼曲线 ​2.PP拟合时间温度曲线 interp1 是 MATLAB 中的一个函数,用于在一维数据上执行插值操作。这个函数可以帮助你估计或计算已知数据点之间未知点的值。以下是 interp1 函数的基本用…

分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测

分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测 目录 分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测(Matlab实…

MySQL——88张表汇总——DDL+外键

外键er图 88张表 /* Navicat MySQL Data TransferSource Server : MyList Source Server Version : 50726 Source Host : localhost:3309 Source Database : schooldbTarget Server Type : MYSQL Target Server Version : 50726 File Encoding …

《深入解析Windows操作系统》第3章读书笔记

1、陷阱分发:中断和异常是导致处理器转向正常控制流之外代码的两种操作系统条件。陷阱的定义如下:当异常或者中断发生时,处理器捕捉到一个执行线程,并且将控制权转移到操作系统中某一个固定地址处。在Windows系统中,处…

Pycharm:常用插件安装和使用

简介:好用的插件可以美化界面或者提升效率,使工作事半功倍。 推荐插件: 1、CSV插件:美化csv数据展示 2、Translation:翻译的插件,可以进行中英互译 3、CodeGlance:代码小地图 4、Markdown …

代码随想录:二叉树29-30

目录 701.二叉搜索树中的插入操作 题目 代码(迭代法走一边) 代码(递归法走一边) 450.删除二叉搜索树中的节点 题目 代码(递归法走一边) 701.二叉搜索树中的插入操作 题目 给定二叉搜索树&#xff…

【软考高项】二十七、范围管理6个过程

一、规划范围管理 1、定义、作用 定义:为了记录如何定义、确认和控制项目范围及产品范围,而创建范围管理计划的过程作用:在整个项目期间对如何管理范围提供指南和方向 2、输入 项目章程 项目管理计划:质量管理计划、项目生命周…

编程本源

文章目录 引言编程的本质工作与编程编程的未来 引言 知乎上有一个热门的问题,什么是人生的顶级享受? 看到这个问题我回想到了多年前,那个炎热的午后,我在学校的图书馆里,一边参照书籍,一边用着一部破旧的t…

使用STM32CubeMX对STM32F4的CAN1/2/3配置及接收中断开启

目录 1. CAN配置1.1引脚(STM32F413VGT6-LQFP100)1.2 时钟1.3 RCC配置1.4 CAN1配置1.5 CAN2配置1.6 CAN3配置1.7 输出设置 2. CAN代码2.1 CAN初始化2.2 CAN滤波器设置2.3 CAN使能2.4 激活中断2.5 CAN发送函数2.6 CAN回调函数2.7 main之后的代码 1. CAN配置…

【无监督+自然语言】 GPT,BERT, GPT-2,GPT-3 生成式预训练模型方法概述 (Generative Pre-Traning)

主要参考 【GPT,GPT-2,GPT-3 论文精读【李沐论文精读】-2022.03.04】 https://www.bilibili.com/video/BV1AF411b7xQ/ 大语言模型综述: https://blog.csdn.net/imwaters/article/details/137019747 GPT与chatgpt的关系 图源:L…

java多功能手机

随着科技的发展,手机的使用已经普及到每个家庭甚至个人,手机的属性越来越强大,功能也越来越多,因此人们在生活中越来越依赖于手机。 任务要求,使用所学知识编写一个手机属性及功能分析程序设计,测试各个手机…

JEECG/SpringBoot集成flowable流程框架

IDEA安装Flowable BPMN visualizer插件 pom.xml中引入flowable相关依赖 <dependency><groupId>org.flowable</groupId><artifactId>flowable-spring-boot-starter</artifactId><version>6.7.2</version></dependency><depe…

PHP 错误 Unparenthesized `a ? b : c ? d : e` is not supported

最近在一个新的服务器上测试一些老代码的时候得到了类似上面的错误&#xff1a; [Thu Apr 25 07:37:34.139768 2024] [php:error] [pid 691410] [client 192.168.1.229:57183] PHP Fatal error: Unparenthesized a ? b : c ? d : e is not supported. Use either (a ? b : …

Docker镜像和容器操作

目录 一.Docker镜像创建与操作 1. 搜索镜像 2. 获取镜像 3. 镜像加速下载 4. 查看镜像信息 5. 查看下载的镜像文件信息 ​编辑6. 查看下载到本地的所有镜像 7. 根据镜像的唯一标识ID号&#xff0c;获取镜像详细信息 8. 为本地的镜像添加新的标签 9. 删除镜像 10. 存入…

【Prometheus】了解你的Prometheus指标

简单Prometheus查询用于指标检查 作者&#xff1a;Michal Kazmierczak 来源&#xff1a;mkaz.me 基数是关键。 它很容易失控&#xff0c;就像任何组合爆炸的实例一样。 这&#xff0c;再加上90%的指标从未被访问过的说法&#xff0c;创造了一个值得探索的领域。 观察性云供应…