STM32第十四课:低功耗模式和RTC实时时钟

news2024/10/7 1:26:54

文章目录

  • 需求
  • 一、低功耗模式
    • 1.睡眠模式
    • 2.停止模式
    • 3.待机模式
  • 二、RTC实现实时时钟
    • 1.寄存器配置流程
    • 2.标准库开发
    • 3.主函数调用
  • 三、需求实现代码


需求

1.实现睡眠模式、停止模式和待机模式。
2.实现RTC实时时间显示。


一、低功耗模式

  电源对电子设备的重要性不言而喻,它是保证系统稳定运行的基础,而保证系统能稳定运行后,又有低功耗的要求。
   在很多应用场合中都对电子设备的功耗要求非常苛刻,如某些传感器信息采集设备,仅靠小型的电池提供电源,要求工作长达数年之久,且期间不需要任何维护;由于智慧穿戴设备的小型化要求,电池体积不能太大导致容量也比较小,所以也很有必要从控制功耗入手,提高设备的续行时间。
   因此, STM32 有专门的电源管理外设监控电源并管理设备的运行模式, 确保系统正常运行,并尽量降低器件的功耗。
  简而言之,低功耗模式就是为了保证移动设备的长时间运行。
从主控芯片角度上来说,如何降低功耗:
1、降低CPU的主频 72M->48M。
2、将不必要的片上外设关闭,对应的时钟也关闭。
3、设备可以设置低功耗模式。
在这里插入图片描述
在这里插入图片描述

1.睡眠模式

首先,我们先看最简单的睡眠模式。
想要设置睡眠模式,只用直接在主函数中根据需求添加__WFI();和__WFE();函数就行。
若是想用中断唤醒就用__WFI();
  想用事件唤醒就用__WFE();

#include "stm32f10x.h"
#include "usart.h"
#include "stdio.h"
#include "delay.h"

int main()
{
		NVIC_SetPriorityGrouping(5);//两位抢占两位次级
    	Usart1_Config(); 
	    Delay_ms(2000);
		KEY1_Exti_PA0_init();
	    printf("睡眠1\r\n");
	    __WFI();
		printf("睡眠2\r\n");
    while(1)
    {													
    }		
		return 0;
}

在睡眠模式中,仅关闭了内核时钟,内核停止运行,但其片上外设, CM3 核心的外设全都还照常运行。
在这里插入图片描述
WFI和WFE 命令,它们实质上都是内核指令,只是在库文件 core_cm3.h 中把这些指令封装成了函数。

2.停止模式

想进入停止模式需要在调用指令前设置一些寄存器位。
而STM32 标准库把这部分的操作封装到 PWR_EnterSTOPMode 函数中了。所以我们直接使用即可。

#include "stm32f10x.h"
#include "usart.h"
#include "stdio.h"
#include "delay.h"
#include "string.h"
#include "key.h"

int main()
{
	NVIC_SetPriorityGrouping(5);//两位抢占两位次级
    Usart1_Config(); 
	Delay_ms(2000);
	KEY1_Exti_PA0_init();
	printf("停止1\r\n");
	PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);
	SystemInit();
	printf("停止2\r\n");
    while(1)
    {																
    }
		
	return 0;
}

  在停止模式中,进一步关闭了其它所有的时钟,于是所有的外设都停止了工作,但由于其 1.8V 区域的部分电源没有关闭,还保留了内核的寄存器、内存的信息,所以从停止模式唤醒,并重新开启时钟后,还可以从上次停止处继续执行代码。
停止模式可以由任意一个外部中断(EXTI)唤醒(此处用的就是key1使能EXTI来唤醒),在停止模式中可以选择电压调节器为开模式或低功耗模式。
在这里插入图片描述

  进入停止模式后, STM32 的所有 I/O 都保持在停止前的状态,而当它被唤醒时, STM32 使用 HSI 作为系统时钟(8MHz)运行,由于系统时钟会影响很多外设的工作状态,所以一般我们在唤醒后会重新开启 HSE,把系统时钟设置回原来的状态。

3.待机模式

待机模式库函数也有封装好的代码,直接用就行。
待机模式,它除了关闭所有的时钟,还把 1.8V 区域的电源也完全关闭了。(除了被使能了的用于唤醒的 I/O,其余 I/O 都进入高阻态)
简单来说,就是从待机模式唤醒后,会从头开始执行程序,类似于复位。

它有四种唤醒方式:

  1. WKUP(PA0)引脚的上升沿。
  2. RTC 闹钟事件。
  3. NRST 引脚的复位。
  4. IWDG(独立看门狗)复位。

本例程使用的是KEY1上升沿唤醒。

#include "stm32f10x.h"
#include "usart.h"
#include "stdio.h"
#include "delay.h"
#include "string.h"
#include "key.h"
uint8_t key3flag,cntt;

void EnterStanbdy(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
	//选择WKUP唤醒
	PWR_WakeUpPinCmd(ENABLE);
	//进入待机模式
	PWR_EnterSTANDBYMode();
	//退出待机模式之后,由于SRAM电压关了,所以清空了,退出之后代码需要重新运行
}

int main()
{
	NVIC_SetPriorityGrouping(5);//两位抢占两位次级
    Usart1_Config(); 
	SysTick_Config(72000);
    Led_Init();
	key_Init();
    while(1)
    {	
		if(ledcnt[0]>=ledcnt[1]){//过去500ms
			ledcnt[0]=0;
			/***LED1闪烁任务***/
			Led_Toggle(1);
			printf(" LED闪烁 \r\n");
					cntt++;
					cntt%=100;
		
		}
			if(keycnt[0]>=keycnt[1]){//过去10ms
			keycnt[0]=0;
			//按键非阻塞检测
			key3flag = key_value();
			if(key3flag == 2)
				{			
				printf("进入待机模式\r\n");
				EnterStanbdy();
				}
			}														
    }
	return 0;
}

在这里插入图片描述

二、RTC实现实时时钟

  实时时钟是一个独立的定时器。 RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
  RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后, RTC的设置和时间维持不变。
  系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问:
● 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟。
● 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。

RTC内部电路
在这里插入图片描述

1.寄存器配置流程

在这里插入图片描述
RTC 从配置上分两大部分:时钟的配置和定时器的配置。
时钟的配置:可以直接访问,直接由RCC的BDCR来配置时钟:时钟源的选择。
定时器的配置:不可以直接访问,因为定时器相关的寄存器在备份区域。
1、 使能备份区域访问— PWREN、BKPEN
a) 开电源控制器以及备份区的时钟
b) 电源PWR_CR的DBP置1
2、 配置分频。
3、 设置计数器计数值。
4、 需要开中断,就开不需要就不开。
5、 需要设置闹钟,就设置闹钟。

2.标准库开发

由于该模块标准库有现成的,所以此处我们使用标准库开发。

该部分在此处:
首先打开官方给的固件库:
然后创建RTC.c和RTC.h编写好基础部分。
将标准库的void RTC_Configuration(void)直接整个函数copy过来。
接下来一行一行看:

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
 PWR_BackupAccessCmd(ENABLE);

该段代码就是使能PWR和BKP的时钟并使能,使备份访区能够访问。

  /* Reset Backup Domain */
  BKP_DeInit();//强制后备区域复位

此处可有可无,是为了防止之前有人设置过备份区,保险起见的话就加上。

  /* Enable LSE */
  RCC_LSEConfig(RCC_LSE_ON);//使能外部低速时钟
  /* Wait till LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)//等待低速时钟就绪
  {}
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//选择RTC的时钟源
  RCC_RTCCLKCmd(ENABLE);//使能RTC时钟

时钟源的配置:1.打开LSE。2.等待低速时钟稳定。3.配置RTC时钟源为LSE。

RTC_WaitForSynchro();//等待APB1和RTC时钟同步

  /* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();//等待上次写操作完成
RTC_EnterConfigMode();//进入配置模式

配置完RTC后需要等待一会儿使时钟源同步。
最后等待上次完上次写操作后就可以配置了。

 RTC_SetPrescaler(32767);
 RTC_WaitForLastTask();

将频率配置为1ms一次。(每操作一次就等待一下)

  RTC_SetCounter(ret);

设置一下初始值

	int ret;
    struct tm info;

    info.tm_year = 2024 - 1900;
    info.tm_mon = 7 - 1;
    info.tm_mday = 1;
    info.tm_hour = 4;
    info.tm_min = 10;
    info.tm_sec = 0;
    info.tm_isdst = -1;

    ret = mktime(&info);
		if(ret==-1)
		{
			printf("时间获取出错\r\n");
			return;
		}
		printf("获取到秒数为%d\r\n",ret);

上面是初始值的由来
最后退出并保存

  RTC_ExitConfigMode();
  RTC_WaitForLastTask();

3.主函数调用

在主函数中直接定义一个32位的值承接一下秒数,然后用localtime()函数转换为标准时间显示格式打印即可。
在这里插入图片描述


三、需求实现代码

main.c

#include "stm32f10x.h"
#include "usart.h"
#include "stdio.h"
#include "delay.h"
#include "string.h"
#include "pwm.h"
#include "adc.h"
#include "su03t.h"
#include "dht11.h"
#include "kqm.h"
#include "key.h"
#include "RTC.h"

uint8_t key3flag,cntt;
uint32_t sec=0;
void EnterStanbdy(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
	//选择WKUP唤醒
	PWR_WakeUpPinCmd(ENABLE);
	//进入待机模式
	PWR_EnterSTANDBYMode();
	//退出待机模式之后,由于SRAM电压关了,所以清空了,退出之后代码需要重新运行
}

int main()
{
		NVIC_SetPriorityGrouping(5);//两位抢占两位次级
    Usart1_Config(); 
		SysTick_Config(72000);
	  Led_Init();
	  key_Init();
	  
    while(1)
    {	
			
		sec = RTC_GetCounter();
	  time_t seconds=sec;
	  struct tm *info = localtime(&seconds);
			
			
		if(ledcnt[0]>=ledcnt[1]){//过去500ms
			ledcnt[0]=0;
			/***LED1闪烁任务***/
			Led_Toggle(1);
			printf(" LED闪烁 \r\n");
			
			printf("本地时间:%d-%02d-%02d %02d:%02d:%02d\r\n",
           info->tm_year + 1900, info->tm_mon + 1, info->tm_mday,
           info->tm_hour, info->tm_min, info->tm_sec);
					cntt++;
					cntt%=100;
		}
			if(keycnt[0]>=keycnt[1]){//过去10ms
			keycnt[0]=0;
			//按键非阻塞检测
			key3flag = key_value();
			if(key3flag == 2)
				{			
				printf("进入待机模式\r\n");
				EnterStanbdy();
				}
			}					
    }
		return 0;
}

RTC.c

#include "RTC.h"

void RTC_Configuration(void)
{
	  int ret;
    struct tm info;

    info.tm_year = 2024 - 1900;
    info.tm_mon = 7 - 1;
    info.tm_mday = 1;
    info.tm_hour = 4;
    info.tm_min = 10;
    info.tm_sec = 0;
    info.tm_isdst = -1;

    ret = mktime(&info);
		if(ret==-1)
		{
			printf("时间获取出错\r\n");
			return;
		}
		printf("获取到秒数为%d\r\n",ret);
	
  /* Enable PWR and BKP clocks */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//使能PWR和BKP的时钟

  /* Allow access to BKP Domain */
  PWR_BackupAccessCmd(ENABLE);//使能后备区域访问

  /* Reset Backup Domain */
  BKP_DeInit();//强制后备区域复位

  /* Enable LSE */
  RCC_LSEConfig(RCC_LSE_ON);//使能外部低速时钟
  /* Wait till LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)//等待低速时钟就绪
  {}

  /* Select LSE as RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//选择RTC的时钟源

  /* Enable RTC Clock */
  RCC_RTCCLKCmd(ENABLE);//使能RTC时钟

  /* Wait for RTC registers synchronization */
  RTC_WaitForSynchro();//等待APB1和RTC时钟同步

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();//等待上次写操作完成
	RTC_EnterConfigMode();//进入配置模式
	//RTC->CRL |= 0x01<<4; 

  /* Enable the RTC Second */
  //RTC_ITConfig(RTC_IT_SEC, ENABLE);

  /* Wait until last write operation on RTC registers has finished */
 // RTC_WaitForLastTask();

  /* Set RTC prescaler: set RTC period to 1sec */
  RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
  RTC_SetCounter(ret);
	RTC_ExitConfigMode();

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
}

RTC.h

#ifndef _RTC_H_
#define _RTC_H_
#include "stm32f10x.h"
#include "time.h"
#include "stdio.h"
void RTC_Configuration(void);
#endif

led.c

#include "stm32f10x.h"

void Led_Init()
{
	//配置好模式,然后全灭
	//开APB2时钟
	RCC->APB2ENR |= 0X01 << 6;
  //配置PE2--PE5为通用推挽输出
	GPIOE->CRL &=~(0X0F << 20);//PE5
	GPIOE->CRL |= 0X03 << 20;
	GPIOE->CRL &=~(0X0F << 16);//PE4
	GPIOE->CRL |= 0X03 << 16;
  GPIOE->CRL &=~(0X0F << 12);//PE3
	GPIOE->CRL |= 0X03 << 12;
	GPIOE->CRL &=~(0X0F << 8);//PE2
	GPIOE->CRL |= 0X03 << 8;
	//4个引脚均输出高电平
	GPIOE->ODR |= (0x0F << 2);
	
}
//开关灯
void Led1_Ctrl(int flag)
{
  if(!!flag)
	 {
		GPIOE->ODR &= ~(0x0F << 2);
	 }
	else
	 {
		GPIOE->ODR |= (0x0F << 2);
	 }
	 
}

void Led_Toggle(int flag)
{
	GPIOE->ODR ^= 0x01<<(flag+1);
}

key.c

#include "stm32f10x.h"
#include "stdio.h"

//PA0
void KEY1_Exti_PA0_init()
{
	RCC->APB2ENR |= 0x05;//打开GPIO和AFIO时钟
	GPIOA->CRL &=~(0X0F << 0);//PC4   key2
	GPIOA->CRL |= 0X04 << 0;
  AFIO->EXTICR[0] &= ~(0x0F);//配置GPIO映射EXTI线
  EXTI->RTSR &= ~(0x1); //关闭上升沿检测
	EXTI->FTSR |= 0x01;  //打开下降沿检测
  EXTI->IMR |= 0x01; //打开exti的屏蔽位
  NVIC_SetPriority(EXTI0_IRQn,2);NVIC设置优先级
	NVIC_EnableIRQ(EXTI0_IRQn); //NVIC使能中断通道
}

//exti0的中断服务函数
void EXTI0_IRQHandler(void)
{
	//判断中断标志是否被置位
	if((EXTI->PR&(0x1<<0))!=0){
		//如果置位,就清理标志位
		EXTI->PR |= 0x1<<0;//写1是清除
		printf("按键1触发中断\r\n");
	}
}

//PC4
void KEY2_Exti_PC4_init()
{
	RCC->APB2ENR |= (0x01<<4); //打开GPIOC时钟
	RCC->APB2ENR |= 0x01; //AFIO时钟
  GPIOC->CRL &=~(0X0F<<16);//配置PC4   key2
	GPIOC->CRL |= (0X04<<16);//浮空输入
  AFIO->EXTICR[1] |= 0x02;//配置GPIOC映射EXTI线,外部中断配置寄存器
  EXTI->RTSR |= (0x01<<4) ; //打开上升沿检测
	EXTI->FTSR &= ~(0x1<<4);  //关闭下降沿检测
  EXTI->IMR |= (0x01<<4); //打开exti的屏蔽位
  NVIC_SetPriority(EXTI4_IRQn,2);NVIC设置优先级
	NVIC_EnableIRQ(EXTI4_IRQn); //NVIC使能中断通道
}

void EXTI4_IRQHandler(void)
{
	//判断中断标志是否被置位
	if((EXTI->PR&(0x1<<4))!=0){
		//如果置位,就清理标志位
		printf("按键2触发中断\r\n");
		EXTI->PR |= (0x1<<4);//写1是清除
	}
}

void key_Init()
{
	//开时钟
	RCC->APB2ENR |= 0x01<<4;//PC
	RCC->APB2ENR |= 0x01<<2;//PA
	//配置模式
	GPIOC->CRL &=~(0X0F << 24);//PC6   key4
	GPIOC->CRL |= 0X04 << 24;
  GPIOC->CRL &=~(0X0F << 20);//PC5   key3
	GPIOC->CRL |= 0X04 << 20;
	GPIOC->CRL &=~(0X0F << 16);//PC4   key2
	GPIOC->CRL |= 0X04 << 16;
	GPIOA->CRL &=~0X0F;//PA0   key1
	GPIOA->CRL |= 0X04;
	
}


int Get_Key_Val(void)
{
	int key_val = 0;
	if(!!(GPIOA->IDR &(0X01 << 0))==1)
		key_val = 1;
	if(!!(GPIOC->IDR &(0X01 << 4))==0)
		key_val = 2;
	if(!!(GPIOC->IDR &(0X01 << 5))==0)
		key_val = 3;
	if(!!(GPIOC->IDR &(0X01 << 6))==0)
		key_val = 4;
	
	return key_val;
}


//PC5
void KEY3_Exti_PC5_init()
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  GPIO_InitTypeDef GPIO_InitStructure={0};
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);
	EXTI_InitTypeDef EXTI_InitStructure={0};
  EXTI_InitStructure.EXTI_Line = EXTI_Line5;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_Init(&EXTI_InitStructure);
  NVIC_SetPriority(EXTI9_5_IRQn,2);NVIC设置优先级00 10
	NVIC_EnableIRQ(EXTI9_5_IRQn); //NVIC使能中断通道
}

//PC6
void KEY4_Exti_PC6_init()
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  GPIO_InitTypeDef GPIO_InitStructure={0};
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource6);
	EXTI_InitTypeDef EXTI_InitStructure={0};
  EXTI_InitStructure.EXTI_Line = EXTI_Line6;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_Init(&EXTI_InitStructure);
  NVIC_SetPriority(EXTI9_5_IRQn,2);NVIC设置优先级00 10
	NVIC_EnableIRQ(EXTI9_5_IRQn); //NVIC使能中断通
}

void EXTI9_5_IRQHandler(void)
{
		//判断中断标志是否被置位
	if(EXTI_GetITStatus(EXTI_Line5) != RESET)
  {
		printf("按键3触发中断\r\n");
		//如果置位,就清理标志位
    EXTI_ClearITPendingBit(EXTI_Line5);
  }
	//判断中断标志是否被置位
	if(EXTI_GetITStatus(EXTI_Line6) != RESET)
  {
		printf("按键4触发中断\r\n");
		//如果置位,就清理标志位
    EXTI_ClearITPendingBit(EXTI_Line6);
  }
}


//非阻塞按键检测   
uint8_t key_value(void)//10ms执行一次
{
	static uint16_t keycnt = 0;//用来计数,本函数,进来一次加一次,
	
	if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0){
		keycnt++;
		
	}
	else if(keycnt>=200){//等待按键松开,如果按下时间超过200*10,认为是长按
		printf(" 按键3长按 \r\n");
		keycnt = 0;
		return 2;
	}	
	else if(keycnt>=2){//等待按键松开,如果按下时间超过2*10ms,认为是短按
		printf(" 按键3短按 \r\n");
		keycnt = 0;
		return 1;
	}	
	else{//等待按键松开如果按下时间不足20ms,认为这是一次无效按下,或者没有按下
		
		return 0;
	}
	return 0;
}

delay.c

#include "stm32f10x.h"
#include "delay.h"

uint32_t systicktime=0;

uint16_t ledcnt[2]={0,1000};//500ms   每个任务执行的时间
uint16_t led2cnt[2]={0,2000};//700ms
uint16_t keycnt[2]={0,10};//10ms检测一次
void SysTick_Handler(void)//1ms调用一次
{
	//不需要清中断挂起位
	systicktime++;
	ledcnt[0]++;
	led2cnt[0]++;
	keycnt[0]++;
}

void Delay_ms(uint32_t time)
{
    uint32_t nowtime = systicktime;
		while(systicktime < time+nowtime);
}

void Delay_nus(uint32_t time)
{
    uint32_t i=0;
    for(i=0;i<time;i++){
        delay1us();
    }    
}

void Delay_nms(uint32_t time)
{
    uint32_t i=0;
    for(i=0;i<time;i++){
         Delay_nus(1000);//延时1ms
    }    
}

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

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

相关文章

springboot校园购物网站APP-计算机毕业设计源码041037

摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…

以太网常用协议——ARP协议

文章目录 一、 ARP协议与MAC层1.TCP/IP协议2. MAC地址3. ARP映射4. ARP请求和ARP应答 二、以太网帧格式三、ARP协议1. 以太网ARP通信测试&#xff1a; 以太网使用的协议很多&#xff0c;常用的有ARP、UDP等。 再介绍具体协议之前需要先知道一些基本的概念&#xff1a; 一、 AR…

生产环境部署与协同开发-Docker(原创超全)

关闭防火墙 systemctl stop firewalld.service 关闭SELinux vim /etc/selinux/config 查看yum支持的包并安装docker引擎 yum listyum install -y docker 启动docker设置docker自启动测试docker是否安装成功&#xff1f; systemctl start dockersystemctl enable dockerdoc…

HCIE实验这样玩太高级了吧?实现FRR+BFD+OSPF与BGP的联动

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 晚上好&#xff0c;我的网工朋友。 今天搞个HCIE实验玩玩&#xff0c;上回分享了个张总讲解的防火墙配置实验思路&#xff0c;后来还特地搞了个视…

【电路笔记】-A类放大器

A类放大器 文章目录 A类放大器1、A类放大器概述2、A类放大器基本通用发射极配置3、变压器耦合配置4、总结在 放大器类型简介的文章中,我们介绍了不同类别的放大器。 在本文中,我们将更详细地介绍A类放大器。 在介绍不同的A类放大器配置前,首先的是要记住放大器类别的选择标…

面向优秀SCI论文写作的语言大模型提示词设计

模板1&#xff1a;Abstract 润色 I want you to act as an SCI reviewer and evaluate the abstract of a research paper. You may check if the abstract is well-written and serves as an informative and descriptive overview of the research. You may also check if it…

Centos7网络配置(设置固定ip)

文章目录 1进入虚拟机设置选中【网络适配器】选择【NAT模式】2 进入windows【控制面板\网络和 Internet\网络和共享中心\更改适配器设置】设置网络状态。3 设置VM的【虚拟网络编辑器】4 设置系统网卡5 设置虚拟机固定IP 刚安装完系统&#xff0c;有的人尤其没有勾选自动网络配置…

IOS17闪退问题Assertion failure in void _UIGraphicsBeginImageContextWithOptions

最近项目更新到最新版本IOS17&#xff0c;发现一个以前的页面突然闪退了。原来是IOS17下&#xff0c;这个方法 UIGraphicsBeginImageContext(CGSize size) 已经被移除&#xff0c;原参数如果size为0的话&#xff0c;会出现闪退现象。 根据说明&#xff0c;上述方法已经被替换…

Python + OpenCV 酷游地址教学V鄋KWK3589

本篇文章汇整了一系列的Python OpenCV 教学&#xff0c;只要按照教学文的顺序阅读和实作&#xff0c;就可以轻松入门OpenCV&#xff0c;并透过OpenCV 实现许多影像相关的创意应用。 接下来我们来介绍OpenCV-- OpenCV 是一个跨平台的电脑视觉函式库( 模组) &#xff0c;可应用…

Supabase 自托管部署实践

Supabase 是 Firebase 的开源替代品。使用 Postgres 数据库、身份验证、即时 API、边缘函数、实时订阅、存储和向量嵌入来启动您的项目。 Supabase介绍 Supabase 是一个开源的后端即服务&#xff08;BaaS&#xff09;平台&#xff0c;提供了一系列工具和服务&#xff0c;帮助…

qt中数据库和excel互导数据————附带详细步骤和代码

文章目录 0 背景1 准备QXlsx环境1.1 cmake安装使用1.2 qmake使用 2 把excel数据导出到mysql数据库3 把mysql数据库的数据写入到excel4 完整代码5 项目代码仓库 0 背景 因为需要批量导入和导出数据&#xff0c;所以需要用到excel。实现把数据库的数据导入到excel中&#xff0c;…

matrix-breakout-2-morpheus靶场

1 信息收集 1.1 主机发现 arp-scan -l 1.2 端口与服务扫描 发现开放22、80、81端口 2 访问服务 2.1 访问80端口 查看源代码 2.2 访问81端口 3 目录扫描 3.1 dirsearch目录扫描 dirsearch -u 192.168.1.14 发现robots.txt文件和javascript文件 访问文件 http://192.168…

linux网络命令:httpie详解-简单易用的命令行 HTTP 客户端

目录 一、命令概述 二、基本特点 1、直观和友好的命令语句 2、内置 JSON 支持 3、支持多种请求方法 4、支持 HTTPS、代理和授权验证 5、支持多种请求数据格式 6、自定义 headers 头 7、持久 sessions 存储 8、插件支持 三、安装 1、对于基于 Debian 的系统&#xf…

【你也能从零基础学会网站开发】关系型数据库中的表(Table)设计结构以及核心组成部分

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;程序猿、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 关系型数据库中…

idea 项目互联网转内网开发 依赖报错问题 maven问题

场景&#xff1a; 这个问题困扰好久&#xff0c;通过分析后&#xff0c;发现是maven配置问题&#xff0c;废话不多说&#xff0c;上干活。 问题描述 项目互联网从转内网开发&#xff0c;提前下载好repository&#xff0c;跟项目一起导入内网&#xff0c;导入后&#xff0c;发…

Jasper Report详细使用教程

1、编写jrxml文件 1.1 新建项目 使用Jaspersoft Studio来创建一个项目&#xff0c;如图所示&#xff0c;新建一个项目&#xff0c;步骤&#xff1a; File -> New -> Project->JasperReportsProject 1.2 新建一个Jasper Report模板 找到你新建的项目。步骤&#xff1a;…

昇思25天学习打卡营第6天|简单的深度学习模型实战 - 函数式自动微分

自动微分(Automatic Differentiation)是什么&#xff1f;微分是函数在某一处的导数值&#xff0c;自动微分就是使用计算机程序自动求解函数在某一处的导数值。自动微分可用于计算神经网络反向传播的梯度大小&#xff0c;是机器学习训练中不可或缺的一步。 这些公式难免让人头大…

抛弃 Neofetch?众多优秀替代方案等你体验!

目录 抛弃 Neofetch&#xff1f;众多优秀替代方案等你体验Neofetch 的替代品FastfetchscreenFetchmacchina 抛弃 Neofetch&#xff1f;众多优秀替代方案等你体验 NeoFetch 是用 Bash 3.2 编写的命令行系统信息工具&#xff0c;该项目的主要开发人员已将 GitHub 存储库存档&…

【C++11:右值引用,列表初始化】

统一列表初始化&#xff1a; 构造函数的函数名与函数体之间增加一个列表&#xff0c;用于对成员初始化 在实例化对象时&#xff0c;支持单/多参数的隐式转化&#xff0c;同时也可以省略符号&#xff0c;让代码更简洁 右值的引用 左值&#xff1a; 左值与右值的重要区别就是能…

用代码实现加载中动图 loading.gif

效果 仅使用htmlcss&#xff0c;效果如下所示 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>加载中</title><style>.el-loading-spinner .circular {height: 42px;width: 42px;…