03:HAL---中断

news/2024/11/29 21:41:06/

目录

一:中断

1:简历

2:AFIO

 3:EXTI

 4:NVIC基本结构

5:使用步骤

6:设计中断函数

二:中断的应用

A:对外式红外传感计数器

1:硬件介绍

 2:计数代码

B:旋转编码计数器

 1:硬件介绍

2:旋转编码器代码

C:按键控制LED

D:代码总结


一:中断

1:简历

        中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行

        中断优先级:当有多个中断源同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源

        中断嵌套:当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回; 注意那种优先级可以插队,那种不能插队;见下面的NVIC基本结构

        STM32中断: 68个可屏蔽中断通道,包含EXTI、TIM、ADC、USART、SPI、I2C、RTC等多个外设 使用NVIC统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级 (EXTI可以产生中断的,众多外设之一)

STM32外部中断简图

2:AFIO

        AFIO主要用于引脚复用功能的选择和重定义

        在STM32中,AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择

注意配置那个引脚为中断引脚的时候,中断函数要一致。

PX5--PX9对应中断服务函数为:EXTI9_5_IRQHandler

PX10--PX15对应中断服务函数为:EXTI15_10_IRQHandler

中断服务函数在启动的汇编文件中定义;中断请求号在stm32f103xb.h文件中定义(STM32F103C8T6)

 3:EXTI

 EXTI简介:
        EXTI(Extern Interrupt)外部中断

        EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序

        支持的触发方式:上升沿/下降沿/双边沿/软件触发

        支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断     (PA1、PB1、PC1这样的,PAO和PBO这样的相同的Pin只能选1个作为中断引脚)  PA6和PA7、PA9和PB15、PBO和PB1这样的都可以---对应上面的AFIO   EXTI和IO的对应关系

原因:AFOI会在APIOA,APIO,APIOC中选择一个GPIO的16个引脚连接到后面的EXTI

        通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒

触发响应方式:中断响应/事件响应

基本结构:

exit0,exit1,exit2,exit3,exit4,exit9_5,exit15_10;  一共有7个中断服务函数,而5-9共用一个中断服务函数,10-15共用一个中断服务函数,

EXTI框图

 4:NVIC基本结构

嵌套中断向量控制器: 用来统一分配断优先级和管理中断的

基本概念

注意那种优先级可以插队,那种不能插队

 NVIC优先级分组:

         NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级(更加紧急)和低4-n位的响应优先级(紧急)抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和响应优先级均相同的按中断号排队   (中断号:EXTI简历中的优先级)

        抢占优先级>响应优先级>自然优先级

        优先级的数是值越小,优先级越高,0就是最高优先级

分组为0: 0位抢占优先级(没有抢占优先级),4位响应优先级(2^4=16--16个响应优先级)

分组为1: 1位抢占优先级(2^1=2,2个抢占优先级),3位响应优先级(2^3=8--8个响应优先级)

.................

配置NVIC的步骤:

 在HAL_Init();  HAL库初始化函数中已经分组过了,所以这就以为这我们可以不要在进行分组。

中断请求号在stm32f103xb.h文件中定义;   第二步和第三步的第一个形参中断请求号在stm32f103xb.h文件中定义

5:使用步骤

步骤1:的使能时钟函数在stm32f1xx _hal_rcc.h定义

步骤2:开启AFIO函数在stm32f1xx hal _gpio.h定义

步骤3,4,5:是配置NVIC的步骤在stm32f1xx hal _gpio.h定义了

步骤6:自己设计中断服务函数(发生中断了要干什么事情)

6:设计中断函数

实际上就是 5:使用步骤里面的步骤6的讲解,以为和标准库不太一样

        中断服务函数:已经固定好了,使用那个EXIT线就选择那个,在汇编文件中固定(实际上就是函数的名字已经固定好了,必须使用人家固定的函数名字)

        HAL库中断处理公用函数:HAL_GPIO_EXTI_IRQHandler 在stm32f1xx hal gpio.h文件中定义
        HAL库数据处理回调函数:HAL_GPIO_EXTI_Callback      在stm32f1xx hal gpio.h文件中定义

下面为ST公司HAL库中使写的

/*** @brief  This function handles EXTI interrupt request.* @param  GPIO_Pin: Specifies the pins connected EXTI line* @retval None*/
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{/* EXTI line interrupt detected */if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u){__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);HAL_GPIO_EXTI_Callback(GPIO_Pin);}
}/*** @brief  EXTI line detection callbacks.* @param  GPIO_Pin: Specifies the pins connected EXTI line* @retval None*/
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{/* Prevent unused argument(s) compilation warning */UNUSED(GPIO_Pin);/* NOTE: This function Should not be modified, when the callback is needed,the HAL_GPIO_EXTI_Callback could be implemented in the user file*/
}

这段代码是用于处理外部中断(EXTI)的回调函数。在STM32微控制器中,外部中断可以由外部事件触发,例如按键按下、传感器信号变化等。

  1. HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin): 这是一个公共中断处理函数,用于处理外部中断。当外部中断发生时,这个函数会被调用。函数参数GPIO_Pin表示触发中断的GPIO引脚。

    • 首先,函数通过__HAL_GPIO_EXTI_GET_IT(GPIO_Pin)检查指定GPIO引脚是否有中断事件发生。如果有,它会返回一个非零值。
    • 如果检测到中断,函数会首先通过__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin)清除中断标志,确保下次中断事件可以再次触发。
    • 然后,它会调用HAL_GPIO_EXTI_Callback(GPIO_Pin)函数,这是一个回调函数,用于处理具体的中断事件。
  2. HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin): 这是一个回调函数,用于处理具体的外部中断事件。默认情况下,这个函数是空的,没有任何操作。用户可以在自己的代码中实现这个函数,以处理特定的中断事件。

    • 在这个函数的实现中,UNUSED(GPIO_Pin);这一行用于防止编译器因为GPIO_Pin参数未被使用而发出警告。如果在实际使用中,用户需要知道是哪个GPIO引脚触发了中断,他们可以在这个函数中处理GPIO_Pin参数。
    • 注释中提到了:“当需要回调函数时,可以在用户文件中实现HAL_GPIO_EXTI_Callback”。这意味着用户可以在自己的代码中重写这个函数,以实现特定的中断处理逻辑。

总的来说,这段代码提供了一个处理外部中断的框架,用户可以在此基础上添加自己的中断处理逻辑。

自己写的中断函数

1:写出中断函数,在中断函数调用公共中断处理函数;不放心的话也可以在清除一遍我们的中断标志位(可选,因为在我们的公共中断处理函数已经清理过了)。

2:然后在写回调函数,回调函数里面写发生中断要干的事情。(回调函数的名字要和ST公司的HAL回调函数的名字一样,不能更改)

下面是一个实例:

void EXTI4_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_4);
}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{delay_ms(20);if(GPIO_Pin == GPIO_PIN_4){if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4)==0){HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);}}
}

二:中断的应用

A:对外式红外传感计数器

        AO(模拟输出)是指传感器输出一个连续变化的电压或电流信号,这个信号与传感器检测到的物体距离、速度或其他参数成比例关系。在红外传感计数器中,AO输出可能用于表示检测到的物体数量或通过的频率,以模拟信号的形式进行传输。这种输出方式适用于需要精确测量或连续监控的应用场景。

        DO(数字输出)则是指传感器输出一个离散的电平信号,通常是高电平或低电平,用于表示检测到的物体状态或计数结果。在红外传感计数器中,DO输出可能用于指示物体是否通过、计数是否达到预设值等离散事件。这种输出方式适用于需要简单判断或控制的应用场景

本实验:我们这里只使用DO线不使用AD;使用一个中断

1:硬件介绍

 2:计数代码

对外式红外传感计数器的亮灭来控制产生中断,然后开关灯

void LED_Init(void)
{__HAL_RCC_GPIOB_CLK_ENABLE() ;GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Mode=GPIO_MODE_OUTPUT_PP;GPIO_InitType.Pin=GPIO_PIN_5;GPIO_InitType.Pull=GPIO_NOPULL;GPIO_InitType.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&GPIO_InitType); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);}	
void LED_Exit_Init(void)
{__HAL_RCC_GPIOB_CLK_ENABLE() ;GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Mode=GPIO_MODE_OUTPUT_PP;GPIO_InitType.Pin=GPIO_PIN_6;GPIO_InitType.Pull=GPIO_NOPULL;GPIO_InitType.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&GPIO_InitType); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);}	void Exit_Init1(void)
{__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Mode=GPIO_MODE_IT_RISING; //中断的下降沿触发GPIO_InitType.Pin=GPIO_PIN_5;GPIO_InitType.Pull=GPIO_PULLUP; //上拉模式GPIO_InitType.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA,&GPIO_InitType);HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);HAL_NVIC_SetPriority(EXTI9_5_IRQn,2,0);HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);}void EXTI9_5_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_5);}//中断处理函数;发生中断来这里
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin==GPIO_PIN_5){		if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==1){HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_6);}}}
int main(void)
{HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */LED_Init();                        /* LED初始化 */LED_Exit_Init();Exit_Init1();while(1){HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);}}

B:旋转编码计数器


        本实验使用的是EC11旋转编码器,这是一种增量式旋转编码器,拥有A、B、C三个输出通道,其中A、B两相输出正交信号,相位差为90°,C相输出零脉冲信号,用于标识位置。当编码器正转时,A相的输出信号超前B相90°;当编码器反转时,A相滞后B相90°。我们在程序中可以根据A、B两相信号输出的先后顺序,来判断旋转编码器是正转还是反转。

我们使用A和B,不使用c;使用了二个中断

 1:硬件介绍

 我们使用判断正反转的条件:

        正转-----B相下降沿和A相低由平时同时满足时;

        反转----在A相下降沿和B相低电频同时满足时;

2:旋转编码器代码

void LED_Init(void)
{__HAL_RCC_GPIOB_CLK_ENABLE() ;GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Mode=GPIO_MODE_OUTPUT_PP;GPIO_InitType.Pin=GPIO_PIN_5;GPIO_InitType.Pull=GPIO_NOPULL;GPIO_InitType.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&GPIO_InitType); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);}	
void LED_Exit_Init(void)
{__HAL_RCC_GPIOB_CLK_ENABLE() ;GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Mode=GPIO_MODE_OUTPUT_PP;GPIO_InitType.Pin=GPIO_PIN_6;GPIO_InitType.Pull=GPIO_NOPULL;GPIO_InitType.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&GPIO_InitType); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);}	void Exit_Encoder_Init(void)
{__HAL_RCC_GPIOB_CLK_ENABLE();///配置GPIOB的第12个引脚为下降沿中断GPIO_InitTypeDef GPIO_InitType1;GPIO_InitType1.Mode=GPIO_MODE_IT_FALLING; GPIO_InitType1.Pin=GPIO_PIN_12;GPIO_InitType1.Pull=GPIO_PULLUP; //上拉模式GPIO_InitType1.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&GPIO_InitType1);// 配置GPIOB的第13个引脚为上升沿中断  GPIO_InitTypeDef GPIO_InitType2;GPIO_InitType2.Mode=GPIO_MODE_IT_FALLING; GPIO_InitType2.Pin=GPIO_PIN_13;GPIO_InitType2.Pull=GPIO_PULLUP; //上拉模式GPIO_InitType2.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&GPIO_InitType2);HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);HAL_NVIC_SetPriority(EXTI15_10_IRQn,2,0);HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);}void EXTI15_10_IRQHandler(void)  
{  // 检查是否是GPIOB的第12个引脚触发的中断  if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_12) != RESET)  {  // 清除GPIOB的第12个引脚的中断标志位  __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_12);  // 调用HAL库的中断处理回调函数  HAL_GPIO_EXTI_Callback(GPIO_PIN_12);  }  // 检查是否是GPIOB的第13个引脚触发的中断  if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_13) != RESET)  {  // 清除GPIOB的第13个引脚的中断标志位  __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_13);  // 调用HAL库的中断处理回调函数  HAL_GPIO_EXTI_Callback(GPIO_PIN_13);  }  
} //中断处理函数;发生中断来这里
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{//正转if(GPIO_Pin==GPIO_PIN_13){		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13)==0){		delay_ms(10);HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);delay_ms(10);}}//反转if(GPIO_Pin==GPIO_PIN_13){		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12)==0){		delay_ms(10);HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_6);delay_ms(10);}}}int main(void)
{HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */LED_Init();                        /* LED初始化 */LED_Exit_Init();Exit_Encoder_Init();while(1){}}

        在STM32微控制器中,当中断被触发时,对应的中断标志位会被硬件置为1。但具体的中断标志位值并不是一个简单的数字,而是与具体的中断源和寄存器相关。每个中断源在特定的寄存器中都有自己对应的中断标志位,通常是一个二进制位

C:按键控制LED

正常工作的时候一个LED正常亮灭,当按键按下的时候控制LED的开和关,使用一个中断

void LED_Init(void)
{__HAL_RCC_GPIOB_CLK_ENABLE() ;GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Mode=GPIO_MODE_OUTPUT_PP;GPIO_InitType.Pin=GPIO_PIN_5;GPIO_InitType.Pull=GPIO_NOPULL;GPIO_InitType.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&GPIO_InitType); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);}	
void LED_Exit_Init(void)
{__HAL_RCC_GPIOB_CLK_ENABLE() ;GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Mode=GPIO_MODE_OUTPUT_PP;GPIO_InitType.Pin=GPIO_PIN_6;GPIO_InitType.Pull=GPIO_NOPULL;GPIO_InitType.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&GPIO_InitType); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);}	void Exit_Init(void)
{__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Mode=GPIO_MODE_IT_FALLING; //中断的下降沿触发GPIO_InitType.Pin=GPIO_PIN_1;GPIO_InitType.Pull=GPIO_PULLUP; //上拉模式GPIO_InitType.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&GPIO_InitType);HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);HAL_NVIC_SetPriority(EXTI1_IRQn,2,0);HAL_NVIC_EnableIRQ(EXTI1_IRQn);}void EXTI1_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);}//中断处理函数;发生中断来这里
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{delay_ms(10);if(GPIO_Pin==GPIO_PIN_1){		//按下if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0){delay_ms(10);while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0);HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_6);}		}}
int main(void)
{HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */LED_Init();                        /* LED初始化 */LED_Exit_Init();Exit_Init();while(1){HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);}}

D:代码总结

        不管有几个中断我们,我们自己写的中断服务函数和处理中断的函数不要我们定义,在HAL库中已经定义了。

void EXTI1_IRQHandler(void)
{
         //注意名字要中断相同
}


//中断处理函数;发生中断来这里
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
        //不管几个中断函数,这个函数只能写一个,不然不能编译

}

在中断模式下选择GPIO的模式(GPIO_InitType.Mode):应该选择那个方式触发中断(而不是常规的8中模式)

GPIO_InitTypeDef GPIO_InitType;GPIO_InitType.Mode=GPIO_MODE_OUTPUT_PP;
GPIO_InitType.Pin=GPIO_PIN_5;
GPIO_InitType.Pull=GPIO_NOPULL;
GPIO_InitType.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&GPIO_InitType); 

本节参考资料: 

链接:https://pan.baidu.com/s/1peVcD-rf3Chd5b-A-0SEtg?pwd=5j2p 
提取码:5j2p 
--来自百度网盘超级会员V2的分享


http://www.ppmy.cn/news/1379627.html

相关文章

cpu masks的初始化

在内核中,有几个位图变量是用作标识cpu数量和状态的,它们分别是: 变量名称用途循环所使用的宏cpu_possible_mask系统中有多少个可以运行的cpu核for_each_possible_cpucpu_present_mask系统中有多少个可处于运行状态的cpu核for_each_present_…

【漏洞复现】Linksys E2000 position.js 身份验证绕过漏洞(CVE-2024-27497)

0x01 产品简介 Linksys E2000是一款由思科(Cisco)品牌推出的无线路由器,它是一款支持2.4GHz和5GHz双频段的无线路由器,用户可以避开拥挤的2.4GHz频段,独自享受5GHz频段的高速无线生活。 0x02 漏洞概述 Linksys E200…

Java实现Tron(波场)区块链的开发实践(三)波场链水龙头、WEB3测试实战

上一节我们具体讲到Java实现Tron波场链的逻辑代码实现。 这一节我们通过部署和开发好的代码,针对测试链进行自测开发,准备测试环境。 1. 创建离线地址 首先我们需要一个离线地址,我们不需要在线进行创建,直接可以通过第一节的离…

Java线程锁之Lock的使用

Lock 的使用 Lock 是java 1.5 中引入的线程同步工具,它主要用于多线程下共享资源的控制。本质上Lock 仅仅是一个接口, 可以通过显式定义同步锁对象来实现同步,能够提供比synchronized 更广泛的锁定操作,并支持多个相关的 Lock接…

快速入门:JS对象/BOM/DOM/事件监听

本贴介绍JS相对进阶的知识,对于JavaScript的基础语法,本文不再赘述~ 一.JavaScript对象 1.Array数组对象 定义 var arr new Array(1,2,3); var arr[1,2,3]; 访问 arr[0]1; Js数组类似Java中的集合,长度,类型都可以改变。 如…

【JS】APIs:事件流、事件委托、其他事件、页面尺寸、日期对象与节点操作

1 事件流 捕获阶段&#xff1a;从父到子 冒泡阶段&#xff1a;从子到父 1.1 事件捕获 <body> <div class"fa"><div class"son"></div> </div> <script>const fadocument.querySelector(.fa);const sondocument.qu…

快速了解Redis

Redis是什么&#xff1f; Redis是一个数据库&#xff0c;是一个跨平台的非关系型数据库&#xff0c;Redis完全开源&#xff0c;遵守BSD协议。它通过键值对(Key-Value)的形式存储数据。 与传统数据库不同的是 Redis 的数据是存在内存中的 &#xff0c;也就是它是内存数据库&am…

跨境电商亚马逊listing埋词技巧,保姆级教程教会你

在亚马逊这个竞争激烈的市场中&#xff0c;只有优秀的选品和质量是远远不够的&#xff0c;一个精心制作的产品页面&#xff08;Listing&#xff09;对于提升销量和排名至关重要。如果你发现自己的商品质量和推广都不错&#xff0c;但销量和排名始终不见起色&#xff0c;那可能就…