HC32L136K8TA单片机输出互为反相双路PWM
可这里可以参考stm32的代码看看 HC32L136K8TA的机制跟32差不多 以使用一个通用定时器输出两路互为反相的 PWM 波,但需要通过一定的配置技巧实现。与高级定时器(如 STM32 的 TIM1、TIM8 等)不同,通用定时器通常没有直接的互补输出功能。因此,我们需要以下两种方法来实现:
方法 1:通过两个通道输出反相 PWM 波
通用定时器通常支持多通道输出(如 TIMx_CH1 和 TIMx_CH2),我们可以:
- 配置一个通道(如 CH1)为标准的 PWM 输出。
- 配置另一个通道(如 CH2)的极性为反相输出。
实现步骤
- 配置定时器的两个通道为 PWM 模式。
- 将一个通道的输出极性配置为正常(高电平有效),另一个通道的输出极性配置为反相(低电平有效)。
- 两个通道设置相同的占空比和频率,但由于极性反转,它们将输出互为反相的 PWM 波形。
#include "stm32f4xx.h"void PWM_Inverted_Init(void) {// 1. 启用时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // TIM3 时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // GPIOA 时钟// 2. 配置 GPIO 引脚为复用功能GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // PA6 (TIM3_CH1), PA7 (TIM3_CH2)GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOA, &GPIO_InitStruct);// 将引脚复用为 TIM3 功能GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3); // PA6 -> TIM3_CH1GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3); // PA7 -> TIM3_CH2// 3. 配置定时器TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;TIM_TimeBaseStruct.TIM_Period = 1000 - 1; // 自动重装载值(决定 PWM 周期)TIM_TimeBaseStruct.TIM_Prescaler = 84 - 1; // 预分频器(假设系统时钟为 84MHz)TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct);// 4. 配置通道 1 为 PWM 模式 1(正常输出)TIM_OCInitTypeDef TIM_OCInitStruct;TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; // PWM 模式 1TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStruct.TIM_Pulse = 500; // 占空比 50%TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; // 高电平有效TIM_OC1Init(TIM3, &TIM_OCInitStruct);// 5. 配置通道 2 为 PWM 模式 1(反相输出)TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; // 低电平有效TIM_OC2Init(TIM3, &TIM_OCInitStruct);// 6. 启动定时器TIM_Cmd(TIM3, ENABLE);
}int main(void) {PWM_Inverted_Init();while (1) {// 主循环}
}
- TIM3_CH1 输出标准 PWM 波。
- TIM3_CH2 输出反相 PWM 波(通过
TIM_OCPolarity
配置为低电平有效)。 - 两个通道的占空比和频率相同,但极性反转,形成互为反相的波形。
方法 2:软件模拟反相输出
如果通用定时器只支持单通道输出,可以通过软件方式生成第二路反相 PWM 波。这通常需要:
- 使用中断或 DMA 捕获定时器的 PWM 输出。
- 在软件中生成一个与原始 PWM 波形反相的信号。
这里其实只需要将输出通道极性改变就可以了
#include "timer3.h"
#include "gpio.h"
#include "flash.h"
#include "pwm.h"/******************************************************************************** TIM3中断服务函数******************************************************************************/
void pwm_Init(uint16_t u16Period, uint16_t u16CHxACompare, uint16_t u16CHxBCompare){//pwm初始化 App_ClockCfg(); //时钟初始化App_Timer3PortCfg(); //Timer3 Port端口配置App_Timer3Cfg( u16Period, u16CHxACompare, u16CHxBCompare); //0x9000, 0x6000, 0x3000Timer3 配置:周期 0x9000 //周期 = 系统时钟/(2 * 分频系数 * pwm频率); CH0/1/2通道A比较值0x6000; CH0/1/2通道B比较值0x3000Tim3_M23_EnPWM_Output(TRUE, FALSE); //端口输出使能Tim3_M23_Run(); //运行。
}
void Tim3_IRQHandler(void)
{static uint8_t i;//Timer3 模式23 更新中断if(TRUE == Tim3_GetIntFlag(Tim3UevIrq)){if(0 == i){
// Gpio_WriteOutputIO(STK_LED_PORT, STK_LED_PIN,TRUE); //LED 引脚输出高电平// Tim3_M23_CCR_Set(Tim3CCR0A, 0x3000); //设置CH0 通道A比较值
// Tim3_M23_CCR_Set(Tim3CCR0B, 0x6000); //设置CH0 通道B比较值
//
// Tim3_M23_CCR_Set(Tim3CCR1A, 0x3000); //设置CH1 通道A比较值
// Tim3_M23_CCR_Set(Tim3CCR1B, 0x6000); //设置CH1 通道B比较值
//
// Tim3_M23_CCR_Set(Tim3CCR2A, 0x3000); //设置CH2 通道A比较值
// Tim3_M23_CCR_Set(Tim3CCR2B, 0x6000); //设置CH2 通道B比较值i++;}else if(1 == i){
// Gpio_WriteOutputIO(STK_LED_PORT, STK_LED_PIN,FALSE); //LED 引脚输出低电平// Tim3_M23_CCR_Set(Tim3CCR0A, 0x6000); //设置CH0 通道A比较值
// Tim3_M23_CCR_Set(Tim3CCR0B, 0x3000); //设置CH0 通道B比较值
//
// Tim3_M23_CCR_Set(Tim3CCR1A, 0x6000); //设置CH1 通道A比较值
// Tim3_M23_CCR_Set(Tim3CCR1B, 0x3000); //设置CH1 通道B比较值
//
// Tim3_M23_CCR_Set(Tim3CCR2A, 0x6000); //设置CH2 通道A比较值
// Tim3_M23_CCR_Set(Tim3CCR2B, 0x3000); //设置CH2 通道B比较值i = 0;}Tim3_ClearIntFlag(Tim3UevIrq); //清中断标志}
}//时钟初始化
void App_ClockCfg(void)
{en_flash_waitcycle_t enFlashWait;stc_sysctrl_pll_cfg_t stcPLLCfg;//结构体初始化清零DDL_ZERO_STRUCT(stcPLLCfg);enFlashWait = FlashWaitCycle1; //读等待周期设置为1(当HCLK大于24MHz时必须至少为1)Flash_WaitCycle(enFlashWait); // Flash 等待1个周期stcPLLCfg.enInFreq = SysctrlPllInFreq4_6MHz; //RCH 4MHzstcPLLCfg.enOutFreq = SysctrlPllOutFreq36_48MHz; //PLL 输出48MHzstcPLLCfg.enPllClkSrc = SysctrlPllRch; //输入时钟源选择RCHstcPLLCfg.enPllMul = SysctrlPllMul12; //4MHz x 12 = 48MHzSysctrl_SetPLLFreq(&stcPLLCfg);Sysctrl_SetPLLStableTime(SysctrlPllStableCycle16384);Sysctrl_ClkSourceEnable(SysctrlClkPLL, TRUE);Sysctrl_SysClkSwitch(SysctrlClkPLL);///< 时钟切换
}//Timer3 Port端口配置
void App_Timer3PortCfg(void)
{stc_gpio_cfg_t stcTIM3Port;
// stc_gpio_cfg_t stcLEDPort;//结构体初始化清零DDL_ZERO_STRUCT(stcTIM3Port);
// DDL_ZERO_STRUCT(stcLEDPort);Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //端口外设时钟使能// stcLEDPort.enDir = GpioDirOut;
// Gpio_Init(STK_LED_PORT, STK_LED_PIN, &stcLEDPort); //PD14设置为LED输出stcTIM3Port.enDir = GpioDirOut;// Gpio_Init(GpioPortA, GpioPin8, &stcTIM3Port);
// Gpio_SetAfMode(GpioPortA,GpioPin8,GpioAf2); //PA08设置为TIM3_CH0A
//
// Gpio_Init(GpioPortA, GpioPin7, &stcTIM3Port);
// Gpio_SetAfMode(GpioPortA,GpioPin7,GpioAf4); //PA07设置为TIM3_CH0B
// Gpio_Init(GpioPortB, GpioPin10, &stcTIM3Port);Gpio_SetAfMode(GpioPortB,GpioPin10,GpioAf5); //PB10设置为TIM3_CH1AGpio_Init(GpioPortB, GpioPin0, &stcTIM3Port);Gpio_SetAfMode(GpioPortB,GpioPin0,GpioAf2); //PB00设置为TIM3_CH1B// Gpio_Init(GpioPortB, GpioPin8, &stcTIM3Port);
// Gpio_SetAfMode(GpioPortB,GpioPin8,GpioAf6); //PB08设置为TIM3_CH2A
//
// Gpio_Init(GpioPortB, GpioPin15, &stcTIM3Port);
// Gpio_SetAfMode(GpioPortB,GpioPin15,GpioAf2); //PB15设置为TIM3_CH2B
}//Timer3 配置
void App_Timer3Cfg(uint16_t u16Period, uint16_t u16CHxACompare, uint16_t u16CHxBCompare)
{uint16_t u16CntValue;uint8_t u8ValidPeriod;stc_tim3_mode23_cfg_t stcTim3BaseCfg;stc_tim3_m23_compare_cfg_t stcTim3PortCmpCfg;//结构体初始化清零DDL_ZERO_STRUCT(stcTim3BaseCfg);DDL_ZERO_STRUCT(stcTim3PortCmpCfg);Sysctrl_SetPeripheralGate(SysctrlPeripheralTim3, TRUE); //Timer3外设时钟使能stcTim3BaseCfg.enWorkMode = Tim3WorkMode3; //三角波模式stcTim3BaseCfg.enCT = Tim3Timer; //定时器功能,计数时钟为内部PCLKstcTim3BaseCfg.enPRS = Tim3PCLKDiv1; //PCLK 预分频PSCstcTim3BaseCfg.enCntDir = Tim3CntUp; //向上计数,在三角波模式时只读stcTim3BaseCfg.enPWMTypeSel = Tim3IndependentPWM; //独立输出PWM //Tim3ComplementaryPWM;stcTim3BaseCfg.enPWM2sSel = Tim3SinglePointCmp; //单点比较功能stcTim3BaseCfg.bOneShot = FALSE; //循环计数stcTim3BaseCfg.bURSSel = FALSE; //上下溢更新Tim3_Mode23_Init(&stcTim3BaseCfg); //TIM3 的模式0功能初始化Tim3_M23_ARRSet(u16Period, TRUE); //设置重载值,并使能缓存 //ARR 自动重装器的值
//
// Tim3_M23_CCR_Set(Tim3CCR0A, u16CHxACompare); //设置CH0比较值A
// Tim3_M23_CCR_Set(Tim3CCR0B, u16CHxBCompare); //设置CH0比较值B
// Tim3_M23_CCR_Set(Tim3CCR1A, u16CHxACompare); //设置CH1比较值ATim3_M23_CCR_Set(Tim3CCR1B, u16CHxBCompare); //设置CH1比较值B// Tim3_M23_CCR_Set(Tim3CCR2A, u16CHxACompare); //设置CH2比较值A
// Tim3_M23_CCR_Set(Tim3CCR2B, u16CHxBCompare); //设置CH2比较值BstcTim3PortCmpCfg.enCHxACmpCtrl = Tim3PWMMode2; //OCREFA输出控制OCMA:PWM模式2stcTim3PortCmpCfg.enCHxAPolarity = Tim3PortPositive; //正常输出stcTim3PortCmpCfg.bCHxACmpBufEn = TRUE; //A通道缓存控制stcTim3PortCmpCfg.enCHxACmpIntSel = Tim3CmpIntNone; //A通道比较中断控制:无stcTim3PortCmpCfg.enCHxBCmpCtrl = Tim3PWMMode2; //OCREFB输出控制OCMB:PWM模式2(PWM互补模式下也要设置,避免强制输出)stcTim3PortCmpCfg.enCHxBPolarity = Tim3PortOpposite; //反相输出stcTim3PortCmpCfg.bCHxBCmpBufEn = TRUE; //B通道缓存控制使能stcTim3PortCmpCfg.enCHxBCmpIntSel = Tim3CmpIntNone; //B通道比较中断控制:无// Tim3_M23_PortOutput_Cfg(Tim3CH0, &stcTim3PortCmpCfg); //比较输出端口配置Tim3_M23_PortOutput_Cfg(Tim3CH1, &stcTim3PortCmpCfg); //比较输出端口配置
// Tim3_M23_PortOutput_Cfg(Tim3CH2, &stcTim3PortCmpCfg); //比较输出端口配置u8ValidPeriod = 1; //事件更新周期设置,0表示三角波每半个周期更新一次,每+1代表延迟半个周期Tim3_M23_SetValidPeriod(u8ValidPeriod); //间隔周期设置u16CntValue = 0;Tim3_M23_Cnt16Set(u16CntValue); //设置计数初值Tim3_ClearAllIntFlag(); //清中断标志Tim3_Mode23_EnableIrq(Tim3UevIrq); //使能TIM3 UEV更新中断EnableNvic(TIM3_IRQn, IrqLevel0, TRUE); //TIM3中断使能
}
相关文章:
HC32L136K8TA单片机输出互为反相双路PWM
可这里可以参考stm32的代码看看 HC32L136K8TA的机制跟32差不多 以使用一个通用定时器输出两路互为反相的 PWM 波,但需要通过一定的配置技巧实现。与高级定时器(如 STM32 的 TIM1、TIM8 等)不同,通用定时器通常没有直接的互补输出…...

数据分析-55-时间序列分析之获取时间序列的自然周期时间区间
文章目录 1 获取某年的总天数1.1 get_year_days()1.2 应用函数2 获取某年的总周数2.1 get_year_weeks()2.2 应用函数3 获取某日期属于某年的周数3.1 get_time_yearweek()3.2 应用函数4 获取某年某周的开始时间和结束时间4.1 get_week_start_end()4.2 应用函数5 获取往前num周期…...

Java Stream流操作List全攻略:Filter、Sort、GroupBy、Average、Sum实践
在Java 8及更高版本中,Stream API为集合处理带来了革命性的改变。本文将深入解析如何运用Stream对List进行高效的操作,包括筛选(Filter)、排序(Sort)、分组(GroupBy)、求平均值&…...

Sentaurus TCAD学习笔记:transform指令
目录 一、transform指令简介二、transform指令的实现1.cut指令2.flip指令3.rotate指令4.stretch指令5.translate指令6.reflect指令 三、transform指令示例 一、transform指令简介 在Sentaurus中,如果需要对器件进行翻转、平移等操作,可以通过transform指…...

vscode支持ssh远程开发
文章目录 一、生成ssh使用的公钥/密钥对二、使用vscode通过ssh连接服务器1.安装插件2.配置文件3.连接服务器4.新建文件夹,存放不同的任务5.为不同的项目选择不同的conda环境 三、使用scp命令与服务器互传文件、文件夹1.检查Windows 系统是否支持scp命令2.在Windows系…...
Java线程详解
一、线程的基本概念 1. 什么是线程? 线程是程序执行的一个单元,它是进程中的一个实体,是被系统独立调度和分派的基本单位。一个进程可以包含多个线程,这些线程共享进程的资源,如内存空间和文件句柄,但每个…...

java -jar启动项目报错:XXX.jar中没有主清单属性
XXX.jar中没有主清单属性 1、错误复现2、错误原因3、解决方案 java -jar启动项目报错:XXX.jar中没有主清单属性 1、错误复现 今天使用springboot给项目打了jar包,使用命令启动时报错,截图如下: 2、错误原因 项目的pom文件配置如…...

【Vue - Element 】实现表单输入框的远程搜索功能
需求 表单是一个常见的元素,而在表单中,常常需要用户从大量的数据中选择一个或多个选项。 为了提高用户体验,提供远程搜索功能可以帮助用户快速找到所需的选项,而不是从冗长的下拉列表中手动查找。 以该需求为例,我…...
Linux(Centos 7.6)命令详解:split
1.命令作用 Linux系统中的一个用于拆分文件的命令。它可以将一个大文件拆分成多个小文件,以便于传输、存储或处理 2.命令语法 Usage: split [OPTION]... [INPUT [PREFIX]] Usage: split [选项]... [输入文件] [输出文件前缀] 3.参数详解 OPTION: -a, --suffi…...

八股学习 Redis
八股学习 Redis 使用场景常见问题问题1、2示例场景缓存穿透解决方案一解决方案二 问题3示例场景缓存击穿解决方案 问题4示例场景缓存雪崩解决方案 问题5示例场景双写一致性强一致方案允许延时一致方案 问题6RDB方式AOF方式两种方式对比 问题7示例场景惰性删除定期删除 使用场景…...
如何通过高防服务隐藏服务器源IP
在网络安全领域,隐藏服务器的真实源IP地址是保护服务器免受直接攻击的重要手段之一。暴露的源IP地址容易成为黑客攻击的目标,尤其是DDoS攻击、端口扫描和暴力破解等威胁。高防服务(如阿里云盾、AWS Shield等)不仅提供强大的流量清…...

【WEB】网络传输中的信息安全 - 加密、签名、数字证书与HTTPS
文章目录 1. 概述2. 网络传输安全2.1.什么是中间人攻击2.2. 加密和签名2.2.1.加密算法2.2.2.摘要2.2.3.签名 2.3.数字证书2.3.1.证书的使用2.3.2.根证书2.3.3.证书链 2.4.HTTPS 1. 概述 本篇主要是讲解讲一些安全相关的基本知识(如加密、签名、证书等)&…...

借助Claude实现Playwright的自动化(MCP Server)
借助Claude实现Playwright的自动化(MCP Server) MCP Server自己开发也是可以的,现在也有很多开箱即用的MCP Server,可以在https://github.com/modelcontextprotocol/servers中查找 Playwright的MCP Server Playwright的MCP Server是社区开发的,它能够为LLM提供操作浏览器的…...
【区间DP】【hard】力扣730. 统计不同回文子序列
给你一个字符串 s ,返回 s 中不同的非空回文子序列个数 。由于答案可能很大,请返回对 109 7 取余 的结果。 字符串的子序列可以经由字符串删除 0 个或多个字符获得。 如果一个序列与它反转后的序列一致,那么它是回文序列。 如果存在某个 …...
【Vim Masterclass 笔记11】S06L24 + L25:Vim 文本的插入、变更、替换与连接操作同步练习(含点评课)
文章目录 S06L24 Exercise 06 - Inserting, Changing, Replacing, and Joining1 训练目标2 操作指令2.1. 打开 insert-practice.txt 文件2.2. 练习 i 命令2.3. 练习 I 命令2.4. 练习 a 命令2.5. 练习 A 命令2.6. 练习 o 命令2.7. 练习 O 命令2.8. 练习 j 命令2.9. 练习 R 命令2…...
分布式组件底层逻辑是什么?
分布式组件是指在分布式系统中执行特定功能的模块,通常分布在多个物理节点上,共同协作完成任务。其底层逻辑包括多个方面,从通信和数据管理到一致性和容错设计,具体如下: 1.分布式组件的核心特点 分布性:功…...
Spring Boot中的扫描注解如何使用
在 Spring Boot 中,扫描注解是指通过注解来告诉 Spring 框架应该扫描哪些包、哪些类或哪些特定的组件,并将其作为 Spring 容器中的 bean 进行管理。Spring Boot 主要通过以下几种注解来实现自动扫描: ComponentScanSpringBootApplicationCom…...

初识JVM HotSopt 的发展历程
目录 导学 目前企业对程序员的基本要求 面向的对象 实战 学习目标 JVM 是什么 JVM 的三大核心功能 各大 JVM look 看一下虚拟机 HotSopt 的发展历程 总结 导学 目前企业对程序员的基本要求 面向的对象 实战 学习目标 JVM 是什么 JVM 的三大核心功能 即时编译 主要是…...

基于springboot果蔬供应链信息管理平台
基于Spring Boot的果蔬供应链信息管理平台是一种集成了先进信息技术和果蔬供应链管理理念的综合性系统。 一、背景与意义 随着人们生活水平的提高和对健康饮食的重视,果蔬市场需求不断增长。然而,果蔬供应链涉及多个环节,包括种植、采摘、加…...
掌握 React 关键:理解 super () 和 super (props) 的不同应用
在 React 中,super() 和 super(props) 都与 React 类组件的构造函数(constructor)以及继承有关。为了理解它们之间的区别,我们需要了解 JavaScript 类继承机制以及 React 类组件的工作原理。 1. super() 与 super(props) 的区别 …...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...

Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...

消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...

软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...