細說STM32F407單片機RTC的備份寄存器原理及使用方法

目錄

一、備份寄存器的功能

二、示例功能

三、項目設置

1、晶振、DEBUG、CodeGenerator、USART6

2、RTC

3、NVIC?

4、GPIO 及KEYLED

四、軟件設計

1、main.h

2、main.c

3、rtc.c

4、keyled.c、keyled.h

五、運行調試


????????本實例旨在介紹備份寄存器的作用。本實例繼續使用旺寶紅龍開發板STM32F407ZGT6 KIT V1.0。本實例將引用本文作者寫的其他文章作為參考文獻。

????????參考項目:細說STM32F407單片機RTC的基本原理及鬧鐘和周期喚醒功能的使用方法-CSDN博客 ?https://wenchm.blog.csdn.net/article/details/145575366

一、備份寄存器的功能

????????STM32F407的RTC有20個32位的備份寄存器,寄存器名稱為RTC_BKP0R~RTC_BKP19R。這些備份寄存器由備用電源VBAT供電,在系統復位或主電源關閉時,只要VBAT有電,備份寄存器的內容就不會丟失。所以,備份寄存器可以用來存儲一些用戶數據

????????文件stm32f4xx_hal_rtc_ex.h中有讀寫備份寄存器的功能函數,其原型定義如下:

uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc,uint32_t BackupReg);
void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc,uint32_t BackupReg,uint32_t Data);

????????其中,參數BackupReg是備份寄存器編號,文stm32f4xx_hal_rtc_ex.h定義了20個備份寄存器編號的宏,定義如下:

#define RTC_BKP_DR0		0x00000000U
#define RTC_BKP_DR1		0x00000001U
/*省略了中間的定義代碼*/
#define RTC_BKP_DR18	0x00000012U
#define RTC_BKP_DR19	0x00000013U

????????RTC也可以由VBAT供電,在系統復位或主電源關閉時,RTC的日歷不受影響。但是在參考項目,因為在系統復位時調用了RTC初始化函數MX_RTC_Init(),而這個函數總是設置RTC的日期和時間,所以復位后,RTC的日期時間又從CubeMX里設置的初始日期時間開始了。

????????可以使用備份寄存器對參考項目進行修改,使得系統在復位時不再自動設置RTC的初始日期時間,而是由備份寄存器RTC_BKP_DR0的內容決定,而且可以把RTC當前時間保存到備份寄存器。

二、示例功能

????????本實例,將設計一個示例,演示備份寄存器的使用。示例具有如下的功能和操作流程。

  • 在RTC初始化函數MX_RTC_Init()中增加代碼,讀取備份寄存器RTC_BKP_DR0的內容,如果值為0,就設置RTC為初始時間和日期,如果值為1,就不設置RTC的日期和時間。
  • 在程序運行時,可以修改保存到備份寄存器RTC_BKP_DR0的值,可以保存0或1。
  • 將RTC當前時間的時、分、秒數據保存到RTC_BKP_DR2到RTC_BKP_DR4的3個寄存器里。RTC_BKP_DR1里的值為1時,表示保存了RTC時間。
  • 讀取備份寄存器RTC_BKP_DR0到RTC_BKP_DR4的內容,顯示到串口助手上。
  • 使用RTC周期喚醒中斷,喚醒中斷周期1s,在喚醒中斷里讀取時間后在串口助手上顯示。本示例還用到4個按鍵和2個LED,所以繼續引用作者發布的其它參考項目中的KEYLED文件中的程序文件。
  • 菜單設計:
[S2]KeyUp ? = Reset RTC time on startup.    //按下S2鍵,用初始時間重置RTC
[S3]KeyDown = Read BKUP registers.          //按下S3鍵,讀取備份寄存器
[S4]KeyLeft = Save current time to BKUP.    //按下S4鍵,把當前時間保存到RTC備份寄存器
[S5]KeyRight= Change RTC time from BKUP.    //按下S5鍵,用備份寄存器存儲的時間重置RTC時間

三、項目設置

1、晶振、DEBUG、CodeGenerator、USART6

? ? ? ? 與參考文章相同。?

2、RTC

????????在RTC的模式設置中,啟用時鐘源和日歷,設置WakeUp模式為Internal WakeUp。在參數設置部分,設置數據格式為Binary data format,設置喚醒時鐘為1Hz信號,喚醒周期數為0,這樣就會每秒產生一次喚醒中斷。

3、NVIC?

????????在NVIC中開啟周期喚醒中斷,設置RTC搶占優先級為1。

4、GPIO 及KEYLED

????????4個按鍵和2個LED。引用文件夾KEYLED的方法請參考本文作者發布的其它文章。

程序標簽

板上名稱

引腳名稱

引腳功能

GPIO模式

默認電平

上拉或下拉

LED1

D1

PA6

GPIO_Output

推挽輸出

High

上拉

LED2

D2

PA4

GPIO_Output

推挽輸出

High

上拉

KeyRight

S5

PF6

GPIO_Input

輸入

上拉

KeyDown

S3

PD3

GPIO_Input

輸入

上拉

KeyLeft

S4

PF7

GPIO_Input

輸入

上拉

KeyUp

S2

PA0

GPIO Input

輸入

上拉

?

四、軟件設計

1、main.h

/* USER CODE BEGIN Private defines */
void RTC_ToggleReset();
void RTC_SaveToBKUP();
void RTC_LoadFromBKUP();
void RTC_ReadBKUP();
/* USER CODE END Private defines */

2、main.c

/* USER CODE BEGIN Includes */
#include "keyled.h"
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
RTC_TimeTypeDef sTime;		//RTC讀取時間和日期的結果數據
RTC_DateTypeDef sDate;uint8_t RTC_isReading=0;	//RTC是否正在讀日期時間數據
/* USER CODE END PV */
/* USER CODE BEGIN 2 */__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc); //禁止RTC周期喚醒printf("Demo11_2_RTC_Backup:Using Backup Registers.\r\n");uint32_t iniRTC = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0);	//讀取備份寄存DR0printf("Reset RTC time on startup: ");if ((iniRTC & 0x01)==0)printf("Yes.\r\n");elseprintf("No.\r\n");/* USER CODE END 2 */
 /* Infinite loop *//* USER CODE BEGIN WHILE *///顯示菜單,也可以放在USER CODE BEGIN 2里printf("[S2]KeyUp   = Reset RTC time on startup(LED2_ON).\r\n");printf("[S3]KeyDown = Read BKUP registers.\r\n");printf("[S4]KeyLeft = Save current time to BKUP.\r\n");printf("[S5]KeyRight= Change RTC time from BKUP.\r\n\r\n");__HAL_RTC_WAKEUPTIMER_ENABLE(&hrtc);	//重啟RTC周期喚醒while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */KEYS curKey=ScanPressedKey(KEY_WAIT_ALWAYS);switch(curKey){case KEY_UP:		//[S2]KeyUp,改變保存到備份寄存器DR0的數值0 or 1RTC_ToggleReset();break;case KEY_DOWN:	//[S3]KeyDown,讀取5個備份寄存器的數據并顯示RTC_ReadBKUP();case KEY_LEFT:	//[S4]KeyLeft,將RTC當前時間保存到備份寄存器RTC_SaveToBKUP();break;case KEY_RIGHT:	//[S5]KeyRight,從備份寄存器讀取時間,改變RTC時間RTC_LoadFromBKUP();break;default:break;}HAL_Delay(300);	//消抖}/* USER CODE END 3 */

????????main()函數里在完成了外設初始化之后,執行__HAL_RTC_WAKEUPTIMER_DISABLE (&hrtc),禁止了RTC周期喚醒單元。在進入while死循環之前,再開啟RTC的周期喚醒單元。

????????調用函數HAL_RTCEx_BKUPRead()讀取備份寄存器RTC_BKP_DR0的內容,如果寄存器的值為0就會在MX_RTC_Init()里用CubeMX設置的初始日期和時間設置RTC的日期時間;如果寄存器的值不為0在MX_RTC_Init()里就不會設置RTC的日期和時間。后一種情況下,在按復位鍵[S6]使系統復位時,RTC仍然保持連續的時間,因為RTC工作在備份域,不會在系統復位時復位。

????????然后,在串口助手上顯示了一個模擬菜單。

????????在while循環里讀取按鍵輸入,用4個按鍵模擬菜單項的選擇,按下某個按鍵后就執行與菜單項對應的功能。按鍵的響應代碼封裝為4個函數。

/* USER CODE BEGIN 4 */
//周期喚醒中斷回調函數
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{LED1_Toggle();RTC_isReading = 1;		//RTC正在讀取數據,該變量的作用類似于RTOS中的二值信號量if (HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK){//調用HAL_RTC_GetTime()之后必須調用HAL_RTC_GetDate()以解鎖數據,才能連續更新日期和時間HAL_RTC_GetDate(hrtc, &sDate, RTC_FORMAT_BIN);RTC_isReading = 0;	//RTC結束了讀取數據//顯示時間hh:mm:sschar str[40];sprintf(str,"RTC Time = %2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);printf(" %s\r\n",str);}
}/* 翻轉保存備份寄存器RTC_BKP_DR0的值 */
void RTC_ToggleReset()	//S2
{uint32_t iniRTC = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0);iniRTC = !iniRTC;if ((iniRTC & 0x01)==0){ //存儲值為0時,用CubeMX中的值復位日期時間printf("Reset RTC time on startup.\r\n");LED2_ON();}else{printf("Not reset RTC time on startup.\r\n");LED2_OFF();}//__HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);		//取消寫保護HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0, iniRTC);	//寫入備份寄存器DR0//__HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc);		//開啟寫保護
}/* RTC時間保存到備份寄存器 */
void RTC_SaveToBKUP()	//S4
{while (RTC_isReading)	//如果RTC的WakeUp中斷里正在讀取數據,就等待其讀取完HAL_Delay(1);//__HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);				//取消寫保護HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1, 0x01);			//0x01=保存了時間的標志HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR2, sTime.Hours);	//使用全局變量sTime,不再讀取當前時間HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, sTime.Minutes);HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR4, sTime.Seconds);//__HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc);				//開啟寫保護char timeStr[30];sprintf(timeStr,"%2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);	//轉換為字符串,自動添加"\0"printf("Current time %s is saved in BKUP.\r\n",timeStr);
}/* 用保存的時間設置為RTC時間 */
void RTC_LoadFromBKUP()	//S5
{uint32_t isTimeSaved = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1);	//讀取備份寄存DR1if (isTimeSaved){RTC_TimeTypeDef time;time.Hours = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);time.Minutes = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);time.Seconds = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);time.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;		//這兩個參數還是有用的,如果不設置這2個參數,設置的小時數會自動減1time.StoreOperation = RTC_STOREOPERATION_SET;//HAL_Delay(10);		//必須加這個延時,否則設置的時間會錯亂while(RTC_isReading)	//如果RTC正在WakeUp中斷里讀取數據,就等待其讀完HAL_Delay(1);/*函數HAL_RTC_SetTime()內部在修改RTC的寄存器之前,會調用 __HAL_RTC_WRITEPROTECTION_DISABLE()取消寫保護,寫完之后,會調用 __HAL_RTC_WRITEPROTECTION_ENABLE() 重新開啟寫保護 */if (HAL_RTC_SetTime(&hrtc, &time, RTC_FORMAT_BIN) == HAL_OK)printf("Load and set BKUP time, success.\r\n");elseprintf("Load and set BKUP time, failure.\r\n");}elseprintf("No BKUP time is saved.\r\n");
}/* 讀取5個備份寄存器內容并顯示 */
void RTC_ReadBKUP()	//S3
{uint32_t regValue;char regStr[40];regValue = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0);	//0=系統復位時復位RTC時間sprintf(regStr,"Reset RTC ,BKP_DR0= %lu",regValue);	//轉換為字符串,自動添加"\0"printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1);	//1=有時間數值sprintf(regStr,"Time is saved,BKP_DR1= %lu",regValue);printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);	//Hoursprintf(regStr,"Saved time(Hour) ,BKP_DR2= %lu",regValue);printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);	//Minutesprintf(regStr,"Saved time(Min) , BKP_DR3= %lu",regValue);printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);	//Secondsprintf(regStr,"Saved time(Sec) , BKP_DR4= %lu",regValue);printf(" %s\r\n",regStr);
}//串口打印
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart6,(uint8_t*)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */

????????回調函數HAL_RTCEx_WakeUpTimerEventCallback()處理RTC周期喚醒中斷。

????????其余的4個函數,是對4個菜單項的響應代碼的封裝。

3、rtc.c

/* USER CODE BEGIN Check_RTC_BKUP */uint32_t iniRTC = HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR0);	//讀取備份寄存DR0if ((iniRTC & 0x01))  //非零,無需初始化RTC日期時間{if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc,0,RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)Error_Handler();return;  //提前退出函數}/* USER CODE END Check_RTC_BKUP */

? ? ? ? 沙箱中添加的代碼就是用函數HAL_RTCEx_BKUPRead()讀取備份寄存器RTC_BKP_DR0的內容,如果寄存器的值不為0,就在執行完HAL_RTCEx_SetWakeUpTimer_IT()設置和啟動周期喚醒后,退出函數;如果寄存器的值為0,就繼續執行函數內后面的代碼。

????????這樣,就在函數MX_RTC_Init()中加入了用戶功能代碼,使得在系統復位時,RTC不必設置初始日期和時間

4、keyled.c、keyled.h

? ? ? ? 引用KEYLED文件夾下的?keyled.c、keyled.h,使用方法請參考本文作者發布的其他文章。

五、運行調試

? ? ? ? 首次下載,或按S6鍵復位,顯示系統菜單。重要的信息是顯示當前從哪里重置RTC時間的信息。如果YES(LED2亮)則從RTC初始化值(15:30:0)重置RTC時間,否則不是;

? ? ? ? 按S2鍵切換從哪里重置RTC時間。比如,下圖,每次按下S6復位鍵,系統都從RTC初始化值重置時間,否則不重置時間,即當LED2燈不亮(DR0=1)時,按下復位鍵S6,不改變RTC時間,連續顯示RTC時間。

?

? ? ? ? ?按S4鍵,存儲當前時間到備份寄存器;按S3鍵,讀取備份存儲器內容并保存當前最新值到備份寄存器;按S5鍵,用備份寄存器內容重置RTC時間;

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/70121.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/70121.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/70121.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

建筑行業安全技能競賽流程方案

一、比賽時間&#xff1a; 6月23日8&#xff1a;30分準時到場&#xff1b;9&#xff1a;00&#xff0d;10&#xff1a;00理論考試&#xff1b;10&#xff1a;10-12:00現場隱患答疑&#xff1b;12:00-13&#xff1a;30午餐&#xff1b;下午13&#xff1a;30-15&#xff1a;30現場…

解鎖機器學習核心算法 | 線性回歸:機器學習的基石

在機器學習的眾多算法中&#xff0c;線性回歸宛如一塊基石&#xff0c;看似質樸無華&#xff0c;卻穩穩支撐起諸多復雜模型的架構。它是我們初涉機器學習領域時便會邂逅的算法之一&#xff0c;其原理與應用廣泛滲透于各個領域。無論是預測房價走勢、剖析股票市場波動&#xff0…

JAVA生產環境(IDEA)排查死鎖

使用 IntelliJ IDEA 排查死鎖 IntelliJ IDEA 提供了強大的工具來幫助開發者排查死鎖問題。以下是具體的排查步驟&#xff1a; 1. 編寫并運行代碼 首先&#xff0c;我們編寫一個可能導致死鎖的示例代碼&#xff1a; public class DeadlockExample {private static final Obj…

解決DeepSeek服務器繁忙問題

目錄 解決DeepSeek服務器繁忙問題 一、用戶端即時優化方案 二、高級技術方案 三、替代方案與平替工具&#xff08;最推薦簡單好用&#xff09; 四、系統層建議與官方動態 用加速器本地部署DeepSeek 使用加速器本地部署DeepSeek的完整指南 一、核心原理與工具選擇 二、…

機器學習 - 大數定律、可能近似正確學習理論

一、大數定律&#xff1a; 大數定律是概率論中的一個基本定理&#xff0c;其核心思想是&#xff1a;當獨立重復的隨機試驗次數足夠大時&#xff0c;樣本的平均值會趨近于該隨機變量的期望值。下面從直觀和數學兩個角度來說明這一概念&#xff1a; 1. 直觀理解 重復試驗的穩定…

【觸想智能】工業顯示器和普通顯示器的區別以及工業顯示器的主要應用領域分析

在現代工業中&#xff0c;工業顯示器被廣泛應用于各種場景&#xff0c;從監控系統到生產控制&#xff0c;它們在實時數據顯示、操作界面和信息傳遞方面發揮著重要作用。與普通顯示器相比&#xff0c;工業顯示器在耐用性、可靠性和適應特殊環境的能力上有著顯著的差異。 觸想工業…

PyCharm2024使用Python3.12在Debug時,F8步進時如同死機狀態

在使用時PyCharm2024&#xff0b;Python3.12&#xff0c;在程序進行調試時&#xff0c;按F8步進時如同死機狀態。 1、相同的程序在PyCharm2023&#xff0b;Python3.9時是沒有問題的&#xff0c;因此決定重裝PyCharm2023&#xff0b;Python3.9&#xff0c;進行調試——調試OK。 …

LLaMA-Factory DeepSeek-R1 模型 微調基礎教程

LLaMA-Factory 模型 微調基礎教程 LLaMA-FactoryLLaMA-Factory 下載 AnacondaAnaconda 環境創建軟硬件依賴 詳情LLaMA-Factory 依賴安裝CUDA 安裝量化 BitsAndBytes 安裝可視化微調啟動 數據集準備所需工具下載使用教程所需數據合并數據集預處理 DeepSeek-R1 可視化微調數據集處…

STM32 如何使用DMA和獲取ADC

目錄 背景 ?搖桿的原理 程序 端口配置 ADC 配置 DMA配置 背景 DMA是一種計算機技術&#xff0c;允許某些硬件子系統直接訪問系統內存&#xff0c;而不需要中央處理器&#xff08;CPU&#xff09;的介入&#xff0c;從而減輕CPU的負擔。我們可以通過DMA來從外設&#xf…

【ISO 14229-1:2023 UDS診斷全量測試用例清單系列:第十六節】

ISO 14229-1:2023 UDS診斷服務測試用例全解析&#xff08;LinkControl_0x87服務&#xff09; 作者&#xff1a;車端域控測試工程師 更新日期&#xff1a;2025年02月14日 關鍵詞&#xff1a;UDS協議、0x87服務、鏈路控制、ISO 14229-1:2023、ECU測試 一、服務功能概述 0x87服務…

DeepSeek與醫院電子病歷的深度融合路徑:本地化和上云差異化分析

一、引言 1.1 研究背景與意義 在醫療信息化快速發展的當下,電子病歷系統已成為醫院信息管理的核心構成。電子病歷(EMR)系統,是指醫務人員在醫療活動過程中,使用醫療機構信息系統生成的文字、符號、圖標、圖形、數據、影像等數字化信息,并能實現存儲、管理、傳輸和重現的…

Django中實現簡單易用的分頁工具

如何在Django中實現簡單易用的分頁工具&#xff1f;&#x1f4da; 嗨&#xff0c;小伙伴們&#xff01;今天我們來看看如何在 Django 中實現一個超簡單的分頁工具。無論你是在處理博客文章、產品列表&#xff0c;還是用戶評論&#xff0c;當數據量一大時&#xff0c;分頁顯得尤…

【kafka系列】生產者

目錄 發送流程 1. 流程邏輯分析 階段一&#xff1a;主線程處理 階段二&#xff1a;Sender 線程異步發送 核心設計思想 2. 流程 關鍵點總結 重要參數 一、核心必填參數 二、可靠性相關參數 三、性能優化參數 四、高級配置 五、安全性配置&#xff08;可選&#xff0…

Docker 入門與實戰:從安裝到容器管理的完整指南

&#x1f680; Docker 入門與實戰&#xff1a;從安裝到容器管理的完整指南 &#x1f31f; &#x1f4d6; 簡介 在現代軟件開發中&#xff0c;容器化技術已經成為不可或缺的一部分。而 Docker 作為容器化領域的領頭羊&#xff0c;以其輕量級、高效和跨平臺的特性&#xff0c;深…

MySQL 插入替換語句(replace into statement)

我們日常使用 insert into 語句向表中插入數據時&#xff0c;一定遇到過主鍵或唯一索引沖突的情況&#xff0c;MySQL的反應是報錯并停止執行后續的語句&#xff0c;而replace into語句可以實現強制插入。 文章目錄 一、replace into 語句簡介1.1 基本用法1.2 使用set語句 二、注…

基于SpringBoot+Vue的智慧校園管理系統設計和實現(源碼+文檔+部署講解)

&#x1f3ac; 秋野醬&#xff1a;《個人主頁》 &#x1f525; 個人專欄:《Java專欄》《Python專欄》 ??心若有所向往,何懼道阻且長 文章目錄 .&#x1f680; 技術架構技術棧全景 &#x1f3af; 功能模塊功能矩陣表&#x1f4ca; 數據庫設計核心ER關系圖 &#x1f4bb; 核心…

【Three.js】JS 3D library(一個月進化史)

#春節過完了&#xff0c;該繼續投入學習了~ 作為一個平面開發者&#xff0c;想要增進更多的技能&#xff0c;掌握web3D開發# Day 1 了解熟悉Three.js&#xff0c;著重基礎理論 學習資源&#xff1a; 前端可視化從0-1 Day 2 寫一個簡易demo 搭建環境-->安裝包-->創建…

moveable 一個可實現前端海報編輯器的 js 庫

目錄 緣由-胡扯本文實驗環境通用流程1.基礎移動1.1 基礎代碼1.1.1 data-* 解釋 1.2 操作元素創建1.3 css 修飾1.4 cdn 引入1.5 js 實現元素可移動1.6 圖片拖拽2.縮放3.旋轉4.裁剪 懶得改文案了&#xff0c;海報編輯器換方案了&#xff0c;如果后面用別的再更。 緣由-胡扯 導火…

Apollo 9.0 速度動態規劃決策算法 – path time heuristic optimizer

文章目錄 1. 動態規劃2. 采樣3. 代價函數3.1 障礙物代價3.2 距離終點代價3.3 速度代價3.4 加速度代價3.5 jerk代價 4. 回溯 這一章將來講解速度決策算法&#xff0c;也就是SPEED_HEURISTIC_OPTIMIZER task里面的內容。Apollo 9.0使用動態規劃算法進行速度決策&#xff0c;從類名…

【Day41 LeetCode】單調棧問題

一、單調棧問題 單調棧問題通常是在一維數組中尋找任一個元素的右邊或者左邊第一個比自己大或者小的元素的位置。 1、每日溫度 739 這題的目的是對于當天&#xff0c;找到未來溫度升高的那一天&#xff0c;也就是當前元素的右邊第一個比自己大的元素。所以我們需要維護一個單…