MCU外設初始化:為什么參數配置必須優先于使能

在微控制器領域,初始化參數配置階段至關重要。此時,雖無電源驅動,但微控制器在使能信號到來前,借初始化參數配置這一精細步驟,開啟關鍵準備進程。初始化參數配置如同物理坐標錨定、邏輯指令部署、內在秩序預設,各參數像深埋沃土的種子,坐標、朝向、深度經精密計算,為未來指令運行奠定基礎。

下面以國科安芯的MCU芯片AS32A601為例,詳細展示下MCU這一嚴格的設計特性:

?1. ?外設檢測階段?:MCU會嘗試檢測外設可用性,然后才開始執行用戶代碼。

2. 時鐘樹配置?:系統時鐘(CK_SYS)、AHB、APB等總線時鐘必須在其他外設初始化前完成配置。

為什么參數要在使能前配置?

避免電平跳變?:

  • GPIO復用模式下,若先使能外設再配置復用選擇器,會導致短暫電平變化。
  • 普通輸出IO默認輸出低電平,若先使能再設置高電平,會出現短暫低脈沖。

? 防止硬件沖突?:

  • 時鐘使能必須在外設初始化之前,否則會導致外設無法正常工作。
  • 寄存器默認值可能不符合應用需求,直接使能可能導致意外行為。

確保穩定狀態?:

  • 外設使能前需要建立正確的時鐘源、中斷優先級等基礎環境。
  • 參數配置需要一定時間生效,立即使能可能導致功能異常。

時鐘配置

  1. 通過閱讀芯片手冊,確認好項目所需外設所在時鐘
  2. 確保時鐘最先配置,再去配置外設

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

void?Systemclock_Init()

{

????//注意:此處需要開啟系統總線級的時鐘配置,具體外設時鐘配置可在各模塊初始化函數中具體開啟,具體請參考時鐘樹或者下圖注釋

????//????? 1. 使用串口時,由于串口掛在APB0總線下,需要在此處開啟AXIBUS3時鐘、AXI4TOAPB0時鐘以及APBBUS0時鐘。

????//????? 2. 使用延時函數時,需要開啟CLINT時鐘

????//????? 3. 使用eflash、qspi時,需要開啟AXIBUS3時鐘、AXILITEBUS2時鐘

?????

????/* AXIBus3 clock operation Guide*/

????AXIBUS3_CLK_ENABLE();

????AXI4TOAPB0_CLK_ENABLE();

????APBBUS0_CLK_ENABLE();

????AXI4TOAPB1_CLK_ENABLE();

????APBBUS1_CLK_ENABLE();

????AXILITEBUS1_CLK_ENABLE();

????AXILITEBUS2_CLK_ENABLE();

????EFLASH_CLK_ENABLE();??

????PLIC_CLK_ENABLE();

????CLINT_CLK_ENABLE();

?????

????SMU_PLLInitTypeDef SMU_PLLInitStruct;

????SMU_ClockInitTypeDef SMU_ClockInitStruct;

???

????/* Set PLL parameters values */

????SMU_PLLInitStruct.OscillatorType = SMU_OSCILLATORTYPE_OSC;

????SMU_PLLInitStruct.FIRCOscState = DISABLE;

????SMU_PLLInitStruct.FIRCCalibrationValue = 0x00;

????SMU_PLLInitStruct.PLLConfig.PLLState = ENABLE;

????SMU_PLLInitStruct.PLLConfig.PLLSource = SMU_PLLCLK_OSC;

????SMU_PLLInitStruct.PLLConfig.PLLDivR = 0x01;

????SMU_PLLInitStruct.PLLConfig.PLLDivQ = 0x01;

????SMU_PLLInitStruct.PLLConfig.PLLDivN = 0x14;

????SMU_PLLInitStruct.PLLConfig.PLLDivF = 0xA0;

????SMU_PLLInit(&SMU_PLLInitStruct);

?????

????/* Ensure that the EFLASH is consistent with the system clock */

????FLASH_UnlockCtrl();

????FLASH_SetCLKFreq(0xA0);

?????

????/* Set System Clock parameters values */

????SMU_ClockInitStruct.SYSCLKSelect = SMU_SYSCLK_PLL;

????SMU_ClockInitStruct.AXI4Bus3CLKDiv = AXI4Bus3CLKDiv1;

????SMU_ClockInitStruct.APBBus0CLKDiv = APBBus0CLKDiv1;

????SMU_ClockInitStruct.APBBus1CLKDiv = APBBus1CLKDiv8;

????SMU_ClockInitStruct.CANX2CLKDiv = CANX2CLKDiv1;

???

????SMU_ClockInit(&SMU_ClockInitStruct);

?????

????EFLASH_CLK_UPDATE_ENABLE();

????EFLASH_CLK_UPDATE_DISABLE();

?

????FLASH_LockCtrl();

?????

????/* Get System Clock values */

????SMU_GetClocksFreq(&SMU_ClocksStruct);

}

GPIO初始化

  1. 開始GPIO對應時鐘

  2. 如果是復用IO,首先要配置復用

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

void?GPIO_Init(void)

{

???GPIO_InitTypeDef? GPIO_InitStructure;

???/*開啟GPIO所在時鐘*/

???GPIOD_CLK_ENABLE();

???GPIOG_CLK_ENABLE();

???GPIOF_CLK_ENABLE();

???/* Set GPIO multiplex mapping */

???GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_CAN1);//先開啟復用模式

???GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_CAN1);

??

???/* GPIO Configure */

???GPIO_StructInit(&GPIO_InitStructure);

???GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;

???GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

???GPIO_InitStructure.GPIO_OType = GPIO_Out_PP;

???GPIO_InitStructure.GPIO_OStrength = GPIO_OStrength_9mA;

???

???GPIO_Init(GPIOD, &GPIO_InitStructure);

???GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;

???GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

???GPIO_InitStructure.GPIO_IType = GPIO_IPU;

???GPIO_InitStructure.GPIO_OStrength = GPIO_OStrength_9mA;

???GPIO_Init(GPIOD, &GPIO_InitStructure);

????

????/* GPIOB Configure */

????GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;

????GPIO_InitStructure.GPIO_Mode????? = GPIO_Mode_OUT;

????GPIO_InitStructure.GPIO_OType???? = GPIO_Out_PP;

????GPIO_InitStructure.GPIO_OStrength = GPIO_OStrength_9mA;

?????

????GPIO_Init(GPIOG, &GPIO_InitStructure);

???

????/* GPIOB Configure */

????GPIO_InitStructure.GPIO_Pin?????? = GPIO_Pin_1;

????GPIO_InitStructure.GPIO_Mode????? = GPIO_Mode_IN;

????GPIO_InitStructure.GPIO_IType???? = GPIO_IPU;

????GPIO_InitStructure.GPIO_OType???? = GPIO_Out_PP;

????GPIO_InitStructure.GPIO_OStrength = GPIO_OStrength_9mA;

?????

????GPIO_Init(GPIOF, &GPIO_InitStructure);?

}

部分外設參數配置

Usart
  1. 最后使能外設
  2. 配置外設參數
  3. 配置GPIO先配置復用
  4. 開啟GPIO和外設時鐘

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

void?User_Print_Init(uint32_t BaudRate)

{

????USART_InitTypeDef USART_InitStructure;

????GPIO_InitTypeDef? GPIO_InitStructure;

????PLIC_InitTypeDef PLIC_InitStructure;

????/*GOPI/外設時鐘使能*/

????GPIOD_CLK_ENABLE();

????USART0_CLK_ENABLE();

????/* Set GPIO multiplex mapping */

????GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART0);?????? /* USART0_TX */?開啟復用模式

????GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART0);?????? /* USART0_RX */

????/* GPIO Configure */

????GPIO_InitStructure.GPIO_Pin?????? = GPIO_Pin_8;????????????

????GPIO_InitStructure.GPIO_Mode????? = GPIO_Mode_OUT;

????GPIO_InitStructure.GPIO_OType???? = GPIO_Out_PP;

????GPIO_InitStructure.GPIO_OStrength = GPIO_OStrength_4_5mA;

????GPIO_Init(GPIOD, &GPIO_InitStructure);

????GPIO_InitStructure.GPIO_Pin?????? = GPIO_Pin_9;????????????

????GPIO_InitStructure.GPIO_Mode????? = GPIO_Mode_IN;

????GPIO_InitStructure.GPIO_IType???? = GPIO_IN_FLOATING;

????GPIO_InitStructure.GPIO_OStrength = GPIO_OStrength_4_5mA;

????GPIO_Init(GPIOD, &GPIO_InitStructure);

????/*防止配置沖突*/

????USART_DeInit(USART0);

????USART_StructInit(&USART_InitStructure);

?

????/* Initializes the USART0 */

????USART_InitStructure.USART_BaudRate???? = BaudRate;

????USART_InitStructure.USART_WordLength?? = USART_WordLength_8b;

????USART_InitStructure.USART_StopBits???? = USART_StopBits_1;

????USART_InitStructure.USART_Parity?????? = USART_Parity_No;

????USART_InitStructure.USART_Mode???????? = USART_Mode_Rx | USART_Mode_Tx;

????USART_InitStructure.USART_OverSampling = USART_OverSampling_16;

USART_Init(USART0, &USART_InitStructure);

/*配置好相關參數后,使能USART*/

????USART_Cmd(USART0, ENABLE);

????USART_ITConfig(USART0, USART_IT_RXNE, ENABLE);

?????

?????/* Configer the USART0 interrupt */

????PLIC_InitStructure.PLIC_IRQChannel = USART0_IRQn;

????PLIC_InitStructure.PLIC_IRQPriority = 1;

????PLIC_InitStructure.PLIC_IRQChannelCmd = ENABLE;

????PLIC_Init(&PLIC_InitStructure);

}

CAN

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

void?User_CANFD3_Init()

{

????CANFD3_CLK_ENABLE();

????GPIOC_CLK_ENABLE();

????

????GPIO_InitTypeDef? GPIO_InitStructure;

????CANFD_InitTypeDef CANFD_InitStructure;

????PLIC_InitTypeDef? PLIC_InitStructure;

?

????/* Set GPIO multiplex mapping */

????GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_CAN3);

????GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_CAN3);

?

????/* GPIO Configure */

????GPIO_StructInit(&GPIO_InitStructure);

????GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;

????GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

????GPIO_InitStructure.GPIO_OType = GPIO_Out_PP;

????GPIO_InitStructure.GPIO_OStrength = GPIO_OStrength_18mA;

?????

????GPIO_Init(GPIOC, &GPIO_InitStructure);

????GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

????GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

????GPIO_InitStructure.GPIO_IType = GPIO_IPU;

????GPIO_InitStructure.GPIO_OStrength = GPIO_OStrength_18mA;

????GPIO_Init(GPIOC, &GPIO_InitStructure);

?????

????/* Initializes the CANFD1 */

????/* Arbitration Phase (Nominal) Baud Rate 500KHz */

????/* Data Phase Baud Rate 2MHz */

????CANFD_StructInit(&CANFD_InitStructure);

????CANFD_InitStructure.CANFD_SRR = CANFD_SRR_RESET;

????CANFD_InitStructure.CANFD_APBRPR = CANFD_APBRPR_10tp;

????CANFD_InitStructure.CANFD_APBTR_APTS1 = CANFD_APBTR_TS1_11tp;

????CANFD_InitStructure.CANFD_APBTR_APTS2 = CANFD_APBTR_TS2_4tp;

????CANFD_InitStructure.CANFD_APBTR_APSJW = CANFD_APBTR_SJW_2tp;

?????

????CANFD_InitStructure.CANFD_DPBRPR = CANFD_DPBRPR_2tp;

????CANFD_InitStructure.CANFD_DPBTR_DPTS1 = CANFD_DPBTR_TS1_7tp;

????CANFD_InitStructure.CANFD_DPBTR_DPTS2 = CANFD_DPBTR_TS2_2tp;

????CANFD_InitStructure.CANFD_DPBTR_DPSJW = CANFD_DPBTR_SJW_2tp;

????CANFD_Init(CANFD3, &CANFD_InitStructure);

?????????

????/* CANFD receive filter configure */

????CANFD_FilterInit(CANFD3, TB0, 0xFFE00000, 0X62E00000);???????

?

????CANFD_AutoRetransConfig(CANFD3,ENABLE);

????/* Enable new message received interrupt */

????CANFD_ITConfig(CANFD3, CANFD_IT_ERXOK, ENABLE);

????/* CANFD Enable */

????CANFD_Enable(CANFD3);

?????

????PLIC_StructInit(&PLIC_InitStructure);

?

????/* Configer the CANFD1 interrupt */

????PLIC_InitStructure.PLIC_IRQChannel = CANFD3_IRQn;

????PLIC_InitStructure.PLIC_IRQPriority = 2;

????PLIC_InitStructure.PLIC_IRQChannelCmd = ENABLE;

????PLIC_Init(&PLIC_InitStructure);

????CANFD_ClearITPendingBit(CANFD3, CANFD_CLEAR_ALL);

}

通過遵循"參數配置在先,外設使能在后"的原則,并采用結構化初始化流程,可以顯著提高MCU系統的穩定性和可靠性。

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

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

相關文章

AI一周事件(2025年8月6日-8月12日)

(以下借助 DeepSeek-R1 & ChatGPT-5 輔助整理) 一、AI 模型與算法進展 1. OpenAI 正式發布 GPT-5(8月7日) 事件:OpenAI 于 2025 年 8 月 7 日推出 GPT-5——其自稱擁有“PhD 級別”的智能,通過內置…

快速了解自然語言處理

在這個智能時代,我們每天都在和機器 “對話”—— 用語音助手查詢天氣、讓翻譯軟件跨越語言障礙、靠智能客服解決問題…… 這些便捷體驗的背后,都離不開自然語言處理(Natural Language Processing,NLP) 技術。作為人工…

洛谷 P2607 [ZJOI2008] 騎士-提高+/省選-

題目描述 Z 國的騎士團是一個很有勢力的組織,幫會中匯聚了來自各地的精英。他們劫富濟貧,懲惡揚善,受到社會各界的贊揚。 最近發生了一件可怕的事情,邪惡的 Y 國發動了一場針對 Z 國的侵略戰爭。戰火綿延五百里,在和平…

不止于GET:掌握POST報錯注入的精髓

文章目錄引言POST請求簡述報錯注入核心思想關鍵前提實戰演練POST報錯注入與GET報錯注入的區別防御之道:如何避免POST報錯注入?引言 SQL注入是Web安全領域危害性最大、最常見、最持久的高危漏洞之一。它直接威脅到應用程序核心數據庫的安全,可…

01數據結構-Prim算法

01數據結構-Prim算法1.普利姆(Prim)算法1.1Prim算法定義1.2Prim算法邏輯1.3Prim代碼分析2.Prim算法代碼實現1.普利姆(Prim)算法 1.1Prim算法定義 Prim算法在找最小生成樹的時候,將頂點分為兩類,一類是在查找的過程中已經包含在生成樹中的頂點(假設為A類…

CacheBlend:結合緩存知識融合的快速RAG大語言模型推理服務

溫馨提示: 本篇文章已同步至"AI專題精講" CacheBlend:結合緩存知識融合的快速RAG大語言模型推理服務 摘要 大語言模型(LLMs)通常在輸入中包含多個文本片段,以提供必要的上下文。為了加速對較長LLM輸入的預…

Docker 在 Linux 中的額外資源占用分析

Docker 本身作為一個運行時環境,除了容器應用本身消耗的資源外,還會引入一些額外的開銷。主要體現在以下幾個方面: 1. 存儲空間占用 (Disk Space) 這是最顯著的額外開銷,主要來源于 Docker 的存儲驅動(如 overlay2&…

[激光原理與應用-264]:理論 - 幾何光學 - 什么是焦距,長焦與短焦的比較

長焦與短焦透鏡是光學系統中兩類核心組件&#xff0c;其成像特性在焦距、視角、景深、像場特性及典型應用中存在顯著差異。以下從多個維度進行詳細對比&#xff1a;一、核心參數對比參數長焦透鏡短焦透鏡焦距范圍通常 >50mm&#xff08;全畫幅相機標準&#xff09;通常 <…

el-input 復制大量數據導致頁面卡頓問題解決

問題根源 復制粘貼操作會瞬間觸發大量 input 事件&#xff0c;導致 Vue 頻繁更新響應式數據&#xff0c;引發性能瓶頸。 解決方案&#xff1a;使用 .lazy 修飾符 <el-input v-model.lazy"inputValue" />

PCIe Electrical Idle Sequences ( EIOS and EIEOS )

前言 PCI Express (PCIe)協議中&#xff0c;EIOS (Electrical Idle Ordered Set) 和 EIEOS (Electrical Idle Exit Ordered Set) 是在高速鏈路管理和狀態切換過程中極為重要的特殊序列。下面做詳細解釋&#xff1a; 一、EIOS&#xff08;Electrical Idle Ordered Set&#xff0…

【GPT入門】第45課 無梯子,linux/win下載huggingface模型方法

【GPT入門】第45課 無梯子&#xff0c;下載huggingface模型方法1.下載模型代碼2. linux 設置鏡像與加速3.windows1.下載模型代碼 from transformers import AutoModelForCausalLM, BertTokenizer, BertForSequenceClassificationmodel_dir /root/autodl-tmp/model_hf# 加載模…

計算機網絡摘星題庫800題筆記 第5章 傳輸層

第5章 傳輸層5.1 傳輸層概述題組闖關1.Internet 傳輸層滑動窗口協議規定 ( )。 A. 網絡接收分組的最低效率&#xff0c;只需要重傳未被確認的分組 B. 固定的窗口大小&#xff0c;只需要重傳未被確認的分組 C. 網絡接收分組的最低效率&#xff0c;固定的窗口大小 D. 未被確認的分…

Apache虛擬主機三種配置實戰

一、虛擬主機概述 目的&#xff1a;實現單臺服務器部署多個獨立站點 三種部署方式&#xff1a; 相同IP 不同端口不同IP 相同端口相同IP和端口 不同域名&#xff08;FQDN&#xff09; 示例目標&#xff1a;在服務器上部署 baidu 和 taobao 兩個站點方式1&#xff1a;相同IP …

【SpringBoot】04 基礎入門 - 自動配置原理入門:依賴管理 + 自動配置

文章目錄前言一、Spring Boot Maven項目POM文件解析1. 基礎項目信息2. 父項目繼承3. 依賴管理4. 構建配置5. 屬性配置Spring Boot特性體現典型Spring Boot項目特點二、依賴管理1、父項目做依賴管理無需關注版本號&#xff0c;自動版本仲裁修改自動仲裁的版本官網文檔2、依賴項引…

機器學習—— TF-IDF文本特征提取評估權重 + Jieba 庫進行分詞(以《紅樓夢》為例)

使用 Jieba 庫進行 TF-IDF 關鍵詞提取&#xff08;以《紅樓夢》為例&#xff09;在中文文本分析中&#xff0c;TF-IDF&#xff08;Term Frequency - Inverse Document Frequency&#xff09; 是最常用的關鍵詞提取方法之一。它通過評估詞在單個文檔中的出現頻率和在所有文檔中的…

Kotlin語法整理

Kotlin語法整理 Kotlin語法整理 一、基本數據類型 共8種 二、變量的聲明三、條件 1. if…else if…else語句2. when 語句 四、循環 1. while 語句2. do…while 語句3. for 語句4. repeat 語句5. break 語句6. continue 語句 五、數組 1. 創建元素未初始化的數組2. 創建元素初始…

跨平臺低延遲的RTMP推流播放在無紙化會議與智慧教室的技術設計和架構實踐

?? 引言&#xff1a;讓每一塊屏幕“同頻”的核心技術 無紙化會議與智慧教室&#xff0c;正在從“輔助工具”走向“核心基礎設施”&#xff0c;成為政企數字化與教育信息化建設的標配。它們的核心訴求并不只是替代紙質文檔或黑板&#xff0c;而是要在多終端、多地點、多網絡環…

最優擴展大型語言模型測試時計算量可能比擴展模型參數更有效

摘要 通過增加測試時計算量使大型語言模型&#xff08;LLMs&#xff09;提升輸出效果&#xff0c;是構建能基于開放自然語言自主改進的通用智能體的重要步驟。本文研究LLMs推理階段計算量的擴展規律&#xff0c;重點回答以下問題&#xff1a;若允許LLM使用固定但可觀的推理階段…

GPT5評測對比與使用

經過長達一年的技術迭代&#xff0c;OpenAI正式推出GPT-5系列模型&#xff0c;包含GPT-5&#xff08;標準版&#xff09;、GPT-5-mini&#xff08;輕量版&#xff09;和GPT-5-nano&#xff08;極簡版&#xff09;三個版本&#xff0c;定價策略保持統一。本次升級在性能、效率與…

Git與CI/CD相關知識點總結

Git與CI/CD相關知識點總結 1. Git對象模型與存儲機制 1.1 Git對象類型 Commit對象&#xff1a;包含提交信息、作者、時間、父commit引用、樹對象引用Tree對象&#xff1a;描述目錄結構和文件引用Blob對象&#xff1a;實際的文件內容 1.2 存儲機制特點 增量存儲&#xff1a;每次…