STM32 中断编程入门

news2024/11/18 20:16:01

目录

一、中断系统

1、中断的原理

2、中断类型

外部中断

定时器中断

DMA中断

3、中断处理函数

中断标志位清除

中断服务程序退出 

二、实际应用

中断控制LED 

任务要求

代码示例

中断控制串口通信

任务要求1

代码示例

任务要求2

代码示例

总结


学习目标:

学习stm32中断原理和开发编程方法,实现中断点亮LED灯;中断发送消息。

一、中断系统

STM32微控制器的中断系统是其功能强大和灵活性的重要组成部分。中断允许微控制器在执行主程序的同时,及时响应外部事件或内部条件的变化,从而实现高效的实时控制和数据处理。核心的中断控制器是NVIC(Nested Vectored Interrupt Controller),负责管理和分发所有的中断请求,并支持优先级分组,使开发人员能够为不同的中断源设置不同的优先级。STM32支持多种类型的中断,包括外部中断、定时器中断、串口中断和DMA中断。每种中断类型都有特定的配置方式和中断服务程序编写规范,以确保及时和有效地处理相应的事件。中断使能和中断优先级设置是配置中断系统的关键步骤,同时需要编写高效的中断服务程序,以便快速响应并尽快恢复主程序的执行。这些特性使得STM32在广泛的嵌入式应用中表现出色,为实时控制和数据处理提供了强大支持。

1、中断的原理

下面通过一个生活中的例子,帮助更好的去理解中断:

可以看到图中,由最开始的看书,转到最后的去卫生间,这个过程中,看书就受到了中断。我们将看书看作主程序,快递电话、肚子疼视为中断源,取快递和去卫生间视为中断服务程序 ,但是通过箭头可以看到,最后还是返回到了看书的 “主程序” ,所以,中断还存在返回,我们叫做中断返回。

在计算机中,执行程序过程中,当出现异常情况(断电等)或特殊请求(数据传输等)时,计算机暂停现行程序的运行,转向对这些异常情况或特殊请求进行处理,处理完毕后再返回到现行程序的中断处,继续执行原程序,这就是“中断”。

中断的主要处理流程为:中断请求——>中断响应——>中断服务——>中断返回

中断请求:中断请求是中断源向CPU发出中断请求信号,此时中断控制系统的中断请求寄存器被置位,向CPU请求中断

中断响应:CPU的中断系统判断中断源的中断请求是否符合中断响应条件,如果符合条件,则暂时中断当前程序并控制程序跳转到中断服务程序

中断服务:为处理中断而编写的程序称为中断服务程序,是由开发人员针对具体中断所要实现的功能进行设计和编写的,需要由开发人员来实现

中断返回:CPU退出中断服务程序,返回到中断请求响应之前被中止的位置继续执行主程序。这部分操作同样由硬件来实现,不需要开发人员进行处理

 当发生了异常或中断,内核要想响应这些异常或中断,就需要知道这些异常或中断的服务程序的入口地址,再由入口地址找到相应的中断服务程序,由中断入口地址组成的表称作中断向量表(如下图)。

STM32中断系统的结构和工作原理如下:

中断请求来源:STM32的中断请求可以来自外部和内部两个方面。外部中断是由GPIO口引脚的电平或边沿信号变化触发,而内部中断通常是由硬件模块(如定时器、ADC)或软件产生的。

NVIC控制器:在STM32中,所有中断请求都由NVIC(Nested Vectored Interrupt Controller)控制器进行管理和调度。NVIC是一个基于向量表的中断控制器,通过优先级和向量表来实现对中断请求的管理。

中断分组:STM32将中断分为多个组别,每个组别包含一组中断请求。不同组别的中断请求可以具有不同的优先级,并且可以使用优先级抢占和屏蔽机制来确保系统的实时性和可靠性。STM32中断分组方式可选为0~4个前缀,用于设定中断优先级组和亚组。

中断服务程序:当中断事件发生后,CPU会暂停当前任务并跳转到相应的中断服务程序,处理该事件。中断服务程序通常包括以下几个步骤:保存CPU寄存器的值(包括堆栈指针、程序计数器等)处理中断请求(根据外部或内部中断的类型进行相应的处理,如清除标志位、读取数据等操作)执行用户自定义代码(根据实际需求执行用户自定义的代码段)恢复CPU寄存器的值(将保存在堆栈中的寄存器值恢复到其原始状态,以便CPU继续执行之前的任务)

中断优先级:STM32中,所有中断请求都具有唯一的编号(IRQn),并且可以根据编号和中断分组方式确定其优先级。优先级高的中断可以打断正在执行的低优先级中断,从而确保系统的实时性和可靠性。如果多个中断请求的优先级相同,则可以使用优先级抢占机制来确定响应顺序

2、中断类型

外部中断

EXTI(外部中断/事件控制器)支持19个外部中断/事件请求,每个中断/事件都有独立的触发和屏蔽设置,具有中断模式和事件模式两种设置模式。

其是一种通过配置GPIO引脚并使用EXTI线路实现的事件处理机制。在初始化GPIO引脚为输入并设置相应的中断触发方式后,可以通过编写中断服务程序来响应外部事件。例如,配置GPIO引脚为上升沿触发,当引脚接收到上升沿信号时,会触发预先定义的中断服务程序,以便快速处理事件。这种机制使得STM32能够高效地监听和响应外部触发事件,广泛应用于各种应用场景中。

  • 输入线:EXTI有19个中断/事件输入线,这些输入线可以通过寄存器设置为任意一个GPIO,也可以是一些外设事件。
  • 边沿检测电路:它会根据上升沿触发选择寄存器(EXTI_RTSR)和下降沿出发选择器(EXTI_FTSR)对应的设置来控制信号触发。

上升沿触发选择寄存器:要配置STM32微控制器的外部中断以在上升沿触发时响应,首先需通过GPIO的配置寄存器(如GPIOxCRH或GPIOxCRL)将相应引脚设置为输入模式。接着,在EXTIx_RTSR寄存器中设置相应的位来使能对应的外部中断线x的上升沿触发。最后,在NVIC中使能对应外部中断的中断处理。这些步骤确保了当引脚接收到上升沿信号时,系统能够及时调用预定义的中断服务程序来处理事件。

下降沿触发选择寄存器:要配置STM32微控制器的外部中断以在下降沿触发时响应,首先需通过GPIO的配置寄存器(如GPIOx_CRH或GPIOx_CRL)将相应引脚设置为输入模式。接着,在EXTIx_FTSR寄存器中设置相应的位来使能对应的外部中断线x的下降沿触发。最后,在NVIC中使能对应外部中断的中断处理。这些步骤确保了当引脚接收到下降沿信号时,系统能够及时调用预定义的中断服务程序来处理事件。

GPIO的中断是以组为单位的,同组的外部中断公用一条外部中断线。    

例如:PA0、PB0、PC0、PD0、PE0、PF0、PG0这些为一组,如果使用PA0作为外部中断源,那么PB0、PC0、PD0、PE0、PF0、PG0就不能同时再作为外部中断使用了,在此情况下,只能使用类似于PB1、PC2这种末端序号不同的外部中断源。

GPIO引脚和外部中断线的映射关系图如下:

定时器中断

STM32微控制器的定时器是关键的外设,用于生成精确的时间延迟和周期性任务。通过选择合适的定时器类型(如通用定时器TIM或基本定时器TIM6/TIM7),配置工作模式和中断触发条件,可以实现定时器中断功能。配置过程包括设置时钟源、计数器初值和自动重装载寄存器,以及使能中断并编写相应的中断服务程序。这些步骤确保了定时器可以在达到预设计数值时产生中断请求,从而实现精确的时间控制和周期性任务执行,适用于实时操作系统、通信协议和其他时间敏感应用。

要配置STM32微控制器的定时器中断,首先选择适合需求的定时器(如TIM1、TIM2等),配置其工作模式时钟源计数周期。通过使能定时器中断控制寄存器中的更新中断位(UIE),允许定时器溢出时产生中断请求。

  • 时钟和预分频设置:选择适当的时钟源和预分频器,以确定定时器的计数频率。
  • 计数器设置:设置定时器的计数器初值和自动重装载寄存器(ARR),确定定时器的计数周期。
  • 中断使能:通过使能定时器中断使能寄存器中的相应中断使能位(如UIE),允许定时器溢出时产生中断请求。

然后编写中断服务程序来处理定时器中断事件,包括清除中断标志执行特定的定时任务重新配置定时器。最后,确保在主程序中使能全局中断,以确保定时器中断能够正常触发和处理。这些步骤能够有效配置和利用STM32定时器中断功能,用于实现各种时间相关的应用和功能需求。

DMA中断

 在STM32微控制器中,DMA(直接存储器访问)提供了高效的数据传输机制,允许外设和内存之间直接交换数据,无需CPU的干预,从而提升系统效率和响应速度。DMA传输完成时可触发中断通知CPU,通过使能DMA中断并配置中断服务程序,可以实现在数据传输完成时执行额外操作或启动后续任务,适用于实时数据处理、高速数据采集和图形显示等应用场景,有效优化系统性能和数据处理效率。

3、中断处理函数

中断标志位清除

void EXTI0_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line0) != RESET)
	{
		EXTI_ClearITPendingBit(EXTI_Line0);
		// 接中断服务程序代码
	}
}

中断服务程序退出 

void EXTI0_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line0) != RESET)
	{
		EXTI_ClearITPendingBit(EXTI_Line0);
		// 接中断服务程序代码
	}
	NVIC_ClearPendingIRQ(EXTI0_IRQn);

二、实际应用

中断控制LED 

任务要求

用stm32F103核心板的GPIOA端一管脚接一个LED,GPIOB端口一引脚接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关接高电平时,LED亮灯;接低电平时,LED灭灯。如果完成后,尝试在main函数while循环中加入一个串口每隔1s 发送一次字符的代码片段,观察按键中断对串口发送是否会带来干扰或延迟。

代码示例

LED.c

#include "stm32f10x.h"                  // Device header
 
/**
  * 函    数:LED初始化
  * 参    数:无
  * 返 回 值:无
  */
void LED_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);		//开启GPIOA的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);		
 
    GPIO_ResetBits(GPIOA, GPIO_Pin_0);
}

 exti_key.c

#include "exti_key.h"
#include "misc.h"
 
void EXTI_Key_Init(void)
{   
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // 使用 B 口的引脚 1
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; // 使用与 GPIOB 引脚 1 相关的外部中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure); 
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_ClearITPendingBit(EXTI_Line1);  
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); // 将 GPIOB 和引脚 1 配置为外部中断
    EXTI_InitStructure.EXTI_Line = EXTI_Line1;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
}

main.c

#include "stm32f10x.h"                  // Device header
#include "LED.h"
#include "exti_key.h"
 
int main(void)
{
	LED_Init();
    GPIO_ResetBits(GPIOA,GPIO_Pin_0);
	EXTI_Key_Init();
 
	while (1)
	{
	}
}
//void EXTI1_IRQHandler(void)
//{
//    if(EXTI_GetITStatus(EXTI_Line1) != RESET)
//    {
//        GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)((1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_0))));
//        EXTI_ClearITPendingBit(EXTI_Line1);
//    }
//}
//两种方法
uint8_t led = 1;
 
void EXTI1_IRQHandler(void)
{
      if(EXTI_GetITStatus(EXTI_Line1) != RESET)
      {
		led = ~led; //状态翻转
        //如果等于1,则PB1复位点亮,否则置1熄灭
        if(led == 1)
            GPIO_ResetBits(GPIOA,GPIO_Pin_0);
        else
            GPIO_SetBits(GPIOA,GPIO_Pin_0);    
     }
     EXTI_ClearITPendingBit(EXTI_Line1); //清除EXTI1的中断标志位
}

即可实现中断控制LED灯亮灭。

中断控制串口通信

任务要求1

当stm32接收到1个字符“s”时,停止持续发送“hello windows!”; 当接收到1个字符“t”时,持续发送“hello windows!”

代码示例

#include "stm32f10x.h"
#include "misc.h"
#include <string.h>
 
volatile uint8_t send_enabled = 0;  // 全局变量,控制发送行为
 
void USART_Configuration(void) {
    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
 
    // 打开 GPIO 与 USART 端口的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
 
    // 配置 USART1 Tx (PA.09) 为复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    // 配置 USART1 Rx (PA.10) 为浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    // 配置 USART 参数
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);
 
    // 使能 USART
    USART_Cmd(USART1, ENABLE);
 
    // 使能接收中断
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
 
    // 配置 NVIC
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
 
void USART1_IRQHandler(void) {
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
        char data = USART_ReceiveData(USART1);
        if(data == 's') {  // 接收到 's' 停止发送
            send_enabled = 0;
        } else if (data == 't') {  // 接收到 't' 开始发送
            send_enabled = 1;
        }
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }
}
 
void Delay(__IO uint32_t nCount) {
    for(; nCount != 0; nCount--);
}
 
int main(void) {
    SystemInit();
    USART_Configuration();
 
    char *str = "hello windows!\r\n";
    while(1) {
        if(send_enabled) {
            for(uint32_t i = 0; i < strlen(str); i++) {
                while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
                USART_SendData(USART1, str[i]);
            }
        }
        Delay(5000000);
    }
}

任务要求2

当stm32接收到字符“stop stm32!”时,停止持续发送“hello windows!”; 当接收到字符“go stm32!”时,持续发送“hello windows!”(提示:要将接收到的连续字符保存到一个字符数组里,进行判别匹配。写一个接收字符串的函数。)

代码示例

NVIC.c

#include "stm32f10x.h"                  // Device header
 
 
void NVIC_Configuration(void) {
    NVIC_InitTypeDef NVIC_InitStructure;
 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
 

Serial.c

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>
 
/**
  * 函    数:串口初始化
  * 参    数:无
  * 返 回 值:无
  */
void Serial_Init(void)
{
	/*开启时钟*/
	USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
 
    // USART Tx (PA.09) 配置为复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    // USART Rx (PA.10) 配置为浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);
 
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 开启接收中断
    USART_Cmd(USART1, ENABLE);
}

main.c

#include "stm32f10x.h"
#include "misc.h"
#include <string.h>
#include "Delay.h"
#include "Serial.h"
#include "NVIC.h"
 
 
#define BUFFER_SIZE 100
volatile char buffer[BUFFER_SIZE];
volatile int buffer_index = 0;
volatile int send_enabled = 0;
 
 
void USART1_IRQHandler(void) {
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
        char data = (char)USART_ReceiveData(USART1);
        if (buffer_index < BUFFER_SIZE - 1) {
            buffer[buffer_index++] = data;
            buffer[buffer_index] = '\0';  // 保持字符串结尾
 
            char* temp_buffer = (char*)buffer; // 创建一个非 volatile 指针
 
            if (strstr(temp_buffer, "stop stm32!") != NULL) {
                send_enabled = 0;
                buffer_index = 0;  // 清空缓冲区
            } else if (strstr(temp_buffer, "go stm32!") != NULL) {
                send_enabled = 1;
                buffer_index = 0;  // 清空缓冲区
            }
        }
    }
}
 
int main(void) {
    SystemInit();
    Serial_Init();
    NVIC_Configuration();
 
    char *str = "hello windows!\r\n";
    while (1) {
        if (send_enabled) {
            for (uint32_t i = 0; i < strlen(str); i++) {
                while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
                USART_SendData(USART1, str[i]);
            }
        }
        Delay_ms(500);
    }
}

最后使用串口助手即可(野火以及其他串口助手均可)。

总结

本章内容理解上不存在太多有问题的地方,对于中断的理解更像是正51单片机的另一个翻版,对于实践过程中的问题,远远多于理论理解,关于软件的操作,环境的配置,串口的调试运行,都是之前学习的逐渐累积,在学习上,没有一蹴而就,要脚踏实地,做好每一步,才可以更好更快,更高效率完成任务。

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

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

相关文章

什么是文档透明加密|好用的文档透明加密软件有哪些?

在当今日益数字化和信息化的时代&#xff0c;数据安全问题愈发受到企业和个人的关注。文档作为信息的重要载体&#xff0c;其安全性不言而喻。为了保障文档的机密性和完整性&#xff0c;文档透明加密技术应运而生。本文将对文档透明加密进行详细介绍&#xff0c;并探讨一些好用…

6月份上海二手房卖疯了,暴涨四成,反价房东被抛弃

6月份刚刚结束&#xff0c;北京、上海两大城市的房市成交情况纷纷出炉&#xff0c;从成交量来看上海房市明显比北京火热许多&#xff0c;同时与其他城市类似&#xff0c;消费者偏向于二手房。 6月份上海二手房往前高达2.6万套&#xff0c;环比增加超四成&#xff0c;创下2021年…

粤港联动,北斗高质量国际化发展的重要机遇

今年是香港回归27周年&#xff0c;也是《粤港澳大湾区发展规划纲要》公布5周年&#xff0c;5年来各项政策、平台不断为粤港联动增添新动能。“十四五”时期的粤港澳大湾区&#xff0c;被国家赋予了更重大的使命&#xff0c;国家“十四五”《规划纲要》提出&#xff0c;以京津冀…

用MySQL+node+vue做一个学生信息管理系统(二):创建MySQL数据表、创建HTML用户列表页面

MySQL代码 CREATE DATABASE students;USE students;CREATE TABLE student( id INT COMMENT 学号, name VARCHAR(32) COMMENT 姓名, sex VARCHAR(8) COMMENT 性别, class VARCHAR(64) COMMENT 班级 )SHOW TABLES;下面介绍一下Vue框架的element-ui的使用方法&#xff0c;这里就不…

【哈尔滨二级等保测评需要测哪些指标】

为了保证系统的安全性、稳定性和遵从性&#xff0c;哈尔滨二级等保评估要求对评估指标进行全面的评估。下面就是对哈尔滨等保二级考核所需要的考核指标的具体说明&#xff0c;并按各个维度分点表达与总结&#xff1a; 一、物理安全要求 物理安全是信息系统的根本&#xff0c;…

go-zero微服务教程(一、基本介绍与安装)

系列文章目录 第一章 go-zero基本介绍与安装 文章目录 一、基本介绍1.1 参考1.2 什么是微服务1.3 什么是go-zero1.4 为什么选择go-zero1.5 go-zero的整体架构1.6 go-zero的特点 二、安装2.1 go-zero需要安装的组件2.2 安装 protoc 及代码生成插件2.3 安装用于生成 go 和 grpc 相…

工业触摸一体机优化MES应用开发流程

工业触摸一体机在现代工业生产中扮演着至关重要的角色&#xff0c;它集成了智能触摸屏和工业计算机的功能&#xff0c;广泛应用于各种生产场景中。而制造执行系统&#xff08;MES&#xff09;作为工业生产管理的重要工具&#xff0c;对于提高生产效率、降低成本、优化资源利用具…

XTDrone-固定翼无人机编队跟踪无人车-配置教程

配置使用ROS版本为Neotic 1 配置 1.1 加载固定翼无人机编队跟踪控制工程文件 cp -r ~/XTDrone/coordination/fixed_wing_formation_control ~/catkin_ws/src 1.2 加载一些用到的功能包 sudo apt-get install ros-noetic-serial #根据自己的ROS版本修改 sudo apt-get insta…

[图解]SysML和EA建模住宅安全系统-07-to be块定义图

1 00:00:00,180 --> 00:00:06,820 我们来看&#xff0c;这是之前的那张图&#xff0c;现有的 2 00:00:08,290 --> 00:00:09,160 我们怎么做 3 00:00:09,170 --> 00:00:11,280 你看&#xff0c;我们之前 4 00:00:11,290 --> 00:00:15,600 在现状&#xff0c;as i…

lstrip()方法——截掉字符串左边的空格或指定的字符

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 lstrip()方法用于截掉字符串左边的空格或指定的字符。lstrip()方法的语法格式如下&#xff1a; str.lstrip([chars]) 参数说明&#xff…

多语言模型(Multilingual Models)用于推理(Inference)

在深入探讨多语言模型&#xff08;Multilingual Models&#xff09;用于推理&#xff08;Inference&#xff09;的详细内容时&#xff0c;我们需要首先理解多语言模型的基本概念、它们如何工作、为什么它们在现代自然语言处理&#xff08;NLP&#xff09;中变得如此重要&#x…

中小企业如何防止被查盗

在当前的商业环境中&#xff0c;小企业面临诸多挑战&#xff0c;其中之一便是如何在有限的预算内满足日常运营的技术需求。由于正版软件的高昂成本&#xff0c;一些小企业可能会选择使用盗版软件来降低成本。 我们联网之后存在很多风险&#xff0c;你可以打开自己的可以联网的电…

TOGAF培训什么内容?参加TOGAF培训有什么好处?考试通过率多少?

TOGAF培训什么内容&#xff1f;参加TOGAF培训有什么好处&#xff1f;考试通过率多少&#xff1f; TOGAF培训哪些内容&#xff1f; 通过本课程&#xff0c;你将掌握TOGAF的理论和实践&#xff0c;理解企业架构的影响&#xff0c;能够评估、启动、设 计、执行新一轮企业和IT架构…

Librechat快速部署指南

引言 Github的开源免费程序里&#xff0c;Librechat作为AI对话使用&#xff0c;现阶段可谓是最佳选择&#xff0c;配合聚合API >>进行使用&#xff0c;能够保证成本最低&#xff0c;自由度最高&#xff0c;私密性最强&#xff0c;功能丰富且界面美观&#xff0c;如此以来…

老旧芯片糊弄不了国人,国产手机纷纷降价,直逼千元

国产手机今年特别糊弄国内消费者&#xff0c;将2022年乃至2018年的芯片稍微升级&#xff0c;或者就是直接改名重新上市&#xff0c;国产手机以为他们可以凭借市场份额优势迫使消费者购买这些采用落后芯片的手机&#xff0c;然而现实说明他们错了。 近期几家国产手机品牌纷纷将这…

生物分子生物学实验过程的自动化与智能监控系统设计

开题报告&#xff1a;生物分子生物学实验过程的自动化与智能监控系统设计 一、引言 随着生物科学技术的飞速发展&#xff0c;生物分子生物学实验在科研、医疗、农业等领域的应用日益广泛。然而&#xff0c;传统的生物分子生物学实验过程大多依赖于人工操作&#xff0c;存在操…

网安加·百家讲坛 | 刘志诚:从安全(Safety)团队看OpenAI之争的本质

作者简介&#xff1a;刘志诚&#xff0c;乐信集团信息安全中心总监、OWASP广东区域负责人、网安加社区特聘专家。专注于企业数字化过程中网络空间安全风险治理&#xff0c;对大数据、人工智能、区块链等新技术在金融风险治理领域的应用&#xff0c;以及新技术带来的技术风险治理…

【UML用户指南】-26-对高级行为建模-状态图

目录 1、概念 2、组成结构 3、一般用法 4、常用建模技术 4.1、对反应型对象建模 一个状态图显示了一个状态机。在为对象的生命期建模中 活动图展示的是跨过不同的对象从活动到活动的控制流 状态图展示的是单个对象内从状态到状态的控制流。 在UML中&#xff0c;用状态图…

基于MATLAB对线阵天线进行泰勒加权

相控阵天线——基于MATLAB对线阵进行泰勒加权 目录 前言 一、泰勒综合 二、单元间距的改变对泰勒阵列方向图的影响 三、单元数的改变对泰勒阵列激励分布的影响 四、副瓣电平SLL对泰勒阵列激励幅度的影响 五、副瓣电平SLL对泰勒阵列方向图的影响 六、泰勒阵列和切比雪夫阵…

去中心化革命:探索区块链技术的前沿

随着信息技术的飞速发展&#xff0c;区块链技术作为一种新兴的去中心化解决方案&#xff0c;正逐渐改变着我们的经济、社会和技术格局。本文将从区块链的基本原理、当前的应用实例以及未来的发展趋势三个方面&#xff0c;深入探讨区块链技术在革命性变革中的角色和影响。 1. 区…