精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

單片機變量不被初始化的實現方法

strongerHuang ? 來源:strongerHuang ? 作者:strongerHuang ? 2023-05-11 09:29 ? 次閱讀

最近有讀者問了一個這樣的問題:看門狗復位之后,能不能保持復位之前的狀態?

這種問題,或者類似的問題,相信很多小伙伴都經歷過,特別是有多年單片機開發經驗的小伙伴,而且現實中的很多項目確實有這樣的需求。

實現的方法有很多種,這里給大家講講在Keil、 IAR編譯環境下,單片機變量不被初始化的實現方法。

處理器復位

處理器復位的方式有很多種,這里結合STM來講述MCU復位的來源:

STM32的復位為三類:系統復位、電源復位和后備域復位

系統復位:

1. NRST引腳上的低電平(外部復位)

2. 窗口看門狗計數終止(WWDG復位)

3. 獨立看門狗計數終止(IWDG復位)

4. 軟件復位(SW復位)

5. 低功耗管理復位

電源復位:

1. 上電/掉電復位(POR/PDR復位)

2. 從待機模式中返回

備份區域復位:

1. 軟件復位,備份區域復位可由設置備份域控制寄存器(RCC_BDCR)中的BDRST位產生。

2. 在VDD和VBAT兩者掉電的前提下, VDD或VBAT上電將引發備份區域復位。

修飾符

實現處理器復位而變量不被初始化方法之前,讓我們先了解一下修飾符的知識。

修飾符是用于限定類型以及類型成員申明的一種符號。如C語言中常見的修飾符:

1.static靜態修飾符:修飾變量,函數。作用域:變量僅僅在本文件可見,函數在本文件可以被調用;

2.extern聲明修飾符:修飾變量,函數。修飾變量時候,變量的聲明在外面;

3.const常量修飾符:修飾變量,函數。修飾變量時候,不能被重復賦值,只能放在只讀段中;

4.volatile不穩定變量修飾符:這個變量不好翻譯,在c中的作用大概有兩點意思:A.表示變量是易失的,易變的; B.強制訪存操作,防止編譯器去優化,告訴編譯器每次必須去內存中取值,而不是從寄存器或者緩存。
其實,在C++ JAVA中還有更多:

public公共訪問修飾符、private私有訪問修飾符、protected保護訪問修飾符、friendly、abstract等。

而本文會使用到一個修飾符:

__no_init
雖然這個修飾符不是C語言標準的修飾符,但在Keil、IAR這種集成開發環境中,他們支持這種修飾符。

而本文說的修飾符,修飾的變量位于RAM中:

在默認情況下,編譯器會將其變量存放在主RAM中,并在啟動時對其進行初始化。而__no_init類型修飾符使編譯器把變量放在非易失RAM區中,在啟動時也不對它們進行初始化,也就是說__no_init在系統啟動時不初始化變量。

Keil中__no_init的配置和使用

在Keil中,__no_init不是標準的修飾符,需要進行配置,配置之后就可以使用了。

1.宏定義__no_init

#define __no_init __attribute__((zero_init))

2.在工程選項中配置__no_init

Project -> Options for Targets -> Target,里面右下有個NoInit,這個就是需要我們配置的區域(可設定某一區域);


3f6b8b62-ef92-11ed-90ce-dac502259ad0.png ?

3.使用方法

比如定義變量:Cnt_NoInit
__no_init uint16_t Cnt_NoInit;

提示:不能初始化這個變量(也就是定義時不要賦值)。

IAR中中使用__no_init

在IAR中“__no_init”屬于是一個關鍵字,你會發現在使用這個修飾符之后,字體都是關鍵字顏色。
直接使用即可,類似上面定義一個不被初始化的變量:

__no_init uint16_t Cnt_NoInit;
參考源碼

這里給大家分享兩個簡單的Demo(源碼),Keil和IAR工程實現的功能一樣。

源代碼:

__no_inituint16_t Cnt_NoInit;
uint16_t Cnt_Init = 100;


int main(void)
{
  System_Initializes();
  printf("Start...
");  //復位打印


  while(1)
  {
    printf("Cnt_NoInit = %d
", Cnt_NoInit);   //打印變量
    Cnt_NoInit++;


    if(Cnt_NoInit > 1000)
    {
      Cnt_NoInit = 0;
    }


    printf("Cnt_Init = %d
", Cnt_Init);
    Cnt_Init++;
    if(Cnt_Init > 1000)
    {
      Cnt_Init = 0;
    }


    LED_ON;  
    TIMDelay_Nms(500);
    LED_OFF;
    TIMDelay_Nms(500);
    NVIC_SystemReset(); //系統復位
  }
}
被Cnt_NoInit修飾,則會打印如下消息:
Start...
Cnt_NoInit = 0
Cnt_Init = 100


Start...
Cnt_NoInit = 1
Cnt_Init = 100


Start...
Cnt_NoInit = 2
Cnt_Init = 100


Start...
Cnt_NoInit = 3
Cnt_Init=100
如果不被修飾:
uint16_t Cnt_NoInit;
uint16_t Cnt_Init = 100;
如果不被修飾:則會打印如下消息:
Start...
Cnt_NoInit = 0
Cnt_Init = 100


Start...
Cnt_NoInit = 0
Cnt_Init = 100


Start...
Cnt_NoInit = 0
Cnt_Init = 100


Start...
Cnt_NoInit = 0
Cnt_Init = 100
相信聰明的你,看了上面例子會明白為什么沒有初始化的變量“Cnt_NoInit”在變化,而初始化了的“Cnt_Init”一直不變。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6032

    文章

    44521

    瀏覽量

    633092
  • mcu
    mcu
    +關注

    關注

    146

    文章

    17002

    瀏覽量

    350326
  • 看門狗
    +關注

    關注

    10

    文章

    559

    瀏覽量

    70746
  • IAR
    IAR
    +關注

    關注

    5

    文章

    345

    瀏覽量

    36625
  • 初始化
    +關注

    關注

    0

    文章

    49

    瀏覽量

    11837

原文標題:單片機變量不被初始化的實現方法

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    基于旋轉平移解耦框架的視覺慣性初始化方法

    精確和魯棒的初始化對于視覺慣性里程計(VIO)至關重要,因為不良的初始化會嚴重降低姿態精度。
    的頭像 發表于 11-01 10:16 ?218次閱讀
    基于旋轉平移解耦框架的視覺慣性<b class='flag-5'>初始化</b><b class='flag-5'>方法</b>

    TMS320C6000 McBSP初始化

    電子發燒友網站提供《TMS320C6000 McBSP初始化.pdf》資料免費下載
    發表于 10-26 10:10 ?0次下載
    TMS320C6000 McBSP<b class='flag-5'>初始化</b>

    Keil中變量不被初始化方法

    有些時候在我們的應用過程中要求變量有連續性,或者現場保留,例如Bootloader跳轉,某種原因的復位過程中我們有些關鍵變量不能被初始化,在不同的編譯環境下有不同的設置,本文就這個操作做總結,分別
    的頭像 發表于 08-30 11:47 ?535次閱讀
    Keil中<b class='flag-5'>變量</b><b class='flag-5'>不被</b><b class='flag-5'>初始化</b><b class='flag-5'>方法</b>

    STM32F103RC變量初始化問題求解

    Test0變量的值一直是0x03,并且無法被初始化其他值。 例如:ArryTest[7]的地址為0x20000200,Test0 的地址為0x2000020e,則Test0 的值無法被修改,一直為0x03. 有哪位朋友遇到過這樣的問題沒有?
    發表于 04-10 07:35

    字符型、指針型等變量等該如何初始化

     對于數值類型的變量往往初始化為0,但對于其他類型的變量,如字符型、指針型等變量等該如何初始化呢?
    的頭像 發表于 03-18 11:02 ?1283次閱讀

    MCU單片機GPIO初始化該按什么順序配置?為什么初始化時有電平跳變?

    GPIO初始化時有時鐘配置、模式配置、輸出配置、復用配置,那么在編寫初始化代碼時,到底該按什么順序執行呢?如果順序不當那初始化過程可能會出現短暫的電平跳變。
    的頭像 發表于 02-22 11:07 ?1430次閱讀
    MCU<b class='flag-5'>單片機</b>GPIO<b class='flag-5'>初始化</b>該按什么順序配置?為什么<b class='flag-5'>初始化</b>時有電平跳變?

    rtc時鐘如何在啟動后會不被初始化為默認值?

    增加了bootloader程序。也就是如果我的app1看門狗復位了。 我還想保持rtc時鐘繼續跑,不被更新,另外我的一部分SRAM中保存的數據不被初始化。這個能否實現?如何
    發表于 02-21 06:08

    單片機變量存儲大小由什么決定?

    最近看到群友在討論【單片機變量存儲大小由什么決定?】的話題。
    的頭像 發表于 01-26 10:11 ?640次閱讀
    <b class='flag-5'>單片機變量</b>存儲大小由什么決定?

    dataflash中的靜態變量初始化會變嗎,怎么改變變量的值?

    dataflash中的靜態變量初始化會變嗎,怎么改變變量的值? 若系統啟動初始化時,不改變變量的值該怎么設
    發表于 01-15 06:27

    使用SEGGER Embedded Studio編譯器發現變量無法自動初始化

    使用SEGGER Embedded Studio編譯器發現變量無法自動初始化, 例如聲明靜態變量static uint8_t i = 0;這種寫法i成了靜態變量,但沒有
    發表于 01-11 14:21

    單片機中for語句的運用

    語句,它的基本結構如下: for (初始化語句; 條件表達式; 更新語句) {循環體;} for語句的執行流程: 運行初始化語句,一般用于初始化循環變量; 判斷條件表達式的值,如果為t
    的頭像 發表于 01-05 14:02 ?2185次閱讀

    串口初始化一般是初始化哪些內容

    串口初始化是指在使用串口進行數據通信之前,對串口進行一系列的設置和配置,以確保串口能夠正常工作。串口初始化的內容主要包括以下幾個方面: 串口硬件設置:首先,需要確定要使用的串口是哪一個,通常計算機
    的頭像 發表于 01-04 09:39 ?3056次閱讀

    labview運行后如何初始化

    LabVIEW是一款強大的圖形編程軟件,在運行之前通常需要進行一些初始化操作。本文將詳細介紹LabVIEW運行前的初始化過程,并提供了一些常用的初始化
    的頭像 發表于 12-28 17:24 ?2490次閱讀

    自動初始化機制原理詳解

    自動初始化機制是指初始化函數不需要被顯式調用,只需要在函數定義處通過宏定義的方式進行申明,就會在系統啟動過程中被執行。這篇文章就來探索一下其中的奧秘, 簡單理解其原理!
    的頭像 發表于 12-16 09:33 ?968次閱讀
    自動<b class='flag-5'>初始化</b>機制原理詳解

    C語言編程時,各種類型的變量該如何初始化

    C語言編程時,各種類型的變量該如何初始化? 在C語言中,每個變量都需要在使用之前進行初始化初始化是為
    的頭像 發表于 12-07 13:53 ?1132次閱讀