普冉PY32系列(十五) PY32F0系列的低功耗模式

来源:https://www.cnblogs.com/milton/p/18168592
-Advertisement-
Play Games

Cortex M0/M0+相對於Cortex M3/M4性能稍弱, 但是優勢在於低價格和低功耗, 這使得M0特別適合性能要求不高且電池供電的便攜類應用, 比如遙控器, 墨水屏, 電子寵物, 電子煙等. 根據 PY32F0 各型號的數據手冊, 對比其最低功耗狀態(STOP模式)下的電流, 全系列可以大... ...


目錄

聲明

任何在廠家數據手冊之外的資源都是無保證的, 本文內容僅對當前測試中使用的樣品有效, 請勿以此作為選型參考, 一切以廠家手冊為準. 因為使用本文數據產生的任何問題本人概不負責.


PY32F0系列的低功耗

Cortex M0/M0+相對於Cortex M3/M4性能稍弱, 但是優勢在於低價格和低功耗, 這使得M0特別適合性能要求不高且電池供電的便攜類應用, 比如遙控器, 墨水屏, 電子寵物, 電子煙等. 根據 PY32F0 各個型號的數據手冊, 對比其最低功耗狀態(STOP模式)下的電流, 全系列可以大致分為三檔

  1. PY32F04x PY32F07x: 最低 10.5 uA
  2. PY32F030 PY32F003 PY32F002A: 最低 4.5 uA
  3. PY32F002B: 最低 1.5 uA

可以看出待機功耗和片上外設的豐富程度基本上是成正比的.

  • PY32F04X外設豐富功耗也大, 面向的是替代M3的場景, 低功耗可能不是最重要的特性
  • PY32F030 系列, PY32F002A是一個特例, 具體原因大家也都知道的
  • PY32F002B 資源最少, 但是功耗非常低, 待機電流1.5uA. 實際測試電流能做到1uA以下(看本文末尾的說明)

電池供電的便攜設備, 待機功耗基本上要控制在十個uA以內. 例如一個用主板電池CR2032供電的設備要求一年的電池使用壽命. CR2032電量為200mAH, 假定工作電流20mA, 待機5uA, 工作時間占比0.1%(比如每隔十秒採集上報一次數據, 上報耗時10毫秒), 電池壽命就差不多是一年. 對於這種場景使用 PY32F030 系列比較勉強, 而使用 PY32F002B 則功耗還有富餘.

這裡具體說明 PY32F030(適用於PY32F003和PY32F002A) 和 PY32F002B 這兩類型號的低功耗設置.

測試方法

要測量的目標為 10uA 以下的電流, 可以用萬用表的微安檔, 但是MCU啟動狀態和正常工作狀態電流差異巨大, 從十幾個mA到幾個uA, 為方便測量, 可以在萬用表的正負極並聯一個開關, 啟動時開關閉合, 電流走開關, 當工作穩定後開關打開, 由微安表讀出電流.

因為測量微小電流很容易受電路其它元件干擾, 為避免因為各種電流泄漏造成的測試結果不准確:

  1. 不要用普通的開發板(除非是專門設計用於測試低功耗場景的), 用簡單的分線板最可靠
  2. 不要用低管腳數的封裝, 因為存在管腳復用的情況, 當復用的管腳沒有正確配置時, 在內部管腳之間也會產生電流泄漏

PY32F030 系列(PY32F002A, PY32F003, PY32F030)

這個系列屬於 PY32F0 中的通用型號, 片上資源可以滿足大部分場景的需求. 待機電流雖然沒那麼低(4.5uA), 但是面對普通電池應用也是綽綽有餘, 一節五號電池可以輕鬆工作半年以上. PY32F030 系列低功耗狀態支持兩種模式 SLEEP 和 DEEP SLEEP(STOP).

  • 正常運行模式下, 使用LSI可以顯著降低功耗, 啟用Flash睡眠後功耗電流可以控制到 100uA 以內
  • SLEEP 模式下只是關閉了CPU時鐘, 外設還能工作, 時鐘頻率高的時候切換到SLEEP後節能效果明顯, 時鐘頻率越低則越無區別, 根據時鐘源為HSI還是LSI, 電流大小區間為 0.1 mA 到 2.x mA
  • STOP 模式大部分外設停止, 時鐘 HSI, HSE 和 PLL 停止. LPTIM 基於 LSI 工作, 當切換到低壓調節器後, 電流大小在 4.5 uA 到 6 uA 區間

工作於內置低速時鐘LSI時的功耗控制

下麵的代碼用於演示如何從內部高速時鐘切換到內部低速時鐘, 並一步步降低功耗

/**
 * 啟用LSI並將其設為系統時鐘
 */
static void APP_RCC_LSI_Config(void)
{
  LL_RCC_LSI_Enable();
  while(LL_RCC_LSI_IsReady() != 1);
  
  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
  
  /* 設置 LSI 為系統時鐘源 */
  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_LSI);
  while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_LSI);
  
  LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);

  LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
  LL_SetSystemCoreClock(LSI_VALUE);
  /* 重設 SysTick 時鐘計數周期, 如果沒有這步, LL_mDelay()延遲就會不正常 */
  LL_Init1msTick(32768);
}

int main(void)
{
  // 設置 HSI 24MHz 作為系統時鐘
  BSP_RCC_HSI_24MConfig();
  // 系統運行於 HSI, 測得電流約 1.3 mA
  LL_mDelay(3000);
  // 系統時鐘切換到內部低速時鐘 LSI
  APP_RCC_LSI_Config();
  // 系統運行於 LSI, 但是 HSI 未關閉, 電流約 360 uA
  LL_mDelay(3000);
  // 關閉 HSI
  LL_RCC_HSI_Disable();
  // 電流降至約 180 uA
  LL_mDelay(3000);
  // 開啟 flash sleep
  SET_BIT(FLASH->STCR, FLASH_STCR_SLEEP_EN);
  // 電流降至約 100 uA
  while (1);
}

測量的時候, 可以觀察到上電後, 每隔三秒電流會降一檔, 切換時鐘源到 LSI 後, 從 1.3mA 降到 360uA, 關閉 HSI 後, 降到 180uA, 啟用 Flash Sleep 後, 降到 100 uA 以內.

進入 SLEEP 模式

進入SLEEP模式的代碼很簡單, 啟用PWR時鐘並調用LL_LPM_EnableSleep就啟用了SLEEP, 然後等待事件或中斷喚醒

// 使能低功耗控制模塊(PWR)時鐘
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
// 設置低功耗狀態為 Sleep, 清除SLEEPDEEP狀態位, CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk))
LL_LPM_EnableSleep();

/*
 * 等待事件喚醒
 * 如果是等待中斷, 將下麵的代碼換成 __WFI();
 */
__SEV();
__WFE();
__WFE();

進入 STOP 模式

啟用低功耗STOP模式, 並等待事件喚醒.

註意這裡面的LL_PWR_SetRegulVoltageScaling方法, 如果 STOP 模式下測得的電流一直在 6 uA 以上, 很可能是電壓沒有調整為 1.0V

// 使能低功耗控制模塊(PWR)時鐘
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
/*
 * 設置低功耗STOP電壓為1.0V, 預設電壓為1.2V, 會增大電流, 
 * 對於 PY32F030 系列, 1.0V和1.2V對應的電流為 4.5uA~4.8uA 和 6uA ~ 7uA
 */
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE2);
/*
 * 設置電壓調節器從工作狀態轉換為低功耗狀態, SET_BIT(PWR->CR1, PWR_CR1_LPR)
 * 在開啟 STOP 模式前, 必須調用這個方法
 */
LL_PWR_EnableLowPowerRunMode();
/*
 * 設置低功耗狀態的模式為Deep sleep, 即STOP模式, 
 * 對應寄存器命令為 SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
 */
LL_LPM_EnableDeepSleep();

/*
 * 等待事件喚醒
 * 如果是等待中斷, 將下麵的代碼換成 __WFI();
 */
__SEV();
__WFE();
__WFE();

/*
 * 退出 STOP 模式時, 設置低功耗狀態為 Sleep, 清除SLEEPDEEP狀態位, 
 * 對應寄存器命令為 CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk))
 */
LL_LPM_EnableSleep();

事件喚醒和中斷喚醒 - 按鍵喚醒

下麵配置的外部中斷, 用於事件喚醒或中斷喚醒 SLEEP/STOP 模式

static void APP_EXTIConfig(void)
{
  LL_GPIO_InitTypeDef GPIO_InitStruct;
  LL_EXTI_InitTypeDef EXTI_InitStruct;

  // GPIOA時鐘使能
  LL_IOP_GRP1_EnableClock (LL_IOP_GRP1_PERIPH_GPIOA);
  // 選擇PA06引腳
  GPIO_InitStruct.Pin = LL_GPIO_PIN_6;
  // 選擇輸入模式
  GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
  // 選擇上拉
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  // GPIOA初始化
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  // 選擇EXTI6做外部中斷輸入
  LL_EXTI_SetEXTISource(LL_EXTI_CONFIG_PORTA,LL_EXTI_CONFIG_LINE6);
  // 選擇EXTI6
  EXTI_InitStruct.Line = LL_EXTI_LINE_6;
  // 使能
  EXTI_InitStruct.LineCommand = ENABLE;
  /*
   * 選擇中斷模式
   * 事件喚醒使用 EXTI_InitStruct.Mode = LL_EXTI_MODE_EVENT;
   * 中斷喚醒使用 EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
   */
  EXTI_InitStruct.Mode = LL_EXTI_MODE_EVENT;
  // 選擇下降沿觸發
  EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
  // 外部中斷初始化
  LL_EXTI_Init(&EXTI_InitStruct);

  // 設置中斷優先順序
  NVIC_SetPriority(EXTI4_15_IRQn,1);
  // 使能中斷
  NVIC_EnableIRQ(EXTI4_15_IRQn);
}

如果配置為中斷喚醒, 那麼還需要加上下麵的中斷回調函數清理中斷位

void EXTI4_15_IRQHandler(void)
{
  if(LL_EXTI_ReadFlag(LL_EXTI_LINE_6) == LL_EXTI_LINE_6)
  {
    LL_EXTI_ClearFlag(LL_EXTI_LINE_6);
  }
}

LPTIM 喚醒 - 自動間隔喚醒

PY32F030 系列的 LPTIM 只有LL_LPTIM_OPERATING_MODE_ONESHOT這一種模式, 不能連續載入. 如果需要保持定期喚醒, 需要在主迴圈中, 再次開始 LPTIM 計數 LL_LPTIM_StartCounter.

配置 LPTIM 的代碼

// 開啟 LPTIM1時鐘
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPTIM1);
// 開啟內部低速時鐘 LSI
LL_RCC_LSI_Enable();
while(LL_RCC_LSI_IsReady() == 0);
// 配置LSI為LPTIM時鐘源 Freq = 32.768 kHz
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSI);

// LPTIM預分頻器128分頻
LL_LPTIM_SetPrescaler(LPTIM1,LL_LPTIM_PRESCALER_DIV128);
// LPTIM計數周期結束更新ARR
LL_LPTIM_SetUpdateMode(LPTIM1,LL_LPTIM_UPDATE_MODE_ENDOFPERIOD);

// 使能NVIC請求
NVIC_SetPriority(LPTIM1_IRQn,0);
NVIC_EnableIRQ(LPTIM1_IRQn);

// 使能ARR中斷
LL_LPTIM_EnableIT_ARRM(LPTIM1);
// 使能LPTIM
LL_LPTIM_Enable(LPTIM1);
// 配置重裝載值 51
LL_LPTIM_SetAutoReload(LPTIM1,51);

配合中斷回調函數

void LPTIM1_IRQHandler(void)
{
  if(LL_LPTIM_IsActiveFlag_ARRM(LPTIM) == 1)
  {
    // 清理中斷標誌位
    LL_LPTIM_ClearFLAG_ARRM(LPTIM);
    // 自定義的中斷處理方法
    APP_LPTIMCallback();
  }
}

在使用時, 在每一個迴圈中先進入低功耗狀態, 開啟LPTIM, 然後進入STOP 等待中斷, MCU會阻塞在__WFI()方法. 當 LPTIM 計數結束後會喚醒 MCU 繼續往下執行.

// 使能低功耗狀態
LL_PWR_EnableLowPowerRunMode();
// 重啟 LPTIM
LL_LPTIM_Disable(LPTIM1);
LL_LPTIM_Enable(LPTIM1);
// 等待
APP_uDelay(65);
// 開啟LPTIM單次模式
LL_LPTIM_StartCounter(LPTIM1,LL_LPTIM_OPERATING_MODE_ONESHOT);
// 使能STOP模式並等待中斷喚醒
LL_LPM_EnableDeepSleep();
__WFI();

PY32F002B

PY32F002B 片上資源相比 PY32F030 系列縮水了不少, 存儲只有 24K flash / 3K RAM, 只有兩個定時器, 還只有一個定時器帶4個IO輸出, 但是勝在低功耗, STOP 模式電流只有 1.5 uA, 可以勝任很多低功耗的需求.

進入 SLEEP 模式

  • PY32F002B 的 SLEEP 模式電流在 1 mA 以下, 整體比正常運行模式低 20% 左右
  • PY32F002B 的 STOP 模式, 當切換到低壓調節器後, 電流大小陡然降到 1.5 uA - 1.7 uA 區間

啟用 SLEEP 模式的代碼和 PY32F030 完全一樣

// Enable PWR clock
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
// Enter Sleep mode
LL_LPM_EnableSleep();
/*
 * 等待事件喚醒
 * 如果是等待中斷, 將下麵的代碼換成 __WFI();
 */
__SEV();
__WFE();
__WFE();

進入 STOP 模式

PY32F002B 開啟 STOP 模式的過程和 PY32F030 系列有區別

  1. 下麵的LL_PWR_SetLprMode等價於F030中的LL_PWR_EnableLowPowerRunMode方法, 都是切換到低電壓調節器
  2. 使用LL_PWR_SetStopModeSramVoltCtrl設置SRAM保持電壓
  3. 啟用 Deep Sleep (STOP) 模式
  4. 等待事件或中斷喚醒
// 使能低功耗控制模塊(PWR)時鐘
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
// STOP 模式啟用低電壓調節器
LL_PWR_SetLprMode(LL_PWR_LPR_MODE_LPR);
// SRAM保持電壓與數字LDO輸出對齊
LL_PWR_SetStopModeSramVoltCtrl(LL_PWR_SRAM_RETENTION_VOLT_CTRL_LDO);

// Enter DeepSleep mode
LL_LPM_EnableDeepSleep();

/*
 * 等待事件喚醒
 * 如果是等待中斷, 將下麵的代碼換成 __WFI();
 */
__SEV();
__WFE();
__WFE();

LL_LPM_EnableSleep();

事件喚醒和中斷喚醒 - 按鍵喚醒

PY32F002B 的按鍵喚醒和 PY32F030 系列是一樣的, 略.

LPTIM 喚醒 - 定時器自動喚醒

配置 LPTIM, PY32F002B 的 LPTIM 和 PY32F030 系列相比, 增加了一個連續模式 LL_LPTIM_OPERATING_MODE_CONTINUOUS.

  • 如果是單次模式 LL_LPTIM_OPERATING_MODE_ONESHOT, 下次進入STOP模式後, 要重啟啟動 LPTIM 才能喚醒
  • 如果是連續模式 LL_LPTIM_OPERATING_MODE_CONTINUOUS, 下次進入STOP模式後, 不需要再設置 LPTIM, 會自動喚醒
// Enable LPTIM clock
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPTIM1);
// Enabel LSI
LL_RCC_LSI_Enable();
while(LL_RCC_LSI_IsReady() == 0);
// Select LSI as LTPIM clock source
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSI);
// prescaler: 128
LPTIM_InitStruct.Prescaler = LL_LPTIM_PRESCALER_DIV128;
// Registers are updated after each APB bus write access
LPTIM_InitStruct.UpdateMode = LL_LPTIM_UPDATE_MODE_IMMEDIATE;
// Init LPTIM
if (LL_LPTIM_Init(LPTIM, &LPTIM_InitStruct) != SUCCESS)
{
  APP_ErrorHandler();
}

// Enable LPTIM1 interrupt
NVIC_SetPriority(LPTIM1_IRQn, 0);
NVIC_EnableIRQ(LPTIM1_IRQn);

// Enable LPTIM autoreload match interrupt
LL_LPTIM_EnableIT_ARRM(LPTIM);
// Enable LPTIM
LL_LPTIM_Enable(LPTIM);
// Set autoreload value
LL_LPTIM_SetAutoReload(LPTIM, 51);
/*
 * LPTIM starts in single mode
 * 如果是連續模式, 則用 LL_LPTIM_StartCounter(LPTIM, LL_LPTIM_OPERATING_MODE_CONTINUOUS);
 */
LL_LPTIM_StartCounter(LPTIM, LL_LPTIM_OPERATING_MODE_ONESHOT);

回調

void LPTIM1_IRQHandler(void)
{
  APP_LptimIRQCallback();
}

void APP_LptimIRQCallback(void)
{
  if((LL_LPTIM_IsActiveFlag_ARRM(LPTIM) == 1) && (LL_LPTIM_IsEnabledIT_ARRM(LPTIM) == 1))
  {
    /* Clear autoreload match flag */
    LL_LPTIM_ClearFLAG_ARRM(LPTIM);
  }
}

文末的彩蛋: PY32F002B 的隱藏資源

1. 開啟 48MHz 運行時鐘

PY32F002B 手冊上的最高運行時鐘是 24MHz, 但是在 py32f002bx5.h 中增加一行 #define RCC_HSI48M_SUPPORT, 就能開啟 PY32F002B 的 48MHz 時鐘支持. 對手裡的幾片 PY32F002B 測試, 以及對一些渠道廠商的合封晶元的測試, 開啟 48MHz 沒有問題, 按 48MHz 的時鐘基準設置定時器和PWM, 反過來也能驗證是真實的 48MHz 頻率.

2. 開啟 DEEP STOP 模式

PY32F002B 手冊上沒有列出 DEEP STOP 模式, 但是在 py32f002bx5.h 中增加如下幾行

#define PWR_DEEPSTOP_SUPPORT                  /*!< PWR feature available only on specific devices: Deep stop feature */

#define PWR_CR1_SRAM_RETV_DLP_Pos    (18U)
#define PWR_CR1_SRAM_RETV_DLP_Msk    (0x1UL << PWR_CR1_SRAM_RETV_DLP_Pos)         /*!< 0x00040000 */
#define PWR_CR1_SRAM_RETV_DLP        PWR_CR1_SRAM_RETV_DLP_Msk                    /*!< SRAM retention voltage control in DeepStop mode */

使用以下的代碼就能使 MCU 進入 DEEP STOP 模式

static void APP_EnterDeepStop(void)
{
  /* Enable PWR clock */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);

  /* STOP mode with deep low power regulator ON */
  LL_PWR_SetLprMode(LL_PWR_LPR_MODE_DLPR);

  /* SRAM retention voltage aligned with digital LDO output */
  LL_PWR_SetStopModeSramVoltCtrl(LL_PWR_SRAM_RETENTION_VOLT_CTRL_LDO);

  /* Enter DeepSleep mode */
  LL_LPM_EnableDeepSleep();

  /* Request Wait For Event */
   __SEV();
   __WFE();
   __WFE();

   LL_LPM_EnableSleep();
}

PY32F002B 在 DEEP STOP 模式下, 待機電流能降到約 0.6uA.

3. DEEP STOP 模式通過 LPTIM 喚醒

經過實際測試, PY32F002B 的 DEEP STOP 模式可以通過 LPTIM 喚醒

  • 當 LPTIM 時鐘源使用 LSE 時, 定時準確, 精度取決於32K晶振的精度, 喚醒的間隔時間最長可以設置到256秒. 但是耗電稍高, 因為開啟 LSE 需要額外的 0.6uA 左右的電流, 待機電流 1.2uA 左右
  • 當 LPTIM 時鐘源使用 LSI 時, 耗電最省, 待機只需要 0.6uA, 但是定時不准確. 當設置為4秒時, 實際間隔稍大於4秒, 當設置為5秒時, 實際間隔為7秒左右, 設置為6秒時, 實際間隔為26秒, 在7秒以上則很可能無法喚醒. 猜測在 DEEP STOP 模式下內部低速時鐘是依靠內部存留(電容?)電量運行, 會隨著內部電量消耗電壓降低而逐漸變慢.

相關代碼

以上的相關常式和代碼可以在下麵的鏈接中找到


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • VMware虛擬機安裝Centos-7.9 創作不易,點贊關註一下吧 1.安裝VMware Workstation Pro 大家根據自己的實際情況安裝合適版本的VMware Workstation Pro,具體的安裝推薦及各版本的下載鏈接大家可以看我之前發佈的一篇博客:VMware Workstat ...
  • 前言 新版WSL2已經支持鏡像模式網路 可以將WSL2的IP固定為與主機相同 鏡像模式網路 但是在啟用後WSL2中Docker運行的服務本機無法訪問 issues 10494 結合上述issues給出自己的使用新的幫助大家避坑 環境 Win11 23H2win + r > winver WSL 2. ...
  • 參考 Ubuntu installation on a RISC-V virtual machine using a server install image and QEMU 用到的文件 fw_jump.bin u-boot.bin ubuntu-22.04.3-preinstalled-serv ...
  • 安裝環境編譯qemu 1. PC啟動 打開兩個視窗,在第一個視窗中 make qemu-gdb,會啟動內核,但在執行第一個指令之前停下; 在第二個視窗中make gdb,實時觀察第一個視窗中的執行過程。 從這裡可以觀察到: IBM PC 在物理地址 0x000ffff0 開始執行, 位於為 ROM ...
  • title: 進程 cover: https://img2.imgtp.com/2024/04/30/ZamtkUJE.jpg tags: - 進程 - linux categories: linux系統編程 程式與進程 程式:是可執行文件,其本質是是一個文件,程式是靜態的,同一個程式可以運行多次, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...