当前位置: 首页 > 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-…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

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

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

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...