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

第十四届蓝桥杯嵌入式详解

 

目录

第一部分 客观试题(15 分)

不定项选择(1.5 分/题)

 第二部分 程序设计试题(85 分)

 2.1 STM32CubeMX初始化配置

         2.1.1 配置GPIO

         2.1.2 配置ADC

         2.1.3 配置RCC

         2.1.4 配置定时器TIM

         2.1.5 配置ADC1、ADC2

         2.1.6 配置定时器2

         2.1.7 配置定时器3

         2.1.8 可以选择配置操作系统

         2.1.9 时钟树设置

2.2 代码详解

         2.2.1 LCD task

         2.2.2 KEYtask

         2.2.3 PWM信号输出控制


 总耗时:4.5h  

第十四届蓝桥杯嵌入式


第一部分 客观试题(15 分)

不定项选择(1.5 分/题)

        01. 下列电路中属于时序逻辑电路的是( ABC)。

        A. 计数器         B. 分频器         C. D 触发器         D. 编码器

         02. 一个 8 位二进制减法计数器,初始状态为 0000 0000,经过 300 个输入脉冲后,计 数器的状态为(B )。

        A. 0010 1100         B. 1101 0011         C. 0010 0011         D. 1101 0100

        03. 晶体管的穿透电流 ICEO能够体现( A)。

        A. 晶体管的温度稳定性         B. 晶体管允许通过最大电流极限参数

        C. 晶体管放大能力                D. 晶体管的频率特性

        04. STM32 系列微控制器,程序可以在哪些区域上运行(AB )。

        A. ROM         B. RAM         C. 寄存器         D. E2PROM

        05. 一个 8 位的 DAC 转换器,供电电压为 3.3V,参考电压 2.4V,其 1LSB 产生的输出 电压增量是(D )V。

        A. 0.0129         B. 0.0047         C. 0.0064         D. 0.0094

        06. 下列门电路中,输出端可以直接相连实现线与的是(AC )。

        A.OC 门         B.TTL 或非门         C.OD 门         D.CMOS 与非门

        07. 在 STM32 系列微控制器中,中断优先级可配置的是(BC )。

        A. RCC         B. NMI         C. HardFault         D. Systick

        08. 工作在线性区域的运算放大器应处于什么状态( A)。

        A. 负反馈         B. 正反馈         C. 开环         D. 振荡

        09. 同步电路和异步电路的区别是(D )。

        A. 电路中是否包含缓冲器                 B. 电路中是否包含触发器

        C. 电路中是否存在时钟信号             D. 电路中是否存在统一的时钟信号

        10. 下列关于关键字 inline 的描述,正确的是(ABD )。

        A. 降低栈内存的消耗。                          B. 可以提高代码的运行效率。

        C. 可以提高微控制器访问内部寄存器的速度。

        D. 程序中大量使用,会增大代码编译后的可执行文件的大小


 第二部分 程序设计试题(85 分)

 

 2.1 STM32CubeMX初始化配置

        选择STM32G431RBTx系列芯片;

        2.1.1 配置GPIO

         2.1.2 配置ADC

         2.1.3 配置RCC

         2.1.4 配置定时器TIM

         2.1.5 配置ADC1、ADC2

        一般是默认设置就可以了,开启全局中断,打开DMA通道1、DMA通道2;

        2.1.6 配置定时器2

        将PA1引脚配置定时器PWM模式1,使PA1输出PWM脉冲信号让PA7捕获。

         2.1.7 配置定时器3

        将PA7引脚配置定时器为输入捕获模式,用来捕捉PWM信号。

         2.1.8 可以选择配置操作系统

        1.添加FreeRTOS定时器

        PWM信号定时器,PWM输出高速模式,PWM输出低速模式

         2.添加任务,提前设置好任务的内存块

        堆栈空间的大小。定义句柄

        3.建立消息队列

        按键功能复杂可以使用队列简化复杂度进行调度, PWM信号分高频和低频模式也可以使用队列进行调度。

        4.其他设置

        使能固件库pack

         使能定义任务函数

         2.1.9 时钟树设置

2.2 代码详解

        定义全局变量Generator_Mode用来选择LCD界面3个模式的显示,Generator_FreqMode用来选择PWM高频和低频模式。Generator_KeyLock用来标志按键是否锁定,如果锁定则不能使用,Generator_DutyLock用来标志占空比锁。Generator_FreqShifting用来选择PWM高低模式,Generator_ShiftNum记录频率切换次数,多于10次则转1。Generator_ShiftNum、Generator_K参数界面的R和K。MaxSpeed_HighFreq、MaxSpeed_LowFreq记录高低频率下的最大速度。

低频输出频率是4k,高频输出频率是8k,可以用const静态关键字进行固定。

// 屏幕显示模式(0为数据,1为参数,2为统计)和频率模式(0低1高)
uint8_t Generator_Mode = 0, Generator_FreqMode = 0;
// 按键锁定标志位(低高频切换过程置高),占空比锁定标志位(数据界面长按B4置高,再短按B4置低)
uint8_t Generator_KeyLock = 0, Generator_DutyLock = 0;
// 正在切换的频率模式(0低1高)
uint8_t Generator_FreqShifting = 0;
// 记录的频率切换次数
uint32_t Generator_ShiftNum = 0;
// 参数界面的R和K
int8_t Generator_R = 1, Generator_K = 1;
// 记录的高/低频率下的最大速度
float MaxSpeed_HighFreq = 0, MaxSpeed_LowFreq = 0;
// PA1输出的占空比,PA7采样计算得到的速度
float Generator_PWMDuty = 0, Generator_Speed = 0;
// PA1输出的频率
uint16_t Generator_Freq = 4000;
//PA1高、低频模式下的频率(因为是固定的,所以声明为const)
const uint16_t Generator_HFreq = 8000, Generator_LFreq = 4000;

        2.2.1 LCD task

        全局变量已经解释过了,按照任务需求进行LCD界面选择显示,

LCD_Printf:va_list关键字作用是宏定义一个para变量,va_start(para, format)执行para = (va_list)&format + _INTSIZEOF(format),para指向参数format之后的那个参数的地址,即para指向第一个可变参数在堆栈的地址。vsnprintf函数用来向一个字符串缓冲区打印格式化字符串,且可以限定打印的格式化字符串的最大长度。va_end(para)用来清空para。LCD_DisplayStringLine函数是官方给的lcd.c文件中的函数用来定位行,直接调用就行。

void LCD_Printf(u8 line, const char *format, ...)
{char buf[22] = {0};va_list para;va_start(para, format);int len = vsnprintf(buf, sizeof(buf), format, para);va_end(para);LCD_DisplayStringLine(line, (unsigned char *)buf);
}

 osMessageQueueGet接收按键队列的消息,osOK枚举确认接收到了队列消息,

void LCD_Handler(void *argument)
{/* USER CODE BEGIN LCD_Handler */int8_t Generator_TempR = 1, Generator_TempK = 1;//R,K两个参数的暂存uint8_t Modified = 0;//0为修改R,1为修改Kuint32_t online_cnt = 0;/* Infinite loop */for (;;){LED_Ctrl(0, (Generator_Mode == 0) ? 1 : 0);//如果在数据模式下才点亮LD1LED_Ctrl(2, Generator_DutyLock);//如果占空比锁定则点亮LD3switch (Generator_Mode)//根据显示模式切换LCD显示{case 0:LCD_Printf(Line1, "        DATA        ");LCD_Printf(Line3, "     M=%c           ", ((Generator_FreqMode) ? 'H' : 'L'));LCD_Printf(Line4, "     P=%.0f%%       ", Generator_PWMDuty * 100.0f);LCD_Printf(Line5, "     V=%.1f         ", Generator_Speed);break;case 1:LCD_Printf(Line1, "        PARA        ");LCD_Printf(Line3, "     R=%d           ", Generator_TempR);LCD_Printf(Line4, "     K=%d           ", Generator_TempK);break;case 2:LCD_Printf(Line1, "        RECD        ");LCD_Printf(Line3, "     N=%d           ", Generator_ShiftNum);LCD_Printf(Line4, "     MH=%.1f        ", MaxSpeed_HighFreq);LCD_Printf(Line5, "     ML=%.1f        ", MaxSpeed_LowFreq);break;default:break;}uint8_t key = 0xff;//暂存变量,接收按键队列传出的按键信息if (osMessageQueueGet(Key_QueueHandle, &key, 0, 0) == osOK)//按键队列有最新按键信息{switch (key){case 0://B1短按LCD_Clear(Black);Generator_Mode++;//刷屏,换模式if (Generator_Mode == 1)//换模式后如果是参数模式,也即按下按键后进入参数模式{Generator_TempR = Generator_R, Generator_TempK = Generator_K;//暂存变量更新为现在设置的值。Modified = 0;//进入模式默认先修改R,所以Modified不管之前是什么值都改为0}if (Generator_Mode > 2)//超过2则返回数据模式Generator_Mode = 0;if (Generator_Mode == 2)//换模式后如果是统计模式,也即刚刚是从参数模式退出来的{Generator_R = Generator_TempR, Generator_K = Generator_TempK;//实际参数用暂存值更新。}break;case 1://B2短按if (!Generator_KeyLock && Generator_Mode == 0)//此时按键未锁定且处于数据模式下{osMessageQueuePut(PWM_Signal_QueueHandle, &key, 0, 0);//启动频率切换进程}else if (Generator_Mode == 1)//此时在参数模式下{Modified = (Modified) ? 0 : 1;//Modified在0,1之间切换}break;case 2://B3短按if (Generator_Mode == 1)//此时在参数模式下{if (Modified)//0为修改R,1为修改KGenerator_TempK++;elseGenerator_TempR++;if (Generator_TempK > 10)//参数越界判定Generator_TempK = 1;if (Generator_TempR > 10)Generator_TempR = 1;}break;case 3://B4短按if (Generator_Mode == 1){if (Modified)//0为修改R,1为修改KGenerator_TempK--;elseGenerator_TempR--;if (Generator_TempK < 1)//参数越界判定Generator_TempK = 10;if (Generator_TempR < 1)Generator_TempR = 10;}else if (Generator_Mode == 0)//此时在数据模式下{Generator_DutyLock = 0;//短按是解除占空比锁}break;case 4:/* code */break;case 5:/* code */break;case 6:/* code */break;case 7://B4触发长按条件if (Generator_Mode == 0)//此时在数据模式下{Generator_DutyLock = 1;//长按是占空比锁上锁}break;default:break;}}osDelayUntil((online_cnt + 1) * 100);//刷新用时控制在100ms左右online_cnt++;}/* USER CODE END LCD_Handler */
}

         2.2.2 KEYtask

        将按键按下次数存入数组中,返回到按键扫描函数。

uint8_t Key_IsUp(uint8_t pos)
{return Key_Up[pos];
}
uint8_t Key_IsLongPress(uint8_t pos)
{return Key_LongPress[pos];
}

        遍历按键gpio是否按下,按下则往Key_Reg数组中存入1,方便接下来取反,判断按键按下次数,并将按键按下次数存入Key_Cnt数组中。

uint8_t Key_Reg[4], Key_Constant[4], Key_Up[4], Key_LongPress[4], Key_LongTemp[4];
uint16_t Key_Cnt[4], Key_Delay = 78;
void Key_Scan(void)
{if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET){Key_Reg[0] = 1;}else{Key_Reg[0] = 0;}if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET){Key_Reg[1] = 1;}else{Key_Reg[1] = 0;}if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET){Key_Reg[2] = 1;}else{Key_Reg[2] = 0;}if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){Key_Reg[3] = 1;}else{Key_Reg[3] = 0;}for (int i = 0; i < 4; i++){Key_Up[i] = ~Key_Reg[i] & (Key_Reg[i] ^ Key_Constant[i]);Key_Constant[i] = Key_Reg[i];if (Key_Cnt[i] >= Key_Delay){if (Key_Up[i]){Key_LongPress[i]=1;// Key_LongPress[i] = Key_Up[i] & (Key_Up[i] ^ Key_LongTemp[i]);Key_Up[i] = 0;}// Key_LongPress[i] = Key_Reg[i] & (Key_Reg[i] ^ Key_LongTemp[i]);Key_LongTemp[i] = Key_Reg[i];}else{Key_LongPress[i] = 0;Key_LongTemp[i] = 0;}}if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET){Key_Cnt[0]++;}else{Key_Cnt[0] = 0;}if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET){Key_Cnt[1]++;}else{Key_Cnt[1] = 0;}if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET){Key_Cnt[2]++;}else{Key_Cnt[2] = 0;}if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){Key_Cnt[3]++;}else{Key_Cnt[3] = 0;}
}

         这里用for循环用来判断按键4是否长按,如果i>3则触发长按,

void Key_Handler(void *argument)
{/* USER CODE BEGIN Key_Handler */uint32_t online_cnt = 0;/* Infinite loop */for (;;){Key_Scan();//扫描按键for (uint8_t i = 0; i < 4; i++){if (Key_IsUp(i)){osMessageQueuePut(Key_QueueHandle, &i, 0, 0);//触发短按条件,B1-4对应数字0-3}if (Key_IsLongPress(i)){uint8_t j = i + 4;osMessageQueuePut(Key_QueueHandle, &j, 0, 0);//触发长按条件,B1-4对应数字4-7}}osDelayUntil((online_cnt + 1) * 25);//扫描周期粗略为25msonline_cnt++;}/* USER CODE END Key_Handler */
}

        2.2.3 PWM信号输出控制

        由题目知道,电压处于0-3V之间,占空比同时随着电压变换。(只展示部分核心代码)

void PWM_Handler(void *argument)
{/* USER CODE BEGIN PWM_Handler */uint32_t online_cnt = 0;/* Infinite loop */for (;;){if (Generator_DutyLock == 0)//未启用占空比锁{//根据题目实时修改占空比(介于10-85%之间)if (R1_Vol < 1.0f){Generator_PWMDuty = 0.1f;}else if (R1_Vol >= 3.0f){Generator_PWMDuty = 0.85f;}else{Generator_PWMDuty = -0.275f + R1_Vol * 0.375f;}}//上锁则保持原有占空比不变Timer_PWMSetDuty(Generator_PWMDuty);//控制占空比Timer_PWMSetFreq(Generator_Freq);//控制频率Generator_Speed = (IC_Freq * 2 * 3.14f * Generator_R) / 100 / Generator_K;//根据PA7输入频率,计算得到“速度”。switch (Generator_FreqMode)//0为低频率模式,1为高频率模式{case 0:if (Generator_Speed > MaxSpeed_LowFreq && !osTimerIsRunning(Lspeed_UpdateTimerHandle)){//发现现有速度高于记录的低频率最高速度,且低频率最高速度更新定时器未启动osTimerStart(Lspeed_UpdateTimerHandle, 2000U);//启动更新定时器,准备2s后更新低频率最高速度}else if (Generator_Speed <= MaxSpeed_LowFreq && osTimerIsRunning(Lspeed_UpdateTimerHandle)){//发现现有速度已经低于记录的低频率最高速度,且低频率最高速度更新定时器已经启动osTimerStop(Lspeed_UpdateTimerHandle);//不必再更新低频率最高速度,停止更新定时器}break;case 1://高频率部分道理同上if (Generator_Speed > MaxSpeed_HighFreq && !osTimerIsRunning(Hspeed_UpdateTimerHandle)){osTimerStart(Hspeed_UpdateTimerHandle, 2000U);}else if (Generator_Speed <= MaxSpeed_HighFreq && osTimerIsRunning(Hspeed_UpdateTimerHandle)){osTimerStop(Hspeed_UpdateTimerHandle);}break;default:break;}uint8_t info = 0;if (osMessageQueueGet(PWM_Signal_QueueHandle, &info, 0, 0) == osOK)//收到LCD控制任务下发的频率切换指令{Generator_KeyLock = 1;//锁定B2按键Generator_FreqShifting = Generator_FreqShifting ? 0 : 1;//此时高频则改为低频(1->0),此时低频则改为高频(0->1)osTimerStart(PWM_Signal_TimerHandle, 100U);//启动频率修改定时器(0.1s刷新一次)}osDelayUntil((online_cnt + 1) * 10);//整个PWM控制任务大概执行一次,延时10msonline_cnt++;}/* USER CODE END PWM_Handler */
}
void PWM_Signal_CB(void *argument)
{/* USER CODE BEGIN PWM_Signal_CB *///频率修改定时器回调函数(0.1s触发一次)if (Generator_FreqShifting)//切换目标是高频还是低频{Generator_Freq += (Generator_HFreq - Generator_LFreq) / 50;//单个周期(0.1s)增加80HZ,5s后正好为8KHZ}else{Generator_Freq -= (Generator_HFreq - Generator_LFreq) / 50;//单个周期(0.1s)减少80HZ,5s后正好为4KHZ}LED_Toggle(1);//LD1以0.1s为周期闪烁if (Generator_FreqShifting && Generator_Freq >= Generator_HFreq){//低频切高频时PWM频率增加后已经超过了8KHZ,也即切换5s之后Generator_FreqMode = Generator_FreqShifting;//现在的频率模式更新为高频Generator_ShiftNum++;//PWM切换次数加一Generator_Freq = Generator_HFreq;//现在的频率和最高频率对齐Generator_KeyLock = 0;//按键B2解锁LED_Ctrl(1, 0);//熄灭LD1osTimerStop(PWM_Signal_TimerHandle);//完成任务,停止定时器}if (!Generator_FreqShifting && Generator_Freq <= Generator_LFreq){//高频切低频时PWM频率减少后已经低于4KHZ,也即切换5s之后Generator_FreqMode = Generator_FreqShifting;//现在的频率模式更新为低频Generator_ShiftNum++;//PWM切换次数加一Generator_Freq = Generator_LFreq;//现在的频率和最低频率对齐Generator_KeyLock = 0;//按键B2解锁LED_Ctrl(1, 0);//熄灭LD1osTimerStop(PWM_Signal_TimerHandle);//完成任务,停止定时器}//注意该定时器为周期性定时器(osTimerPeriodic),完成切换后需要手动终止定时器/* USER CODE END PWM_Signal_CB */
}

         

相关文章:

第十四届蓝桥杯嵌入式详解

目录 第一部分 客观试题&#xff08;15 分&#xff09; 不定项选择&#xff08;1.5 分/题&#xff09; 第二部分 程序设计试题&#xff08;85 分&#xff09; 2.1 STM32CubeMX初始化配置 2.1.1 配置GPIO 2.1.2 配置ADC 2.1.3 配置RCC 2.1.4 配置定时器TIM 2.1.5 配置ADC1、AD…...

新建论文三线表模板,一键格式刷

论文三线表模板写在最前面①表设计&#xff0c;新建表格样式②三线表上下线③三线表标题线④设置表格居中⑤设置表头格式容易出错的步骤写在最前面 论文写完啦&#xff0c;准备调整格式 之前建模也是三线表&#xff0c;但只能基于该文档模板&#xff0c;所以重新设置一下。 如…...

攻防世界-web2(逆向加密算法)

打开链接是PHP源码 给了一串密文&#xff0c;并对这串密文进行了一系列操作加密&#xff0c;注释里说解密$miwen就是flag 在此我们先介绍一些PHP内置函数&#xff1a; strrev(string): 反转字符串 strlen(string): 返回字符串的长度 substr(string, start, length): 返回字符…...

C语言学习1--------Visual Studio集成开发环境的搭建

C语言学习1--------Visual Studio集成开发环境的搭建适合初学者适用集成开发环境下载 Visual Studio 2019安装 Visual Studio 2019安装工作负载为C自定义安装位置激活 Visual Studio适合初学者适用集成开发环境 建议初学者适用最新的——Visual Studio 2019为集成开发环境。 部…...

腾讯云轻量应用服务器搭建网站教程(WordPress为例)

腾讯云轻量应用服务器搭建WordPress网站教程&#xff0c;先安装WordPress应用镜像&#xff0c;然后远程连接轻量应用服务器获取WP用户名和密码&#xff0c;域名DNS解析到轻量服务器IP地址&#xff0c;登陆WordPress后台管理全过程&#xff0c;腾讯云百科来详细说下腾讯云轻量服…...

mac上的PCB设计软件现状

Altium Designer是一款商业化的电路板设计软件&#xff0c;目前没有Mac版本。但是&#xff0c;MacOS上有一些类似Altium Designer的电路板设计软件&#xff0c;以下是一些常用的软件&#xff1a; Eagle&#xff1a;Eagle是一款商业化的电路板设计软件&#xff0c;具有强大的功能…...

【面试题】JavaScript 你常用的 函数有哪些呢? (12个)

大厂面试题分享 面试题库 前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 本文收集了 12 个在日常开发中非常常用的函数&#xff0c;有些可能很复杂&#xff0c;有些可…...

Java集合——Set接口学习总结

一、HashSet实现类 1.常用方法 增加&#xff1a;add(E e)删除&#xff1a;remove(Object o)、clear()修改&#xff1a;查看&#xff1a;iterator()判断&#xff1a;contains(Object o)、isEmpty()常用遍历方式&#xff1a;Set<String> set new HashSet<String>()…...

2023最全的自动化测试入门基础知识(建议收藏)

1)首先&#xff0c;什么是自动化测试&#xff1f; 自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。通常&#xff0c;在设计了测试用例并通过评审之后&#xff0c;由测试人员根据测试用例中描述的过程一步步执行测试&#xff0c;得到实际结果与期望结果的比较。…...

【RabbitMQ】SpringBoot整合RabbitMQ、实现RabbitMQ五大工作模式(万字长文)

目录 一、准备 1、创建SpringBoot项目 2、添加配置信息 3、创建配置类 二、RabbitMQ的配置类里创建队列 三、RabbitMQ的配置类里创建交换机及绑定队列 四、SpringBoot整合RabbitMQ入门案例 1、生产者 2、消费者 四、SpringBoot里实现RabbitMQ五大工作模式 1、简单模式…...

ES6(函数扩展、数组扩展)

一、 函数扩展 1. 参数可以默认 ES5调用函数&#xff1a;如果给参数设置默认需要进行判断 ES6可以直接给参数设置默认 //ES5 function log(x, y) {//两种判断方法&#xff08;传统分支判断、利用逻辑符&#xff09;if (typeof y undefined) {y World;}//y y || World;cons…...

postman汉化教程

文章目录1. 下载对应版本的postman2.下载对应版本的汉化包2.1. github下载地址 : &#xff08;9.12.2&#xff09;2.2 百度网盘&#xff08;9.12.2&#xff09;3. 打开postman安装位置4. 压缩包解压到/resources目录下5. 重启postman即可汉化成中文了1. 下载对应版本的postman …...

java day8

第8章 数据结构8.1 超越数组8.2 java数据结构8.2.1 Iterator8.2.2 位组8.2.3 链表8.2.4 遍历数据结构8.2.5 堆栈8.1 超越数组 java类库的java.util包中有一组数据结构&#xff0c;它们让您能够更灵活地组织和操纵数据。 8.2 java数据结构 8.2.1 Iterator 接口Iterator提供了…...

口令暴力破解--Telnet协议暴力破解、数据库暴力破解与远程桌面暴力破解

Telnet协议暴力破解 Telnet Telnet协议是TCP/IP协议族中的一员&#xff0c;是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。要开始一个telnet会话&#xff0c;必须输入用户名和密码来登录服务器。而一般服务器不会对用户名…...

[译]什么是SourceMap

原文链接: https://web.dev/source-maps/使用 SourceMap 来提升 web 调试体验。今天&#xff0c;我们要讨论的是 SourceMap&#xff0c;这是现代 Web 开发中至关重要的工具&#xff0c;它能够显著地简化调试工作。在本文中&#xff0c;我们将探讨 SourceMap 的基础知识&#xf…...

saga模式、Seata saga模式详解

文章目录 一、前言二、SAGA模式0、saga论文摘要1、什么是长事务?2、saga的组成3、saga的两种执行场景1)forward recovery2)backward recovery4、saga log5、saga协调(saga实现方式)1)SAGA - Choreography 策略2)SAGA - Orchestration 策略3)如何选择三、Seata saga模式…...

java开发工程师碰到技术难题怎么办?我来聊聊我的做法

最近公司遇到了一个技术难题。这一周基本上都在加班解决这个问题&#xff0c;头发也掉了不少&#xff0c;但问题还没有解决。我写这篇文章&#xff0c;主要是想看看看我文章的同学们是否有类似的经验或者是自己的一些想法。让我们看一下这个问题的一个具体情况。 我们的公司是…...

高比例可再生能源电力系统的调峰成本量化与分摊模型(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Hive安装与操作

目录 环境 数据 实验步骤与结果 &#xff08;1&#xff09;环境启动 &#xff08;2&#xff09;Hive基本操作 环境 Hadoop集群开发环境、mysql、Hive环境 数据 course.txt、sc.txt、student.txt 实验步骤与结果 &#xff08;1&#xff09;环境启动 ①执行命令&#xf…...

oracle centos7安装Oracle12(附oracle所有版本安装包)

环境: centos 7 Oracle12c jdk1.8 一.配置环境 (1)安装依赖 yum -y install binutils.x86_64 compat-libcap1.x86_64 gcc.x86_64 gcc-c++.x86_64 glibc.i686 glibc.x86_64 glibc-devel.i686 glibc-devel.x86_64 ksh compat-libstdc++-33 libaio.i686 libaio.x86_64 libaio-…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...