TIM输出比较之PWM驱动LED呼吸灯应用案例

news2025/1/11 17:57:50

文章目录

  • 前言
  • 一、应用案例演示
  • 二、电路接线图
  • 三、应用案例代码
  • 四、应用案例分析
    • 4.1 基本思路
    • 4.2 相关库函数介绍
    • 4.3 初始化PWM模块
      • 4.3.1 RCC开启时钟
      • 4.3.2 配置时基单元
      • 4.3.3 配置输出比较单元
      • 4.3.4 配置GPIO
      • 4.3.5 运行控制
    • 4.4 PWM输出模块
    • 4.5 主程序


前言

提示:本文主要用作在学习江科大自化协STM32入门教程后做的归纳总结笔记,旨在学习记录,如有侵权请联系作者

本案例利用输出占空比可调的PWM波形来驱动LED灯,实现了一个LED呼吸灯的效果。


一、应用案例演示

TIM输出比较之PWM驱动LED呼吸灯演示

二、电路接线图

在这里插入图片描述

三、应用案例代码

PWD.h文件:

#ifndef __PWM_H
#define __PWM_H

void PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);

#endif

PWD.c文件:

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
//	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_InternalClockConfig(TIM2);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCStructInit(&TIM_OCInitStructure);
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0;		//CCR
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);
	
	TIM_Cmd(TIM2, ENABLE);
}

void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);
}

主程序main.c文件:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"

uint8_t i;

int main(void)
{
	OLED_Init();
	PWM_Init();
	
	while (1)
	{
		for (i = 0; i <= 100; i++)
		{
			PWM_SetCompare1(i);
			Delay_ms(10);
		}
		for (i = 0; i <= 100; i++)
		{
			PWM_SetCompare1(100 - i);
			Delay_ms(10);
		}
	}
}

完整工程:TIM输出比较之PWM驱动LED呼吸灯应用案例

四、应用案例分析

我们先来看一下PWM的基本结构图,如下所示,我们只需要把下面这些模块打通就可以输出PWM了。

在这里插入图片描述

4.1 基本思路

具体的步骤如下:

  • 第一步,RCC开启时钟。把我们要用的TIM外设和GPIO外设的时钟都打开。
  • 第二步,配置时基单元。包括这前面的时钟源选择。
  • 第三步,配置输出比较单元。包括CCR的值、输出比较模式、极性选择、输出使能这些参数。
  • 第四步,配置GPIO。把PWM对应的GPIO口初始化为复用推挽输出的配置。
  • 第五步,运行控制。启动计数器,这样就能输出PWM了。

以上就是基本思路,老规矩,我们先来看一下都有哪些相关的库函数。

4.2 相关库函数介绍

先来看一下这四个函数

void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

这四个函数就是用来配置输出比较模块的,也就是对应PWM的基本结构图中的输出比较单元的位置。输出比较单元有4个,那对应的就是这四个函数。参数TIMx,选择定时器。参数TIM_OCInitStruct,就是输出比较那些参数。

接下来再往下看,该函数是用来给输出比较结构体赋一个默认值的。

void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);

那到这里,输出比较的配置其实就已经可以完成了,接下来就是一些小功能和运行时需要更改参数的函数了。

我们来看一下下面这四个函数,这四个函数是用来配置强制输出模式的,如果你在运行中想要暂停输出波形并且强制输出高或者低电平就可以使用这四个函数。用得不多,了解一下即可。

void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);

再看一下下面这四个函数,这四个函数是用来配置CCR寄存器的预装功能的。这个预装功能就是影子寄存器,就是你写入的值不会立即生效,而是在更新事件才会生效,这样可以避免一些小问题。用得不多,了解一下即可。

void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);

再看一下下面这四个函数,这四个函数是用来配置快速使能的,用得也不多,了解即可。

void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);

再看一下下面这四个函数,这四个函数是用于外部事件时清除REF信号,用得也不多,了解即可。

void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);

再来看一下下面这些函数,这些函数就是用来单独设置输出比较的极性的,这里带个N的就是高级定时器里互补通道的配置,0C4没有互补通道,所以就没有OC4N的函数。那这里有函数可以设置极性,在结构体初始化的那个函数里也可以设置极性。这两个地方设置极性的作用是一样的。

void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);

再看一下下面这两个函数,这两个函数是用来单独修改输出使能参数的。

void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);

再下面,这个是用来单独更改输出比较模式的函数。

void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);

再往下看,这四个函数是用来单独更改CCR寄存器值的,这四个函数比较重要。我们在运行的时候更改占空比就需要用到这四个函数。

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);

补充一个函数,该函数仅高级定时器使用,在使用高级定时器输出PWM时需要调用这个函数,使能主输出,否则PWM将不能正常输出。

void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);

ok,那到这里,有关输出比较的函数就介绍完了,现在开始写代码。

4.3 初始化PWM模块

4.3.1 RCC开启时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

注意:TIM2是APB1总线的外设,要使用APB1的开启时钟函数

4.3.2 配置时基单元

TIM_InternalClockConfig(TIM2);

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;		//ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;		//PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);

TIM_InternalClockConfig(TIM2);//选择时基单元的时钟源,选择内部时钟。若不调用这个函数,系统上电后默认也是内部时钟。

  • TIM_ClockDivision:指定时钟分频。在这里选择TIM_CKD_DIV1,1分频,也就是不分频。
  • TIM_CounterMode:计数模式。在这里选择TIM_CounterMode_Up向上计数模式。
  • TIM_Period:ARR自动重装器的值。
  • TIM_Prescaler:PSC预分频器的值。
  • TIM_RepetitionCounter:重复计数器的值。这个是高级定时器才有的,我们不需要用,直接给0即可。

计算公式如下:
PWM频率:Freq = CK_PSC / (PSC + 1) / (ARR + 1)
PWM占空比:Duty = CCR / (ARR + 1)
PWM分辨率:Reso = 1 / (ARR + 1)
换算公式:1 MHz = 1,000 KHz = 1,000,000 Hz

假设我要输出一个频率为1KHz,占空比为50%,分辨率为1%的PWM波形,时钟源选择内部时钟,也就是说CK_PSC=72MHz。
代入公式计算可得:
Freq =1000 = 72000000 / 720 / 100
那么可以推算出PSC为719,ARR为99
同样的道理,Duty = 50% = CCR / 100,推算出CCR为50
同样也可以推算出周期 T = 1 / 1000 = 0.001秒,也就是1毫秒。(频率是周期的倒数 f = 1 / T)

4.3.3 配置输出比较单元

TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;		//CCR
TIM_OC1Init(TIM2, &TIM_OCInitStructure);

各个参数解析如下:

  • TIM_OCMode:设置输出比较的模式,这里选择PWM模式1。
  • TIM_OCPolarity:设置输出比较的极性,这里选择高极性,也就是极性不翻转,REF波形直接输出。
  • TIM_OutputState: 设置输出使能,设置使能。
  • TIM_Pulse:设置CCR,这里先暂时设置为0。

设置完成后,在TIM2的OC1通道上就可以输出PWM波形了,但最终这个波形肯定要借用一下GPIO口才能输出对吧?那这个TIM2的OC1通道是借用了哪个GPIO通道呢?

外设引脚和GPIO引脚的复用关系和重映射介绍:

我们可以查看一下引脚定义表,我们来看一下默认复用功能这一列,这一列就是片上外设的端口和GPIO的连接关系。

在这里插入图片描述

在这里可以看到,有TIM2_CH1_ETR,它是在这个PA0这一行的,这就说明TIM2的ETR引脚和通道1的引脚都是借用了PA0这个引脚的位置的。换句话说就是TIM2的引脚复用在了PA0引脚上。所以说如果我们要使用TIM2的OC1也就是CH1通道输出PWM,那它就只能在PA0引脚上输出,而不能任意选择引脚输出。

同样,如果选择TIM2的CH2通道,那就只能在PA1端口上输出。同样的道理,TIM2的CH3就对应PA2,以此类推。这些关系是定死的,不能随意更改。但是如果想要更改的话,还是有办法的,那就是重定义,也叫做重映射。

比如如果你既想用USART2_TX引脚,又要用TIM2的CH3通道,他俩冲突了,没办法同时使用,那我们就可以在这个重映射的列表里找一下,比如我们在引脚号为21的这里找到了TIM2_CH3,那TIM2的CH3就可以从原来的引脚,换到这里的引脚也就是PB10,这样就避免了两个外设引脚的冲突。

在这里插入图片描述
如果这个重映射的列表里找不到,那外设复用的GPIO就不能挪位置,这就是重映射的功能。配置重映射是用AFIO来完成的。

那在了解完外设引脚和GPIO引脚的关系之后,通过查看引脚定义表可知,TIM2的CH1通道复用在了PA0上。或者使用重映射,可以看到TIM2_CH1_ETR可以重映射到PA15上。

在这里插入图片描述

4.3.4 配置GPIO

通过上面的分析可以知道TIM2的CH1通道复用在了PA0上,所以需要初始化一个GPIOA,引脚为pin 0。

要注意的一点就是,这里GPIO的模式要选择GPIO_Mode_AF_PP复用推挽输出模式,为什么要选择这个模式呢?

在这里插入图片描述
对于普通的开漏/推挽输出,引脚的控制权是来自于输出数据寄存器的,那如果想让定时器来控制引脚,那就需要使用复用开漏/推挽输出的模式。在这里输出数据寄存器将被断开,输出控制权将转移给片上外设。那通过刚才看到的引脚定义表我们就知道了这里的片上外设引脚连接的就是TIM2的CH1通道,所以,只有把GPIO设置为复用推挽输出,引脚的控制权才能交给片上外设,PWM波形才能通过引脚输出。

在这里插入图片描述

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

这样,输出PWM的GPIO就配置好了。

4.3.5 运行控制

TIM_Cmd(TIM2, ENABLE);

最后一步,启动定时器。这样,PWM的波形就能通过PA0输出了。

4.4 PWM输出模块

我们想让LED呈现呼吸灯的效果,那就不断更改CCR的值就行了。

void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);
}

4.5 主程序

我们只需要在while(1)主循环里不断调用PWM_SetCompare1函数更改CCR的值(占空比从0到100,再从100到0),这样就能完成LED呼吸灯的效果了。

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"

uint8_t i;

int main(void)
{
	OLED_Init();
	PWM_Init();
	
	while (1)
	{
		for (i = 0; i <= 100; i++)
		{
			PWM_SetCompare1(i);
			Delay_ms(10);
		}
		for (i = 0; i <= 100; i++)
		{
			PWM_SetCompare1(100 - i);
			Delay_ms(10);
		}
	}
}

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

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

相关文章

无人机培训与装配维修技术详解

一、无人机基础理论 无人机&#xff0c;即无人驾驶航空器&#xff0c;凭借其灵活性、高效性和广泛应用性&#xff0c;已成为现代科技领域的热点之一。在学习无人机培训与装配维修技术之前&#xff0c;掌握无人机的基础理论是必不可少的。这包括但不限于&#xff1a; 1. 无人机…

Alpaca 汉化版 v2.9.3 — 免费 PS 智能 AI 插件

Alpaca是一款免费的PS智能AI插件&#xff0c;包含了6大AI功能&#xff0c;包括提示词生图、图像转绘画风格、生成式填充、文本转图像、计算图像模型、提高图像分辨率。汉化版本安装简单&#xff0c;只需解压到PhotoShop安装目录\Plug-ins文件夹即可。安装启动PhotoShop - 增效工…

基于Springboot和BS架构的宠物健康咨询系统pf

TOC springboot509基于Springboot和BS架构的宠物健康咨询系统pf 第一章 课题背景及研究内容 1.1 课题背景 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#x…

前端本地代理配置方式

Whistle 介绍 Whistle 是一个基于 Node.js 的跨平台 Web 调试工具。允许捕获、查看和修改 HTTP/HTTPS 网络请求。通过使用 Whistle&#xff0c;可以轻松地进行接口代理、抓包、模拟数据、修改请求和响应等操作&#xff0c;以便在前端开发中调试网络请求。 Proxy SwitchyOmega…

记录一个变量溢出的bug

文章目录 如题 如题 count2变量溢出了&#xff08;超过了255&#xff09;&#xff0c;结果导致busOff_16bitRecordHILTime变量莫名其妙被清0

c++题目_背包问题(可任意分割) 贪心算法

题目描述 有一个背包&#xff0c;背包容量是mm。有nn个物品&#xff0c;每个物品都有自己的重量wiw​i​​和价值viv​i​​&#xff0c;物品可以分割成任意大小。 要求尽可能让装入背包中的物品总价值最大&#xff0c;但不能超过总容量。 输入 第一行输入两个正整数 mm 和 n…

【C++】提高 -- 类模板

目录 一、类模板的作用 二、类模板的语法 三、类模板的例子 四、类模板和函数模板的区别 五、类模板中成员函数创建时机 六、类模板对象做函数参数 七、类模板与继承 八、类模板成员函数类外实现 九、类模板分文件编写 十、类模板与友元 十一、类模板案例 一、类模板…

日撸Java三百行(day31:整数矩阵及其运算)

目录 前言 一、基本属性与方法 二、getter与setter方法 三、矩阵相加与矩阵相乘方法 1.矩阵相加 2.矩阵相乘 四、数据测试 五、完整的程序代码 总结 前言 从今天开始&#xff0c;我们就要踏上图论的学习之路了。第一天&#xff0c;我们先简单热个身&#xff0c;构造一…

手持气象站:便携式、高精度设备

在科技日新月异的今天&#xff0c;气象观测技术正以前所未有的速度发展&#xff0c;从传统的地面观测站、高空探测到卫星遥感&#xff0c;每一步都极大地拓宽了我们对天气的认知边界。而在这股科技浪潮中&#xff0c;手持气象站作为一种便携式、高精度的气象监测设备&#xff0…

Ps:首选项 - 文件处理

Ps菜单&#xff1a;编辑/首选项 Edit/Preferences 快捷键&#xff1a;Ctrl K Photoshop 首选项中的“文件处理” File Handling选项卡允许用户精确控制 Photoshop 的文件保存行为和兼容性选项。这些设置非常重要&#xff0c;尤其在处理大文件或与其他软件协作时&#xff0c;可…

用Zipkin在分布式系统追踪收集和查看时间数据

Zipkin是一个开源的分布式追踪系统&#xff0c;它帮助收集、存储和展示实时的数据&#xff0c;以便于定位微服务架构中的延迟问题。以下是Zipkin的核心组件和工作流程的介绍&#xff0c;以及如何在Java中使用Spring Cloud Sleuth与Zipkin集成的案例。 Zipkin的核心组件&#x…

那些久远的开发语言(COBOL、Pascal、Perl等)还有市场吗

旧的开发语言 在旧的开发语言中&#xff0c;除了Combo和BASIC之外&#xff0c;还有一些其他曾经流行或具有重要历史意义的编程语言&#xff0c;例如&#xff1a; FORTRAN&#xff1a;1957年诞生&#xff0c;是第一个编译型语言&#xff0c;主要用于科学和工程计算 。LISP&…

RabbitMQ高级用法

&#x1f4a5; 该系列属于【SpringBoot基础】专栏&#xff0c;如您需查看其他SpringBoot相关文章&#xff0c;请您点击左边的连接 目录 一、发送者的可靠性 1. 生产者重试机制 2. 生产者确认机制【return和confirm机制】 &#xff08;1&#xff09;开启生产者确认 &#x…

ARCGIS XY坐标excel转要素面

1、准备好excel 坐标 excel文件转为csv才能识别&#xff0c;CSV只能保留第一个工作表并且&#xff0c;不会保留格式。 2、在ArcGis中导入XY事件图层 创建XY事件图层 图层要素赋对象ID 将导入的图层导出为先新的图层&#xff0c;这样就给每个要素附加了唯一的值 选择点集转线…

python模块03 --ddt数据驱动

自动化框架设计思想&#xff1a; (1) 数据驱动测试&#xff1a;即英文单词Data-Driven Testing&#xff0c;简称DDT。 (2) 关键字驱动测试&#xff1a;即英文单词Keyword-Driven Testing&#xff0c;简称KDT。 (3) 业务流程测试&#xff1a;即英文单词Business Process Tesi…

AI大模型:开源与闭源的激烈交锋与未来展望

在人工智能的浩瀚星空中&#xff0c;大模型作为技术的璀璨明珠&#xff0c;正引领着行业变革的浪潮。从最初的闭源垄断到如今的开源与闭源并驾齐驱&#xff0c;AI大模型的发布趋势、竞争格局以及技术演进&#xff0c;无不彰显着这一领域的蓬勃生机与无限可能。本文将深入探讨开…

大白话讲微服务的灾难性雪崩效应

讲在前面&#xff0c;为什么微服务需要有熔断等策略呢&#xff1f;今天我们用大白话来讲讲微服务的灾难性雪崩效应&#xff0c;熔断策略就是解决雪崩效应的有效解决方案。 什么是灾难性雪崩效应&#xff1f; 假设我们有两个访问量比较大的服务A和B&#xff0c;这两个服务分别依…

深度理解指针(2)

hello各位小伙伴们&#xff0c;关于指针的了解我们断更了好久了&#xff0c;接下来这几天我会带领大家继续我们指针的学习。 数组名的理解 我们首先来看一段代码&#xff1a; #include<stdio.h> int main () {int arr[10] {1,2,3,4,5,6,7,8,9,10};printf("arr …

汇编语言:标志寄存器ZF、PF、SF、CF、OF、DF、IF、AF

CPU内部的寄存器中&#xff0c;一种特殊的寄存器&#xff08;对于不同的CPU&#xff0c;个数和结构可能都不同&#xff09;&#xff0c;具有以下3种作用。 &#xff08;1&#xff09;用来存储相关指令的某些执行结果 &#xff08;2&#xff09;用来为CPU执行相关指令提供行为…

科技大通缩

BCG 增长份额矩阵的经典“摇钱树”象限。 来源&#xff1a;Understanding the BCG Growth Share Matrix and How to Use It &#xfeff; S 曲线的暴政 要了解这如何应用于科技行业&#xff0c;我们需要了解 S 曲线现象。 成功产品带来的价值通常会经历 S 曲线增长&#xff…