国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32使用HAL庫中外設(shè)初始化MSP回調(diào)機(jī)制及中斷回調(diào)機(jī)制詳解

這篇具有很好參考價(jià)值的文章主要介紹了STM32使用HAL庫中外設(shè)初始化MSP回調(diào)機(jī)制及中斷回調(diào)機(jī)制詳解。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

STM32使用HAL庫之Msp回調(diào)函數(shù)

1.問題提出

在STM32的HAL庫使用中,會(huì)發(fā)現(xiàn)庫函數(shù)大都被設(shè)計(jì)成了一對:

HAL_PPP/PPPP_Init

HAL_PPP/PPPP_MspInit

而且HAL_PPP/PPPP_MspInit函數(shù)的defination前面還會(huì)有__weak關(guān)鍵字

上面的PPP/PPPP代表常見外設(shè)的名稱為3個(gè)字符或者4個(gè)字符

怎么理解這個(gè)設(shè)計(jì)呢?

2.問題分析

2.1 結(jié)論

首先說結(jié)論:

  • HAL_PPP/PPPP_Init 是與具體芯片(無論是STM32F4/F1/F7)無關(guān)的設(shè)置

  • HAL_PPP/PPPP_MspInit 是與具體芯片相關(guān)的配置(如STM32F429IGTx)

這樣的設(shè)計(jì)是將不變的東西以庫函數(shù)HAL_PPP/PPPP_Init的形式固定下來,而將需要用戶根據(jù)

芯片進(jìn)行編寫的部分抽象成函數(shù)HAL_PPP/PPPP_MspInit的形式,用戶只需要編寫這部分函數(shù)

即可,這樣做減少了用戶的代碼編寫量

__weak關(guān)鍵字的使用是定義一個(gè)弱函數(shù),這個(gè)函數(shù)的函數(shù)體通常是空的

方便用戶重寫一個(gè)自己的函數(shù)HAL_PPP/PPPP_MspInit,來覆蓋之前庫函數(shù)中定義的函數(shù)帶有

__weak關(guān)鍵字的HAL_PPP/PPPP_MspInit函數(shù),編譯器在編譯的時(shí)候,如果檢查到有重名的

(但不含__weak關(guān)鍵字)HAL_PPP/PPPP_MspInit的函數(shù),此時(shí)就會(huì)默認(rèn)編譯這個(gè)用戶寫的函數(shù)

2.2 實(shí)例分析

下面以串口通信為例進(jìn)行分析:

在編寫串口通信的代碼的時(shí)候,常使用正點(diǎn)原子提供的usart.c&usart.h組合,正點(diǎn)原子在usart.c中

定義了HAL_UART_MspInit作為回調(diào)函數(shù):

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    // GPIO configuration
	GPIO_InitTypeDef GPIO_Initure;
	
	if(huart->Instance==USART1)
	{
		__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA 時(shí)鐘			
		__HAL_RCC_USART1_CLK_ENABLE();	// 使能USART1 時(shí)鐘	
	
		GPIO_Initure.Pin=GPIO_PIN_9;			//PA9
		GPIO_Initure.Mode=GPIO_MODE_AF_PP;	// AF復(fù)用,PP為推挽(push pull)	
		GPIO_Initure.Pull=GPIO_PULLUP;  // 設(shè)置上拉
		GPIO_Initure.Speed=GPIO_SPEED_FAST;  // 設(shè)置為高速
		GPIO_Initure.Alternate=GPIO_AF7_USART1;	  // 復(fù)用為USART1
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	  // 初始化PA9  	
 
		GPIO_Initure.Pin=GPIO_PIN_10;	//PA10
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);  // 初始化PA10	   	
		
#if EN_USART1_RX
		HAL_NVIC_EnableIRQ(USART1_IRQn);  // 使能USART1中斷通道			
		HAL_NVIC_SetPriority(USART1_IRQn,3,3);	// 搶占優(yōu)先級3, 子優(yōu)先級3		
#endif	
	}
 
}

這個(gè)庫同時(shí)提供了一個(gè)調(diào)用串口初始化的接口:void uart_init(u32 bound) // bound為波特率

void uart_init(u32 bound)
{	
	//UART initialization
	UART1_Handler.Instance=USART1;					    // USART1
	UART1_Handler.Init.BaudRate=bound;				    // 設(shè)置波特率
	UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   // 字長為8位的數(shù)據(jù)格式
	UART1_Handler.Init.StopBits=UART_STOPBITS_1;	    // 一個(gè)停止位
	UART1_Handler.Init.Parity=UART_PARITY_NONE;		    // 無奇偶校驗(yàn)位
	UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   // 無硬件流控
	UART1_Handler.Init.Mode=UART_MODE_TX_RX;		    // 收發(fā)模式
	HAL_UART_Init(&UART1_Handler);					    // HAL_UART_Init() 會(huì)使能UART1
	
	HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);
// 該函數(shù)會(huì)開啟接收中斷,標(biāo)志位UART_IT_RXNE,并設(shè)置接收緩沖以及接收緩沖的最大接收數(shù)量
  
}

這樣在main函數(shù)中,首先調(diào)用函數(shù)uart_init()

然后uart_init()函數(shù)就會(huì)去調(diào)用HAL_UART_Init,這個(gè)函數(shù)就是HAL庫中的函數(shù)

STM32使用HAL庫中外設(shè)初始化MSP回調(diào)機(jī)制及中斷回調(diào)機(jī)制詳解,STM32,stm32,單片機(jī),嵌入式硬件

跳轉(zhuǎn)到文件stm32f4xx_hal_uart.c,找到函數(shù)HAL_UART_Init的定義:

/**
  * @brief  Initializes the UART mode according to the specified parameters in
  *         the UART_InitTypeDef and create the associated handle.
  * @param  huart: pointer to a UART_HandleTypeDef structure that contains
  *                the configuration information for the specified UART module.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
{
  /* Check the UART handle allocation */
  if(huart == NULL)
  {
    return HAL_ERROR;
  }
 
  /* Check the parameters */
  if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
  { 
    /* The hardware flow control is available only for USART1, USART2, USART3 and USART6 */
    assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
    assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
  }
  else
  {
    assert_param(IS_UART_INSTANCE(huart->Instance));
  }
  assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
  assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
  
  if(huart->gState == HAL_UART_STATE_RESET)
  {  
    /* Allocate lock resource and initialize it */
    huart->Lock = HAL_UNLOCKED;
    /* Init the low level hardware */
    HAL_UART_MspInit(huart);
  }
 
  huart->gState = HAL_UART_STATE_BUSY;
 
  /* Disable the peripheral */
  __HAL_UART_DISABLE(huart);
  
  /* Set the UART Communication parameters */
  UART_SetConfig(huart);
  
  /* In asynchronous mode, the following bits must be kept cleared: 
     - LINEN and CLKEN bits in the USART_CR2 register,
     - SCEN, HDSEL and IREN  bits in the USART_CR3 register.*/
  huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN);
  huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
  
  /* Enable the peripheral */
  __HAL_UART_ENABLE(huart);
  
  /* Initialize the UART state */
  huart->ErrorCode = HAL_UART_ERROR_NONE;
  huart->gState= HAL_UART_STATE_READY;
  huart->RxState= HAL_UART_STATE_READY;
  
  return HAL_OK;
}

可以看到函數(shù)HAL_UART_Init中調(diào)用了函數(shù)HAL_UART_MspInit

在庫文件中本身是有一個(gè)同名的使用__weak關(guān)鍵字定義的函數(shù),

/**
  * @brief  UART MSP Init.
  * @param  huart: pointer to a UART_HandleTypeDef structure that contains
  *                the configuration information for the specified UART module.
  * @retval None
  */
 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
   /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_MspInit could be implemented in the user file
   */ 
}

由于使用了正點(diǎn)原子的庫,所以編譯器在編譯的時(shí)候就不會(huì)再編譯這個(gè)HAL庫自帶的函數(shù)HAL_UART_MspInit

而是編譯引入的庫函數(shù)HAL_UART_MspInit

3. STM32程序的一般執(zhí)行流程

由上面1.2節(jié)的分析,對于一個(gè)真實(shí)的STM32應(yīng)用程序可以總結(jié)其運(yùn)行一般執(zhí)行(編寫)流程如下:

以一個(gè)真實(shí)的點(diǎn)亮跑馬燈的main.c為例進(jìn)行分析(工程使用HAL庫):

#include "sys.h"
#include "delay.h"
#include "usart.h"
 
 
void Delay(__IO uint32_t nCount);
 
void Delay(__IO uint32_t nCount)
{
  while(nCount--){}
}
 
int main(void)
{
 
	GPIO_InitTypeDef GPIO_Initure;
     
    HAL_Init();                     
    Stm32_Clock_Init(360,25,2,8);   
 
    __HAL_RCC_GPIOB_CLK_ENABLE();        
	
    GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1; 
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; 
    GPIO_Initure.Pull=GPIO_PULLUP;        
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;   
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);
 
	while(1)
	{
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);	
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);				
		Delay(0x7FFFFF);
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);	
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);	
		Delay(0x7FFFFF);
	}
	}

這里插入正點(diǎn)原子的圖進(jìn)行解釋:
STM32使用HAL庫中外設(shè)初始化MSP回調(diào)機(jī)制及中斷回調(diào)機(jī)制詳解,STM32,stm32,單片機(jī),嵌入式硬件

一個(gè)項(xiàng)目首先是引導(dǎo)程序先運(yùn)行,匯編函數(shù)會(huì)引導(dǎo)SystemInit函數(shù)進(jìn)行系統(tǒng)初始化的設(shè)置,再HAL庫版本的項(xiàng)目中有這個(gè)函數(shù)的定義,在寄存器版本中通常會(huì)將匯編代碼中引導(dǎo)SystemInit函數(shù)的語句刪掉。然后引導(dǎo)程序會(huì)引導(dǎo)main函數(shù),main函數(shù)被引導(dǎo)完成之后就會(huì)開始執(zhí)行用戶寫的main函數(shù)中的代碼。然后HAL_Init()函數(shù)會(huì)調(diào)用函數(shù)進(jìn)行全局的MSP初始化,然后調(diào)用了正點(diǎn)原子提供的庫函數(shù)Stm32_Clock_init函數(shù),這個(gè)函數(shù)調(diào)用HAL_RCC_Oscconfig和HAL_RCC_ClockConfig函數(shù)進(jìn)行系統(tǒng)時(shí)鐘初始化,使用該函數(shù)需要導(dǎo)入SYSTEM庫(正點(diǎn)原子提供),上面的一系列初始化都是常規(guī)操作,也就是每一個(gè)項(xiàng)目必做的系統(tǒng)的初始化。下面正式進(jìn)入了用戶自己編寫得到邏輯,假設(shè)用戶要使用PPP外設(shè),那么就會(huì)調(diào)用HAL庫中的函數(shù)HAL_PPP_Init,這個(gè)函數(shù)又會(huì)去嘗試調(diào)用用戶自定義的HAL_PPP_MspInit,然后進(jìn)入用戶自己定義的邏輯。
————————————————
原文鏈接:《[STM32] NOTE07-STM32使用HAL庫之Msp回調(diào)函數(shù)理解》

STM32HAL庫中外設(shè)初始化MSP回調(diào)機(jī)制及中斷回調(diào)機(jī)制詳解

我們開始學(xué)習(xí)HAL庫的過程中,一定會(huì)發(fā)現(xiàn)與固件庫開發(fā)中外設(shè)初始化流程和中斷處理機(jī)制不相同,在這里將為大家解答一下心中的譯文。

HAL外設(shè)初始化MSP回調(diào)機(jī)制

在外設(shè)初始化函數(shù)中,HAL_PPP_Init();中需配置外設(shè)的相關(guān)參數(shù),外設(shè)用到的IO和NVIC和時(shí)鐘等放到HAL_PPP_MspInit()回調(diào)函數(shù)中。初始化函數(shù)會(huì)自動(dòng)調(diào)用回調(diào)函數(shù).
STM32使用HAL庫中外設(shè)初始化MSP回調(diào)機(jī)制及中斷回調(diào)機(jī)制詳解,STM32,stm32,單片機(jī),嵌入式硬件
STM32使用HAL庫中外設(shè)初始化MSP回調(diào)機(jī)制及中斷回調(diào)機(jī)制詳解,STM32,stm32,單片機(jī),嵌入式硬件

HAL庫中斷回調(diào)機(jī)制

HAL庫中中斷處理機(jī)制與固件庫中不同,他是經(jīng)過公共中斷處理函數(shù),自動(dòng)調(diào)用中斷處理回調(diào)函數(shù)。用戶想要再中斷中實(shí)現(xiàn)的邏輯代碼則要放在回調(diào)函數(shù)中,而公共中斷處理函數(shù)會(huì)幫你檢測是否有中斷發(fā)生,并幫你清除中斷標(biāo)志位。

STM32使用HAL庫中外設(shè)初始化MSP回調(diào)機(jī)制及中斷回調(diào)機(jī)制詳解,STM32,stm32,單片機(jī),嵌入式硬件
HAL_PPP_IRQHandler();公共中斷處理函數(shù),它會(huì)自動(dòng)調(diào)用中斷處理回調(diào)函數(shù)HAL_PPP_Callback()
用戶要寫在中斷服務(wù)處理函數(shù)中的邏輯代碼要放在回調(diào)函數(shù)中,公共中斷處理函數(shù)會(huì)幫你清除中斷標(biāo)志,并且自動(dòng)調(diào)用回調(diào)函數(shù)
STM32使用HAL庫中外設(shè)初始化MSP回調(diào)機(jī)制及中斷回調(diào)機(jī)制詳解,STM32,stm32,單片機(jī),嵌入式硬件
參考原文:《STM32HAL庫中外設(shè)初始化MSP回調(diào)機(jī)制及中斷回調(diào)機(jī)制詳解》文章來源地址http://www.zghlxwxcb.cn/news/detail-649622.html

到了這里,關(guān)于STM32使用HAL庫中外設(shè)初始化MSP回調(diào)機(jī)制及中斷回調(diào)機(jī)制詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STM32 cubemx CAN
STM32 CAN初始化詳解

    STM32 cubemx CAN STM32 CAN初始化詳解

    接收用到的結(jié)構(gòu)體如下: CAN概念: ? ? ? ? 全稱Controller Area Network,是一種半雙工,異步通訊。 物理層: ? ? ? ? 閉環(huán):允許總線最長40m,最高速1Mbps,規(guī)定總線兩端各有一個(gè)120Ω電阻,閉環(huán) ? ? ? ?開環(huán):最大傳輸距離1Km,最高速125Kbps,規(guī)定每根線串聯(lián)一個(gè)2.2kΩ的電阻,

    2024年02月13日
    瀏覽(29)
  • STM32的GPIO初始化配置-學(xué)習(xí)筆記

    STM32的GPIO初始化配置-學(xué)習(xí)筆記

    ? ? ? ? 由于剛開始沒有學(xué)懂GPIO的配置原理,導(dǎo)致后面學(xué)習(xí)其它外設(shè)的時(shí)候總是產(chǎn)生阻礙,因?yàn)槠渌庠O(shè)要使用前,大部分都要配置GPIO的初始化,因此這幾天重新學(xué)習(xí)了一遍GPIO的配置,記錄如下。 ? ? ? ? 首先我們要知道芯片上的引腳,并不是只有GPIO的功能,還能復(fù)用成

    2024年04月17日
    瀏覽(31)
  • STM32 串口的初始化(內(nèi)附詳細(xì)代碼)

    STM32 串口的初始化(內(nèi)附詳細(xì)代碼)

    首先我們先要根據(jù)原理圖來確認(rèn)我們用的串口接到了那個(gè)引腳 ?我這邊的串口1為例,接收端是PA10,發(fā)送端是PA9首先我們需要配置PA9和PA10. 把接受端配置成浮空輸入,完全靠引腳來判斷。把發(fā)送端配置成復(fù)用推挽模式,并打開GPIOA的時(shí)鐘和復(fù)用時(shí)鐘多的看代碼吧,我把注釋都寫

    2024年02月13日
    瀏覽(21)
  • STM32 GPIO設(shè)置(GPIO初始化)學(xué)習(xí)筆記

    STM32 GPIO設(shè)置(GPIO初始化)學(xué)習(xí)筆記

    GPIO 都知道是 通用輸入輸出接口 的意思就不詳細(xì)解釋 那么我們就直接進(jìn)入怎么設(shè)置GPIO接口: 這里我的編譯軟件是keil5,相信大家都應(yīng)該知道stm32有各種的工作模式上拉、下拉、推挽、開漏等等。如果想要了解具體的工作模式原理這里我推薦大家看:推挽 開漏 高阻 這都是誰

    2024年03月28日
    瀏覽(29)
  • STM32—TIM定時(shí)器初始化結(jié)構(gòu)體詳解

    STM32—TIM定時(shí)器初始化結(jié)構(gòu)體詳解

    ??注:高級控制定時(shí)器可以用到所有初始化結(jié)構(gòu)體,通用定時(shí)器不能使用 TIM_BDTRInitTypeDef 結(jié)構(gòu)體,基本定時(shí)器只能使用時(shí)基結(jié)構(gòu)體。 ?? 時(shí)基結(jié)構(gòu)體TIM_TimeBaseInitTypeDef用于定時(shí)器基礎(chǔ)參數(shù)設(shè)置,與TIM_TimeBaseInit函數(shù)配合使用完成配置。 (1) TIM_Prescaler:定時(shí)器預(yù)分頻器設(shè)置,

    2024年02月02日
    瀏覽(23)
  • STM32單片機(jī)同時(shí)初始化GPIOA和GPIOB

    要同時(shí)初始化STM32F1xx的GPIOA和GPIOB,您可以按照以下步驟進(jìn)行: 首先,在代碼中包含stm32f1xx.h頭文件 , 例如: 然后,使能GPIOA和GPIOB的時(shí)鐘 ,例如: 這將使能GPIOA和GPIOB的時(shí)鐘,以便進(jìn)行配置和使用。需要注意的是,STM32F103C8T6使用APB2總線驅(qū)動(dòng)GPIOA和GPIOB。 接下來,設(shè)置GPIOA和

    2024年02月14日
    瀏覽(139)
  • STM32/GD32學(xué)習(xí)指南-踩坑之(一)外部晶振配置,初始化失敗,不起振

    STM32/GD32學(xué)習(xí)指南-踩坑之(一)外部晶振配置,初始化失敗,不起振

    GD32使用外部有源晶振和無源晶振的問題,型號(hào)為GD32 F450 一、GD32配置使用外部晶振 1.使用外部無源晶振 找到startup_gd32f450_470.s匯編文件,找到SystemInit()函數(shù)跳轉(zhuǎn)進(jìn)去 在底部找到system_clock_config()函數(shù),再次跳轉(zhuǎn)進(jìn)去 選中宏定義:__SYSTEM_CLOCK_200M_PLL_IRC16M,跳轉(zhuǎn),如圖 將內(nèi)部時(shí)鐘

    2024年02月13日
    瀏覽(26)
  • STM32CubeMX v6.9.0 BUG:FLASH_LATENCY設(shè)置錯(cuò)誤導(dǎo)致初始化失敗

    STM32CubeMX v6.9.0 BUG:FLASH_LATENCY設(shè)置錯(cuò)誤導(dǎo)致初始化失敗

    今天在調(diào)試外設(shè)功能時(shí),發(fā)現(xiàn)設(shè)置了使用外部時(shí)鐘之后程序運(yùn)行異常,進(jìn)行追蹤調(diào)試并與先前可以正常運(yùn)行的項(xiàng)目進(jìn)行對比之后發(fā)現(xiàn)這個(gè)問題可能是由于新版本的STM32CubeMX配置生成代碼時(shí)的BUG引起的。 MCU: STM32H750VBT6 STM32CubeIDE: Version: 1.13.0 Build: 17399_20230707_0829 (UTC) STM32CubeMX: v

    2024年02月15日
    瀏覽(33)
  • 【STM32&RT-Thread零基礎(chǔ)入門】 5. 線程創(chuàng)建應(yīng)用(線程創(chuàng)建、刪除、初始化、脫離、啟動(dòng)、睡眠)

    【STM32&RT-Thread零基礎(chǔ)入門】 5. 線程創(chuàng)建應(yīng)用(線程創(chuàng)建、刪除、初始化、脫離、啟動(dòng)、睡眠)

    硬件:STM32F103ZET6、ST-LINK、usb轉(zhuǎn)串口工具、4個(gè)LED燈、1個(gè)蜂鳴器、4個(gè)1k電阻、2個(gè)按鍵、面包板、杜邦線 本章主要講線程的工作機(jī)制和管理方法,通過實(shí)例講解如何使用多線程完成多任務(wù)開發(fā)。 RT-Thread用線程控制塊來描述和管理一個(gè)線程,一個(gè)線程對應(yīng)一個(gè)線程控制塊。線程控

    2024年02月12日
    瀏覽(26)
  • 通用輸入輸出端口GPIO,及其初始化(HAL庫)

    我在學(xué)習(xí)STM32時(shí)候呢,是直接先接觸的STM32CubeMX軟件,更著網(wǎng)上各種教程迷迷糊糊學(xué)了一大堆沒用的東西,于是先一步步來吧,我總結(jié)了很長時(shí)間,希望對正在學(xué)習(xí)相關(guān)知識(shí)的朋友們有幫助。 可以先去看看STM32CubeMX如何配置:傳送門 讀完以上我寫的文章基本上是蒙的,因?yàn)槲?/p>

    2024年02月09日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包