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

嵌入式计算器模块实现

嵌入式计算器模块规划

计算器混合算法解析
上面我们的算法理论已经完善, 我们只用给一个混合运算式, 计算器就可以帮助我们计算出结果.

但是存在一个痛点, 每次计算算式,都要重新编译程序, 所以我们想到了, 利用单片机, 读取用户输入的按键, 组成算式, 输入给机器, 这样我们就可以利用上面的算法, 再次计算出结果了.

大致流程如下:

image-20240624100125749

所以, 我们第一步做的,就是stm32利用矩阵按键识别键值

第二步,就是单片机把读取到的键值, 组合成算式

第三步,就是把算式传给算法,计算出结果

第四步, 就是把结果清零

拓展:第五步,可以把结果转换成语音播报

第一步: 矩阵按键,读取键值

(1)读取原理

首先我们要了解矩阵按键, 是干什么的, 顾名思义,矩阵按键,就是几行几列,依次排开的,按钮, 我们如果知道行,知道列,就可以锁定那个按键,所以我们只需要让单片机知道,我们按下的是哪一行,哪一列,那么单片机通过提前布局好的按键键值,就可以知道我们按下的是哪个按键了.

image-20240624101158298

(2)按键布局

如下图, 即为我们矩阵按键的键盘布局:

第一行 ( ) / *

第二行 1 2 3 +

第三行 4 5 6 -

第四行 7 8 9 Esc

第五行 ← 0 → =

image-20240624102450597

(3)按键原理图

矩阵按键原理图:

image-20240624103255572

(4)单片机io口识别原理

我们锁定行列, 此矩阵按键有五行,四列, 我们就先识别按下哪一列吧,然后后面再锁定行,这样就可以得到坐标了.

单说, 按下按键, 怎么io口怎么识别出按下按键呢?

举一个例子, 单片机io口,相当于装满水的水杯, 单片机会检测io口水杯, 是满的,还是空的. 用户按下按键,就相当于, 把水倒掉,那么我们就可以让单片机检测到按键.

image-20240624122114389

所以, 单片机检测io口,端口被称作输入口,顾名思义就是读取io口状态, 并把io口状态,反馈给单片机,那么水倒哪里了呢? 我们按下按键, 水就倒到了地下. 所以我们按键另一端按键接地是持续输出低电平的输出口.

<1>识别列

我们把上述的步骤, 复制四份, 我们就可以判断按下是哪一列了

image-20240624122801579

此时,四个列检测io口, 链接四个按键,按键另一端连接的是地, 这个地可以用io口输出低电平代替,方便后续矩阵键盘拓展.

image-20240624131512384

但是我们有四列, 五行, 所以, 每列都有,五个按钮, 我们紧接着, 再把他们排列起来.

image-20240624131141800

<2>识别行

此时, 我们通过判断 PA1,PA2,PA3,PA4那个io口变化了,就可以识别到是哪列按键按下了,

但是我们是矩阵按键,还要进行行的识别.

其实,识别方法同理,我们只需要把, io口类型进行反转,把列控制端口全反转成输出低电平, 现在检测io口状态的变成每行的端口,当按下第一行按钮时候,对应的端口就会变成低电平, 单片机检测到,就可以识别到行 如下图所示

image-20240624132339632

进行拓展后,就变成了矩阵按键,

image-20240624132534304

<3> 识别原理总结

我们识别原理就是,先赋予列检测io口,高电平,设置其端口类型为输入口,读取按键状态,按键另一端,是输出口,持续输出低电平.

当我们按下按键的时候, 输入口io口的高电平会通过按键,送到低电平,此时单片机检测到低电平, 就判定是哪一列的按键按下了.

此时列已经锁定了, 下面开始锁定行,此时按下仍然处于按下状态.

我们此时设置控制行的io口,为输入口,检测按键状态, 控制列的io口,设置为输出低电平,那么此时按键是按下状态, 对应的行io口,电平就会从高电平->低电平, 那么单片机就会检测到io口状态变化, 我们就可以锁定对应的行.

行和列已经锁定,那么我们通过计算就可以得到我们按下的是矩阵按键的哪一个按键了.

<4>代码实现

我们使用线性反转法的核心思想,就是锁定行和列的坐标, 通过反转io口类型,检测io口状态,根据按键按下的状态,进而锁定坐标.

为了更快的进入列的选择,我们把四列io口,全部设置成中断形式,对应的行io口,全部设置为推挽输出低电平, 四列io口的中断触发方式,设置成下降沿触发.

①锁定列

这样我们就可以很快的进行, 锁定列了;

配置 PA1 ,PA2, PA3, PA4 为下降沿触发中断

1.中断初始化
void Exti_key_config(void)
{//定义官方文档结构体EXTI_InitTypeDef   EXTI_InitStructure;GPIO_InitTypeDef   GPIO_InitStructure;NVIC_InitTypeDef   NVIC_InitStructure;//初始化//使能时钟 PA  AFIORCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);	//io口初始化, 设置//使能内部上拉GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	GPIO_Init(GPIOA, &GPIO_InitStructure);/* Connect EXTI1 line to PA1 pin */GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);/* Connect EXTI2 line to PA2 pin */GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);/* Connect EXTI3 line to PA3 pin */GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);/* Connect EXTI4 line to PA4 pin */GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);//中断端口的设置(外部中断线 1,2,3和4,  端口模式, 什么触发: 下降沿 , 开启等)/* Configure EXTI0 line */EXTI_InitStructure.EXTI_Line = EXTI_Line1 | EXTI_Line2 | EXTI_Line3 | EXTI_Line4;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);//下面配置中断优先级/* Configure EXTI1 interrupt */NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/* Configure EXTI2 interrupt */NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;NVIC_Init(&NVIC_InitStructure);/* Configure EXTI3 interrupt */NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;NVIC_Init(&NVIC_InitStructure);/* Configure EXTI4 interrupt */NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;NVIC_Init(&NVIC_InitStructure);
}	
2.触发中断

char key_number; // 1–4 (代表一到四列)

_Bool key_button_down; //代表按键按下

void EXTI1_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line1) != RESET){delay(0x20000);	//中断服务函数当中 , 是不能用大延时的,快进		快出/* Your code goes here */key_number = 1;key_button_down = 1;//中断服务函数当中 , 是不能用大延时的,快进		快出delay(0x20000);	EXTI_ClearITPendingBit(EXTI_Line1);}
}void EXTI2_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line2) != RESET){//中断服务函数当中 是不能用大延时的,快进		快出delay(0x20000);	/* Your code goes here */key_number = 2;key_button_down = 1;//中断服务函数当中 , 是不能用大延时的,快进快出delay(0x20000);	EXTI_ClearITPendingBit(EXTI_Line2);}
}void EXTI3_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line3) != RESET){//中断服务函数当中 , 是不能用大延时的,快进快出delay(0x20000);	/* Your code goes here */key_number = 3;key_button_down = 1;//中断服务函数当中 , 是不能用大延时的,快进快出delay(0x20000);	EXTI_ClearITPendingBit(EXTI_Line3);}
}void EXTI4_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line4) != RESET){//中断服务函数当中 , 是不能用大延时的,快进快出delay(0x20000);	/* Your code goes here */key_number = 4;key_button_down = 1;//中断服务函数当中 , 是不能用大延时的,快进快出delay(0x20000);	EXTI_ClearITPendingBit(EXTI_Line4);}
}
3.锁定列数值
extern char key_number;
extern char chose_column;//选中的列
void find_column(void)
{if(key_number == 1){chose_column = 1;}elseif(key_number == 2){chose_column = 2;}		elseif(key_number == 3){chose_column = 3;}elseif(key_number == 4){chose_column = 4;}	else{}		
}
②锁定行

此时列已经锁定, 我们把列io口,全变成输出低电平, 控制行的io口,变成输入口,高电平, 此时单片机检测io的变化,就可以检测到哪行按下了.

1.端口类型转换
/* 切换为推挽输出模式 GPIO_Mode_Out_PP*/
//下面进行判断是哪个行(对调模式)
//GPIOA, GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4
void exchange_Mode(void)
{GPIO_InitTypeDef   GPIO_InitStructure;//初始化//使能时钟 PA  AFIORCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);	//io口初始化, 设置//使能内部上拉GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	GPIO_Init(GPIOA, &GPIO_InitStructure);	/* 切换为下拉输入输入模式  GPIO_Mode_IPD *///GPIOA, GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7//GPIOB, GPIO_Pin_0 | GPIO_Pin_10	//io口初始化, 设置//使能内部上拉GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	GPIO_Init(GPIOA, &GPIO_InitStructure);	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	GPIO_Init(GPIOB, &GPIO_InitStructure);		}	

2.锁定行

电平反转, 类型反转,当检测到行io口电平变成低电平,就可以锁定行了

extern char chose_line;//选中的行
void find_line(void)	//行
{GPIO_SetBits(GPIOA, GPIO_Pin_1);GPIO_SetBits(GPIOA, GPIO_Pin_2);GPIO_SetBits(GPIOA, GPIO_Pin_3);GPIO_SetBits(GPIOA, GPIO_Pin_4);GPIO_ResetBits(GPIOA, GPIO_Pin_5);GPIO_ResetBits(GPIOA, GPIO_Pin_6);GPIO_ResetBits(GPIOA, GPIO_Pin_7);GPIO_ResetBits(GPIOB, GPIO_Pin_0);GPIO_ResetBits(GPIOB, GPIO_Pin_10);delay(0x20000);if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5) == SET){delay(0x20000);while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5) == SET);chose_line = 1;}elseif(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6) == SET){delay(0x20000);while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6) == SET);chose_line = 2;}elseif(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_7) == SET){delay(0x20000);while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_7) == SET);chose_line = 3;}elseif(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == SET){delay(0x20000);while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == SET);chose_line = 4;}elseif(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10) == SET){delay(0x20000);while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10) == SET);chose_line = 5;}	
}
③ 计算键值

//根据所在行列 ,计算出特定符号

char compute_sign(char lines,char columns)
{//算出特定需要char counter;char sign;counter = (lines-1)*4 + columns;
/* 行  1	2	3	4 (列)
1   (	)	/	*
2	1	2	3	+
3	4	5	6	-
4	7	8	9	Esc
5	<-	0	->	=*/	switch(counter){case 1:	sign = '(';break;case 2:sign = ')';break;case 3:sign = '/';break;case 4:sign = '*';break;case 5:sign = '1';break;case 6:sign = '2';break;case 7:sign = '3';break;case 8:sign = '+';break;case 9:sign = '4';break;case 10:sign = '5';break;case 11:sign = '6';break;case 12:sign = '-';break;		case 13:sign = '7';break;		case 14:sign = '8';break;		case 15:sign = '9';break;		case 16:sign = 'x';break;		case 17:sign = '<';break;		case 18:sign = '0';break;		case 19:sign = '>';break;		case 20:sign = '=';break;		default:sign = 0;break;		}return sign;
}
④ main函数调用展示键值
<1>软件初始化
void Software_Init(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//中断控制器分组设置OLED_Init();Delay_Init();
//	uart_init();//波特率115200uart1_init(115200);//线性反转第一波(等待按键按下)button_key_config();Exti_key_config();init_collect_data();//按键收集中缀式初始化
}
<2>按键展示在OLED上
//按键展示
void show_keyboard(void)
{int counter;//展示选中的数字OLED_ShowChar(80, 0, show_sign, OLED_8X16);if(collect_space.counter == collect_space.insert_locate && (show_sign != '<') && (show_sign != '>')){OLED_ClearArea(0, 40, 128, 16);//for循环输出字符for(counter = 0; counter < collect_space.counter ;counter++){OLED_ShowChar(5+(counter)*14, 40, collect_space.data_symbol[counter], OLED_8X16);}		}elseif(collect_space.counter != collect_space.insert_locate){OLED_ClearArea(0, 40, 128, 16);//for循环输出字符for(counter = 0; counter < collect_space.counter ;counter++){OLED_ShowChar(5+(counter)*14, 40, 			collect_space.data_symbol[counter], OLED_8X16);}}OLED_Update();	
}
<3>循环检测按键按下
	while(1){//按键按下if(key_button_down == 1){//识别按键scan_keyboard();	//注意,此时按键应该抬起//拾取按键到中缀式collect_Key_information(show_sign);//按键展示show_keyboard();//擦屁股, 恢复读取模式 线性反转第一波(等待按键按下)button_key_config();Exti_key_config();	key_button_down = 0;}}

第二步: 单片机键值, 组合成算式字符串

(1)收集框架

我们收集的算式, 包括,加减乘除,‘0’-‘9’,还有左右括号,至于等于号,就不需要了,因为按完算式后,按下等于号, 相当于计算结果,等计算出结果后, 我们再按下等于,相当于清零,所以我们要做一下区分.

image-20240624170617115

(2)中缀式数据结构

所以, 我们定义一个中缀算式的数据结构

#define data_MaxSize   100
//中缀式处理结构体
struct CollectSpace
{char data_symbol[data_MaxSize];	//存储中缀式符号的数组int counter;					//最后一个字符的数组位置int insert_locate;					//当前需要插入的位置_Bool Start_Mode;				//是否开始计算_Bool clear;					//是否清零		
};	

(3)读取开始运算标志,计算结果

如果第一次按下等于号 ,就开始计算

if(collect_space.Start_Mode == 1)	//判断中缀式处理结构,是否进入计算模式
{//中缀式结构数组 --> 后缀式
Conversion_expression(collect_space.data_symbol,Suffix_expression);//转换后缀式//计算数值Calculate_result = Calculate_value(Suffix_expression);OLED_Clear();//结果OLED_Printf(0,0, OLED_8X16,"%.2f", Calculate_result);//总算式OLED_ShowString(0,20, collect_space.data_symbol,OLED_8X16);OLED_Update();collect_space.Start_Mode = 0;	//停止计算
}

(4)收集按键信息

①分按键类型,进入不同模式

收集的信息, 分为数字,运算符和等于号,

我们分别根据类型, 进入不同的模式进行处理:

image-20240624180928671

判断对应类型,进入不同处理模式

void collect_Key_information(char collect_key)
{//获得按键//查询功能if(collect_key >= '0' && collect_key <= '9'){char_input.character_Mode = 1;	//数字模式}elseif(collect_key == '+' || collect_key == '-' || collect_key == '*' || collect_key == '/' || collect_key == '(' || collect_key == ')'	)		{char_input.character_Mode = 2;	//运算符模式}elseif(collect_key == '<'||collect_key == '>'){char_input.character_Mode = 3;	//移动编辑模式}elseif(collect_key == 'x'){char_input.character_Mode = 4;	//编辑删除模式}elseif(collect_key == '='){char_input.character_Mode = 5;	//运算结果模式}deal_mode(collect_key);
}
② 根据不同模式,进入不同的处理
<1>数字模式

数字可以插入第一个位置和 第字符个数+1的位置

处理方法: 先腾出要插入的位置,然后把对应位置插入

if(char_input.character_Mode == 1)
{//合法性判断(可以插入第一个位置, 和 第(字符个数 + 1)的位置)直接使用物理序号if(collect_space.insert_locate >= 0 && collect_space.insert_locate <= collect_space.counter){for(j = collect_space.counter; j > collect_space.insert_locate; j--){collect_space.data_symbol[j] = collect_space.data_symbol[j-1];}collect_space.data_symbol[collect_space.insert_locate] = deal_key;//合法后 , 字符数量加1collect_space.counter++;//默认下次光标插入位置++collect_space.insert_locate++;}
}
<2>运算符模式

(可以插入第一个位置, 和 第(字符个数 + 1)的位置)直接使用物理序号

if(char_input.character_Mode == 2)	//加入合法性判断
{//合法性判断(可以插入第一个位置, 和 第(字符个数 + 1)的位置)直接使用物理序号if(collect_space.insert_locate >= 0 && collect_space.insert_locate <= collect_space.counter){for(j = collect_space.counter; j > collect_space.insert_locate; j--){collect_space.data_symbol[j] = collect_space.data_symbol[j-1];}collect_space.data_symbol[collect_space.insert_locate] = deal_key;//合法后 , 字符数量加1collect_space.counter++;//默认下次光标插入位置++collect_space.insert_locate++;}}
<3>移动编辑模式

这里, 我们只是切换了光标序号,所以我们下次插入字符的时候,就不能直接覆盖了,而是腾出位置,然后插入了

if(char_input.character_Mode == 3)	//移动编辑插入字符模式
{//光标跟踪if(deal_key == '<'){if(collect_space.insert_locate > 0){collect_space.insert_locate--;		}}else if(deal_key == '>'){if(collect_space.insert_locate < collect_space.counter){collect_space.insert_locate++;}}
}
<4>删除字符模式

我们删除字符前, 要做删除位置合法性判断(删除位置 = 插入位置的前一个字符)

//合法性判断(可以删除的位置 0 ~ 数组的collect_space.counter-1)

if(char_input.character_Mode == 4)	//删除字符模式
{//删除位置合法性判断(删除位置 = 插入位置的前一个字符)deletesapce.now_delete = collect_space.insert_locate-1;//合法性判断(可以删除的位置 0 ~ 数组的collect_space.counter-1)if(deletesapce.now_delete >= 0 && deletesapce.now_delete < collect_space.counter){//删除光标处的前一个字符 === //把光标后的字符移动到此为止(覆盖)//临界 data[collect_space.counter-2 ] = data[collect_space.counter-1 ];//==> j = collect_space.counter-2 =得出范围=> j < collect_space.counter-1for(j = deletesapce.now_delete; j < collect_space.counter-1; j++){collect_space.data_symbol[j] = collect_space.data_symbol[j+1];}//数组个数减去1collect_space.counter--;//光标位序减去1collect_space.insert_locate--;}
}
<5>运算模式

当我们第一次按下按键,我们就进入运算模式, 并且加一个自锁变量,下次等于就是清零变量,collect_space.clear ^= 1;

if(char_input.character_Mode == 5)	//运算模式
{//开启计算结果,并将计算数值装入中缀式if(collect_space.clear == 0){collect_space.data_symbol[collect_space.counter] = '\0';collect_space.Start_Mode = 1;	//中缀式结构 进入下次计算的待计算模式(擦屁股)//分情况collect_space.counter = 0;collect_space.insert_locate = 0;//初始的时候, 是数组, 0collect_space.clear ^= 1;}elseif(collect_space.clear == 1)	//将计算清零(归零):擦屁股{//清空屏幕OLED_Clear();OLED_Update();collect_space.clear ^= 1;}}

第三步,计算结果

我们通过观看博客原理,即可

https://blog.csdn.net/qq_57484399/article/details/138288148

第四步,屏幕显示

我们可以直接调用OLED显示函数,显示结果

但是如果我们需要使用语音,读出结果的话,就要对每一位进行分个进行读取,然后结合个十百千万以及汉语的语言习惯了,我会单独出一个博客,讲解,如果把自然数小数进行语音播报.

第五步, 清零

再次按下等于号,即可清零

相关文章:

嵌入式计算器模块实现

嵌入式计算器模块规划 计算器混合算法解析 上面我们的算法理论已经完善, 我们只用给一个混合运算式, 计算器就可以帮助我们计算出结果. 但是存在一个痛点, 每次计算算式,都要重新编译程序, 所以我们想到了, 利用单片机, 读取用户输入的按键, 组成算式, 输入给机器, 这样我们就…...

tomcat定时重启

Tomcat定时重启&#xff08;linux&#xff09; 1. 编写脚本 在tomcat的bin目录下&#xff0c;使用vim restart.sh&#xff0c;编写restart.sh脚本&#xff0c;插入一下内容&#xff0c;最后并保存&#xff01; #!/bin/bash# 初始化全局环境变量 . /etc/profilecd /usr/loca…...

构建LangChain应用程序的示例代码:48、如何使用非文本生成工具创建多模态代理

多模态输出&#xff1a;图像和文本 这个示例展示了如何使用非文本生成工具来创建多模态代理。 本例仅限于文本和图像输出&#xff0c;并使用UUID在工具和代理之间传输内容。 本例使用Steamship生成和存储生成的图像。生成的内容默认受到身份验证保护。 您可以在这里获取Ste…...

【笔记】记录一次全新的Java项目部署过程

记录一次全新的Java项目部署过程 环境:CentOS7一、初始环境准备 yum install wget -y yum install vim -y yum install net-tools -y mkdir /data mkdir /data/html mkdir /data/backend一、安装JDK 17 安装JDK17# 下载rpm wget https://download.oracle.com/java/17/latest/…...

达梦数据库系列—14. 表空间的备份和还原

目录 1、表空间备份 2、表空间还原 3、表空间恢复 4、增量还原恢复 1、表空间备份 表空间只能在联机状态下进行备份。 BACKUP TABLESPACE TBS BACKUPSET /dm/backup/dm_bak/ts_bak_01; 完全备份 BACKUP TABLESPACE TBS FULL BACKUPSET /dm/backup/dm_bak/ts_full_bak_01…...

奔驰G350升级原厂自适应悬挂系统有哪些作用

奔驰 G350 升级自适应悬挂系统后&#xff0c;可根据行车路况自动调整悬架高度和弹性&#xff0c;从而提升驾乘的舒适性和稳定性。 这套系统的具体功能包括&#xff1a; • 多种模式选择&#xff1a;一般有舒适、弯道、运动及越野等模式。例如&#xff0c;弯道模式在过弯时能为…...

一个启动脚本例子

一、全部代码 #!/bin/bash DATE$(date %Y%m%d)SOURCE"abc.jar" TARGET"backup/abc.jar.jew.$DATE"if [ -f "$SOURCE" ]; thencp "$SOURCE" "$TARGET" firm -f abc.jar mv abc_1.jar abc.jarpidNumps -ef | grep $SOURCE |…...

grpc学习golang版( 六、服务器流式传输 )

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 第七章 客户端流式传输 第八章 双向流示例 文章目录 一、前言二、定义proto文件三、拷贝任意文件进项目四、编写serve…...

ubuntu语音库ALSA报错具体原因

在ubuntu中使用pyaudio或portaudio时总会有下面的提示&#xff0c;不胜其烦。 ALSA lib pcm_dsnoop.c:612:(snd_pcm_dsnoop_open) unable to open slave ALSA lib pcm_dmix.c:1018:(snd_pcm_dmix_open) unable to open slave ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unkn…...

Java高级重点知识点-17-异常

文章目录 异常异常处理自定义异常 异常 指的是程序在执行过程中&#xff0c;出现的非正常的情况&#xff0c;最终会导致JVM的非正常停止。Java处 理异常的方式是中断处理。 异常体系 异常的根类是 java.lang.Throwable&#xff0c;&#xff0c;其下有两个子类&#xff1a;ja…...

DM达梦数据库函数分析(与mysql对应函数区别及用法分析)

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 💝💝💝如有需要请大家订阅我的专栏【数据库系列】哟!我会定期更新相关系列的文章 💝💝💝关注!关注!!请…...

ROS2用c++开发参数节点通信

1.创建节点 cd chapt4/chapt4_ws/ ros2 pkg create example_parameters_rclcpp --build-type ament_cmake --dependencies rclcpp --destination-directory src --node-name parameters_basic --maintainer-name "joe" --maintainer-email "1027038527qq.com&…...

docker 部署jitsi meet

1. 部署环境&#xff1a; 1.1 vm 虚拟机 安装的 centos 7 1.2 centos7安装docker 和 docker-compose 2.docker命令 官网部署文档地址&#xff1a;&#xff08;文档地址有可能失效&#xff09; Self-Hosting Guide - Docker | Jitsi Meet 2.1Download and extract the late…...

【Pytest自动化测试详解】

目录 一、前言pytest是一个非常成熟的全功能的Python测试框架&#xff0c;主要特点&#xff1a; 二、pytest安装 2.1、安装 pip install -U pytest 2.2、验证安装 pytest --version # 会展示当前已安装版本 2.3、pytest文档 官方文档&#xff1a;https:…...

6-14题连接 - 高频 SQL 50 题基础版

目录 1. 相关知识点2. 例子2.6. 使用唯一标识码替换员工ID2.7- 产品销售分析 I2.8 - 进店却未进行过交易的顾客2.9 - 上升的温度2.10 - 每台机器的进程平均运行时间2.11- 员工奖金2.12-学生们参加各科测试的次数2.13-至少有5名直接下属的经理2.14 - 确认率 1. 相关知识点 left …...

深度挖掘数据资产,洞察业务先机:利用先进的数据分析技术,精准把握市场趋势,洞悉客户需求,为业务决策提供有力支持,实现持续增长与创新

在当今日益激烈的商业竞争环境中&#xff0c;企业想要实现持续增长与创新&#xff0c;必须深入挖掘和有效运用自身的数据资产。数据不仅是企业运营过程中的副产品&#xff0c;更是洞察市场趋势、理解客户需求、优化业务决策的重要资源。本文将探讨如何通过利用先进的数据分析技…...

亚马逊广告如何设置关键词竞价获取最优广告投入产出比 (ACOS)

在投放亚马逊商品广告的时候&#xff0c;从我们通常的理解来说&#xff0c;关键词竞价CPC设置的越高&#xff0c;广告投入产出比 (ACOS)越高&#xff0c;所以我们通常希望CPC越低越好&#xff0c;但是从我们实际投放广告来看&#xff0c;CPC与ACOS并不是线性相关。有时候CPC设定…...

vision mamba-yolov8:结合Vmamba的yolov8目标检测改进实现

1.vision mamba结构与原理 Mamba成功的关键在于S6模型&#xff0c;该模型为NLP任务设计&#xff0c;通过选择性扫描空间状态序列模型&#xff0c;将二次复杂度降低至线性。但由于视觉信号&#xff08;如图像&#xff09;的无序性&#xff0c;Mamba的S6模型不能直接应用&#xf…...

2025秋招NLP算法面试真题(十一)-Transformer的并行化

正文 本文主要谈一下关于 Transformer的并行化。文章比较短&#xff0c;适合大家碎片化阅读。 Decoder不用多说&#xff0c;没有并行&#xff0c;只能一个一个的解码&#xff0c;很类似于RNN&#xff0c;这个时刻的输入依赖于上一个时刻的输出。 对于Encoder侧&#xff1a; …...

如何在本地一键配置最强国产大模型

自从OpenAI的ChatGPT横空出世以来&#xff0c;国内外各类大语言模型&#xff08;LLM&#xff09;层出不穷&#xff0c;其中不乏Google的Gemini、Claude、文心一言等等。相较于竞争激烈的商业模型赛道&#xff0c;以Llama为代表的开源大模型的进步速度也十分惊人。 伴随着大语言…...

代码随想录算法训练营第九天|151.翻转字符串里的单词、右旋字符串、28. 实现 strStr()、459.重复的子字符串

打卡Day9 1.151.翻转字符串里的单词2.右旋字符串3.28. 实现 strStr()4.459.重复的子字符串 1.151.翻转字符串里的单词 题目链接&#xff1a;翻转字符串里的单词 文档讲解&#xff1a; 代码随想录 思路&#xff1a;首先&#xff0c;移除多余的空格&#xff1b;然后&#xff0c…...

第6天:文件操作和异常处理

学习目标 掌握如何在Python中进行文件读写操作理解文件的打开模式学习如何处理文件中的数据理解异常处理的基本概念掌握使用try、except、else和finally进行异常处理 学习内容 1. 文件操作 在Python中&#xff0c;文件操作包括打开文件、读写文件内容和关闭文件。 文件的打…...

关于freesql 频繁报“【主库】状态不可用,等待后台检查程序恢复方可使用”异常的解决。

我的项目仓储FreeSqlRepository中同时引用了“FreeSql.Provider.MySql” 和“FreeSql.Provider.MySqlConnector” 两个组件。 当我使用freesql操作数据库增删改查时&#xff0c;系统总是报类似如下错误&#xff1a;【主库】状态不可用&#xff0c;等待后台检查程序恢复方可使用…...

Spring Boot中如何使用Flyway进行数据库版本控制

Spring Boot中如何使用Flyway进行数据库版本控制 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在现代的软件开发中&#xff0c;数据库版本控制是保证应用程序…...

心理学|人格心理学——人格心理学单科作业(中科院)

一、单选题(第1-40小题,每题1.5分,共计60分。) 1、没有两个人能对同一事物做出相同的反应,反映的是人格的( ) 分值1.5分 A、稳定性 B、独特性 C、统合性 D、功能性 正确答案: B、独特性 2、人格决定一个人的生活方式,甚至有时会决定一个人的命运,反映的…...

第三方服务提供商的五大风险

亚马逊如何应对网络安全挑战 关键网络安全统计数据和趋势 移动优先世界中安全和隐私策略 当今数字时代网络安全的重要性 用户无法停止犯安全错误的 3 个原因 首席安全官可能过于依赖 EDR/XDR 防御 随着业务流程变得越来越复杂&#xff0c;公司开始转向第三方来提高其提供关…...

海康视频播放,包含h5和web插件

自行下载 海康开放平台 demo 都写得很清楚&#xff0c;不多描述 1.视频web插件 vue2写法&#xff0c;公共vue文件写法&#xff0c;调用文件即可 开始时需要以下配置&#xff0c;不知道的找对接平台数据的人&#xff0c;必须要&#xff0c;否则播不了 getParameterData: {po…...

数据库-python SQLite3

数据库-python SQLite3 一&#xff1a;sqlite3 简介二: sqlite3 流程1> demo2> sqlite3 流程 三&#xff1a;sqlite3 step1> create table2> insert into3> update4> select1. fetchall()2. fetchone()3. fetchmany() 5> delete6> other step 四&#…...

FFMpeg rtmp 推送本地yuv文件

可以借鉴的&#xff1a;C使用FFmpeg实现YUV数据编码转视频文件_C 语言_脚本之家 yuv文件下载地址&#xff1a;YUV Sequences 代码&#xff1a; #include <stdio.h> #include <unistd.h> #include <iostream> extern "C" { #include "libav…...

websocket使用,spring boot + vite + vue3

websocket使用&#xff0c;spring boot vite vue3 Websocket是什么WebSocket 服务端构建websocket 服务实现处理器pom文件 客户端仓库地址 Websocket是什么 WebSocket 是一种网络传输协议&#xff0c;可在单个 TCP 连接上进行全双工通信&#xff0c;位于 OSI 模型的应用层。…...

基础位运算

基础知识点&#xff1a; 1.判断2的幂 n&&#xff08;n-1&#xff09;0 2.每次减一处理 n&(n-1) 3.判断出现1次次数的数 x^0x&#xff0c;x^x0&#xff0c;a^bc则ab^c&#xff0c;ba^c 力扣练习题&#xff1a; 136.只出现一次的数字 class Solution { public:int si…...

性价比高真无线蓝牙耳机有哪些?性价比真无线蓝牙耳机推荐

目前真无线蓝牙耳机的音质和性能已经越来越接近甚至超越传统有线耳机。然而&#xff0c;市面上的TWS耳机品牌和型号繁多&#xff0c;价格也从几十元到几千元不等&#xff0c;性价比自然成了消费者选择时的重要考量因素&#xff0c;究竟哪些真无线蓝牙耳机既能够提供满意的音质和…...

Big Data Tools插件

一些介绍 在Jetbrains的产品中&#xff0c;均可以安装插件&#xff0c;其中&#xff1a;Big Data Tools插件可以帮助我们方便的操作HDFS&#xff0c;比如 IntelliJ IDEA&#xff08;Java IDE&#xff09; PyCharm&#xff08;Python IDE&#xff09; DataGrip&#xff08;SQL …...

两个li标签之间有空格这是什么原因

<li> 标签之间出现的空格可能由多种原因造成。以下是一些常见的原因&#xff1a; HTML源代码中的空格&#xff1a;如果你在HTML源代码中直接在两个 <li> 标签之间输入了空格或制表符&#xff08;Tab&#xff09;&#xff0c;这些空格可能会被浏览器渲染出来。不过&…...

使用Colly库进行高效的网络爬虫开发

引言 随着互联网技术的飞速发展&#xff0c;网络数据已成为信息获取的重要来源。网络爬虫作为自动获取网页内容的工具&#xff0c;在数据分析、市场研究、信息聚合等领域发挥着重要作用。本文将介绍如何使用Go语言中的Colly库来开发高效的网络爬虫。 什么是Colly库&#xff1…...

【C#】制作图集

如题目&#xff0c;用好几个图片拼在一个大图里&#xff0c;博主是用于Unity游戏开发使用的&#xff0c;话不多说&#xff0c;上代码&#xff01; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging;namespace EffectsPac…...

行列视报表系统制作的报表与厂级监控信息系统(SIS)系统中的报表有什么区别?

厂级监控信息系统是集过程实时监测、优化控制及生产过程管理为一体的厂级自动化信息系统&#xff0c;是处于DCS以及相关辅助程控系统与全厂管理信息系统之间的一套实时厂级监控信息系统&#xff0c;该产品也是本公司的一套独立产品。 SIS系统中的报表只是其中的一个模块&#…...

算法08 广/宽度优先搜索及相关问题详解

这是《C算法宝典》算法篇的第08节文章啦~ 如果你之前没有太多C基础&#xff0c;请点击&#x1f449;专栏&#xff1a;C语法入门&#xff0c;如果你C语法基础已经炉火纯青&#xff0c;则可以进阶算法&#x1f449;专栏&#xff1a;算法知识和数据结构&#x1f449;专栏&#xff…...

PyTorch 版本与 CUDA 版本的兼容性示例

PyTorch 1.9.0 及以上版本支持 CUDA 11.1。PyTorch 1.8.0 支持 CUDA 11.0。PyTorch 1.7.0 支持 CUDA 10.2。PyTorch 1.6.0 支持 CUDA 10.1。PyTorch 1.5.0 支持 CUDA 10.1。PyTorch 1.4.0 支持 CUDA 10.1。PyTorch 1.3.0 支持 CUDA 10.0。PyTorch 1.2.0 支持 CUDA 9.2。PyTorch…...

Selenium进行Web自动化滚动

在使用Selenium进行Web自动化时&#xff0c;计算页面内的滚动条位置或执行滚动操作通常涉及JavaScript执行。Selenium的WebDriver提供了执行JavaScript代码的功能&#xff0c;这可以用来获取滚动条的位置或滚动到页面上的特定位置。 获取滚动条位置 你可以使用JavaScript的wi…...

机器学习模型训练过程和预测过程 用孩子来生动的比喻 --九五小庞

训练过程&#xff1a;孩子在学习知识 想象一下&#xff0c;一个年幼的孩子刚开始学习新知识&#xff0c;这就像是机器学习的模型训练过程。 收集教材&#xff1a;孩子首先得到了一本教科书或一系列学习材料&#xff0c;这些材料就像机器学习中的数据集&#xff0c;包含了各种…...

【爱上C++】详解string类2:模拟实现、深浅拷贝

在上一篇文章中我们介绍了string类的基本使用&#xff0c;本篇文章我们将讲解string类一些常用的模拟实现&#xff0c;其中有很多细小的知识点值得我们深入学习。Let’s go&#xff01; 文章目录 类声明默认成员函数构造函数析构函数拷贝构造函数深浅拷贝问题传统写法现代写法…...

狄克斯特拉算法

狄克斯特拉算法&#xff08;Dijkstra’s algorithm&#xff09;是一种用于在带权图中找到从单一源点到所有其他顶点的最短路径的算法。它适用于处理带有非负权值的图。 下面将详细解释算法的工作原理、时间复杂度以及如何通过优化数据结构来改进其性能。 狄克斯特拉算法的工作…...

2024推荐整理几个磁力导航网站可提供海量资源的

都2024现在网上找资源像流水得鱼一样&#xff0c;抓一大把结果很难吃&#xff0c;我通宵特意整理的网站&#xff0c;网上有许多磁力导航网站可以提供海量的磁力链接资源&#xff0c;以下是一些有效的磁力导航网站推荐&#xff1a; 磁力搜索 链接&#xff1a; 资源类型&#x…...

链式访问:C语言中的函数调用技巧

链式访问&#xff1a;C语言中的函数调用技巧 在C语言编程中&#xff0c;链式访问&#xff08;chained calls&#xff09;是一个常见的编程技巧&#xff0c;它允许你在一行代码中连续调用多个函数或方法。这种技巧不仅能够让代码更加简洁和易读&#xff0c;还能减少临时变量的使…...

数据库设计(实战项目)-1个手机号多用户身份

一. 背景&#xff1a; 该需求是一个互联网医院的预约单场景&#xff0c;护士在小程序上申请患者查房预约单&#xff0c;医生在小程序上对预约单进行接单&#xff0c;护士开始查房后填写查房小结&#xff0c;客户需要对用户信息进行授权&#xff0c;医生查房后进行签字&#xff…...

vue+fineReport 使用前端搜索+报表显示数据

--fineReprot 将需要搜索的参数添加到模版参数 sql&#xff1a; --前端传递参数 注&#xff1a;因为每次点击搜索的结果需要不一样&#xff0c;还要传递一个时间戳的参数&#xff1a; let timesamp new Date().getTime()...

高阶面试-存储系统的设计

概述 分类 块存储 block storage文件存储 file storage对象存储 object storage 区别&#xff1a; 块存储 概述 位于最底层&#xff0c;块&#xff0c;是物理存储设备上数据存储的最小单位。硬盘(Hard Disk Drive&#xff0c;HDD)就属于块存储。常见的还有固态硬盘(SSD)、…...

柔性测斜仪:土木工程与地质监测的得力助手

在现代土木工程和地质工程领域&#xff0c;精确监测土壤和岩石的位移情况对于确保工程安全至关重要。柔性测斜仪作为一种高精度、稳定性和灵活性兼备的测量设备&#xff0c;已逐渐成为工程师和研究人员的得力助手。本文将深入探讨柔性测斜仪在多个关键领域的应用及其重要性。 点…...

数字资产和数据资产你真的了解吗?

数据作为新型生产要素&#xff0c;是数字化、网络化、智能化的基础&#xff0c;已快速融入生产、分配、流通、消费和社会服务管理等各环节&#xff0c;深刻改变着生产方式、生活方式和社会治理方式。 何为数据资产&#xff1f;即由个人或企业拥有或控制的&#xff0c;能为企业带…...

某网页gpt的JS逆向

原网页网址 (base64) 在线解码 aHR0cHM6Ly9jbGF1ZGUzLmZyZWUyZ3B0Lnh5ei8 逆向效果图 调用代码&#xff08;复制即用&#xff09; 把倒数第三行换成下面的base64解码 aHR0cHM6Ly9jbGF1ZGUzLmZyZWUyZ3B0Lnh5ei9hcGkvZ2VuZXJhdGU import hashlib import time import reques…...

机器学习 C++ 的opencv实现SVM图像二分类的训练 (二)【附源码】

本节讲机器学习 C 的opencv实现SVM图像二分类的训练&#xff0c;下节讲测试&#xff1a; 数据集合data内容如下&#xff1a; 下载地址为&#xff1a;https://download.csdn.net/download/hgaohr1021/89506900 #include <stdio.h> #include <time.h> #include…...

DJYGUI AI低代码图形编程开发平台:开启嵌入式软件图形编程新纪元

在科技高速发展的当今时代&#xff0c;软件开发行业对创新和高效的需求日益增长。DJYGUI AI低代码图形编程开发平台的出现&#xff0c;为智能屏、物联屏、串口屏等嵌入式显示设备领域带来了全新的机遇。该平台由都江堰操作系统 AI 代码自动生成平台研发&#xff0c;具有显著的优…...

【ACM_2023】3D Gaussian Splatting for Real-Time Radiance Field Rendering

【ACM_2023】3D Gaussian Splatting for Real-Time Radiance Field Rendering 一、前言Abstract1 INTRODUCTION2 RELATED WORK2.1 Traditional Scene Reconstruction and Rendering2.2 Neural Rendering and Radiance Fields2.3 Point-Based Rendering and Radiance Fields 3 O…...

Linux应急响应靶机 1

一、靶机介绍 应急响应靶机-Linux1 前景需要&#xff1a;小王急匆匆地找到小张&#xff0c;小王说"李哥&#xff0c;我dev服务器被黑了",快救救我&#xff01;&#xff01; 挑战内容&#xff1a; 黑客的IP地址 遗留下的三个flag 注意&#xff1a; 该靶机有很多…...

Spark面试题总结

一、RDD的五大特性是什么 1、RDD是由一些分区构成的&#xff0c;读取文件时有多少个block块&#xff0c;RDD中就会有多少个分区 2、算子实际上是作用在RDD中的分区上的&#xff0c;一个分区是由一个task处理&#xff0c;有多少个分区&#xff0c;总共就有多少个task 3、RDD之间…...

4JJ1动力+定制化冷厢翼放冷链版助你夏日创富遥遥领“鲜”

夏日高温,对于生鲜食材的运输来说是个巨大的挑战。如何确保物品新鲜及时的送达,成为摆在物流行业面前不得不思考的问题。冷链物流的重要性愈发凸显,而高效、可靠的冷藏车则成为了解决这一问题的关键。那么,面对市场上琳琅满目的冷藏车产品,如何选到一款既省心又高效赚钱的…...

别再为选车纠结,凯迪拉克XT5用实力告诉你什么是真正的性价比

凯迪拉克XT5的宽敞空间,乘坐无忧空间表现方面,凯迪拉克XT5的车长是4813mm、车宽是1903mm、车高是1686mm,在这个级别车型中可以说是数一数二的,这也保证了凯迪拉克XT5的驾乘舒适性和空间。而奥迪Q5L的车长是4770mm、车宽是1893mm、车高是1667mm,明显的参数对比可以看到凯迪…...

15.99万起奇瑞风云T9开启预售,这是不得不知道的几点

奇瑞风云T9正式开启了预售,此次公布的是120km长续航版的预售价格,预售区间为15.99-19.99万元。那么新车有哪些亮点呢?一起来看下。紧凑型SUV价格给你7座布局奇瑞风云T9官方给它的定位是紧凑型SUV,但它的车身尺寸其实并不小,车身尺寸为4795/1930/1738mm,轴距为2770mm。这个…...

ECMAScript 详解

ECMAScript 详解 ECMAScript&#xff08;ES&#xff09;是JavaScript的标准化脚本语言&#xff0c;由ECMA国际通过ECMA-262标准进行规范。ECMAScript定义了语法、类型、对象模型和内置对象等基本特性&#xff0c;是JavaScript、JScript和ActionScript等语言的核心部分。 以下…...

Python OCR 文字识别使用模型:读光-文字识别-行识别模型-中英-通用领域

介绍 什么是OCR&#xff1f; OCR是“Optical Character Recognition”的缩写&#xff0c;中文意为“光学字符识别”。它是一种技术&#xff0c;可以识别和转换打印在纸张或图像上的文字和字符为机器可处理的格式&#xff0c;如计算机文本文件。通过使用OCR技术&#xff0c;可…...

0基础认识C语言(理论+实操 2)

小伙伴们大家好&#xff0c;今天也要撸起袖子加油干&#xff01;万事开头难&#xff0c;越学到后面越轻松~ 话不多说&#xff0c;开始正题~ 前提回顾&#xff1a; 接上次博客&#xff0c;我们学到了转义字符&#xff0c;最后留下两个转义字符不知道大家有没有动手尝试了一遍&a…...