日韩一区二区三区精品,欧美疯狂xxxxbbbb牲交,热99re久久免费视精品频,人妻互换 综合,欧美激情肉欲高潮视频

歷史上的今天

今天是:2025年06月14日(星期六)

2019年06月14日 | STM32-仿真調(diào)試時(shí)的SystemInit陷阱

發(fā)布者:sjp5035022 來源: eefocus關(guān)鍵字:STM32  仿真調(diào)試  SystemInit陷阱 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

我在開始STM32的仿真調(diào)試時(shí),遇到一個(gè)問題,就是調(diào)試時(shí)程序一直停在SystemInit()中的等待晶振中,怎么也出不來。


SystemInit()前面部分的代碼,都能走過,就是在執(zhí)行到最后一個(gè)函數(shù)時(shí)出問題了。

最后一個(gè)函數(shù)是:SetSysClock(); 

執(zhí)行到下面這個(gè)循環(huán)之后,出不來了:

  /* Wait till HSE is ready and if Time out is reached exit */

  do

  {

    HSEStatus = RCC->CR & RCC_CR_HSERDY;

    StartUpCounter++;  

  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));


這里,我就有疑問了:

1,我希望的是直接進(jìn)main函數(shù),那么,這個(gè)SystemInit()函數(shù)是從哪里來的?

2,為什么會(huì)進(jìn)入死循環(huán)?


我全工程搜索“SystemInit”,發(fā)現(xiàn)在startup_stm32f0xx.s中有這樣的代碼:

        IMPORT  __main

        IMPORT  SystemInit  

                 LDR     R0, =SystemInit

                 BLX     R0

                 LDR     R0, =__main

                 BX      R0

                 ENDP

看來,系統(tǒng)是先執(zhí)行SystemInit,然后才執(zhí)行main的啊。


接下來是第二個(gè)問題,為什么進(jìn)入死循環(huán)?

看看注釋:/* Wait till HSE is ready and if Time out is reached exit */

等待HSE準(zhǔn)備就緒且超時(shí)時(shí)間到達(dá)。超時(shí)時(shí)間且不去管它,這個(gè)HSE是什么?


HSE(High Speed External Clock signal),高速外部時(shí)鐘信號(hào),是接外部時(shí)鐘源的。

相應(yīng)的還有HSI(High Speed Internal Clock signal),高速內(nèi)部時(shí)鐘信號(hào),是stm32芯片自帶的。


看到這個(gè)概念,我就明白問題所在了:是我用的板子,沒有接外部晶振啊!

所以,等待HSE準(zhǔn)備就緒,這是永遠(yuǎn)不能達(dá)成的條件啊。

所以,這里需要修改一下,不再等待HSE了,其實(shí)是不使用HSE了,而是修改為使用HSI。


當(dāng)我準(zhǔn)備修改文件的時(shí)候,發(fā)現(xiàn)了一個(gè)問題,我居然修改不了這個(gè)文件!

敲了字母,它不出現(xiàn)在代碼中???

上網(wǎng)一查,原來是system_stm32f0xx.c這個(gè)文件是只讀的。

好吧,從windows的文件夾中找到文件,查看屬性,

見下圖:


去掉“只讀”即可。



不依賴于HSE,使用HSI,我修改后的代碼如下:


/**

  * @brief  Configures the System clock frequency, AHB/APBx prescalers and Flash

  *         settings.

  * @note   This function should be called only once the RCC clock configuration

  *         is reset to the default reset state (done in SystemInit() function).

  * @param  None

  * @retval None

  */

static void SetSysClock(void)

{

  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

  

  /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/

//  /* Enable HSE */    

//  RCC->CR |= ((uint32_t)RCC_CR_HSEON);

// 

//  /* Wait till HSE is ready and if Time out is reached exit */

//  do

//  {

//    HSEStatus = RCC->CR & RCC_CR_HSERDY;

//    StartUpCounter++;  

//  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));


    

//    RCC_HSEConfig(RCC_HSE_OFF);//外部晶振關(guān)閉!

    RCC->CR |= ((uint32_t)RCC_CR_HSION);//使用內(nèi)部晶振

    

    

  if ((RCC->CR & RCC_CR_HSERDY) != RESET)

  {

    HSEStatus = (uint32_t)0x01;

  }

  else

  {

    HSEStatus = (uint32_t)0x00;

  }  


  if (HSEStatus == (uint32_t)0x01)

  {

    /* Enable Prefetch Buffer and set Flash Latency */

    FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;

 

    /* HCLK = SYSCLK */

    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

      

    /* PCLK = HCLK */

    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;


    /* PLL configuration = HSE * 6 = 48 MHz */

    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));

    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6);

            

    /* Enable PLL */

    RCC->CR |= RCC_CR_PLLON;


    /* Wait till PLL is ready */

    while((RCC->CR & RCC_CR_PLLRDY) == 0)

    {

    }


    /* Select PLL as system clock source */

    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    


    /* Wait till PLL is used as system clock source */

    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)

    {

    }

  }

  else

  { /* If HSE fails to start-up, the application will have wrong clock 

         configuration. User can add here some code to deal with this error */

        

          //設(shè)置系統(tǒng)時(shí)鐘8MHz

                RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);

                while(0x00 != RCC_GetSYSCLKSource());//等待設(shè)置成功       8--PLL  4--HSE   0--

HSI


                RCC_HCLKConfig(RCC_SYSCLK_Div1);//HCLK 8MHz

                RCC_PCLKConfig(RCC_HCLK_Div1);//PLCK 8MHz

        

                RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_SYSCFG,ENABLE);

                RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_GPIOB,ENABLE);    

        

                RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);//ADC1時(shí)鐘頻率 2MHz

  }  

    

}


這樣修改之后,再進(jìn)入在線調(diào)試,果然走過了SystemInit(),然后進(jìn)入了main()。

這樣,就解決了在線調(diào)試總是進(jìn)不來main()的問題了。


不過,我還是有個(gè)疑問:為什么,這樣的代碼,在調(diào)試時(shí)有問題,而在全速運(yùn)行的時(shí)候就沒有問題呢?


再次仔細(xì)查看這段代碼:

  do

  {

    HSEStatus = RCC->CR & RCC_CR_HSERDY;

    StartUpCounter++;  

  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

其實(shí)并不是一個(gè)死循環(huán),跳出的條件有兩個(gè):HSE準(zhǔn)備好了,或者超時(shí)。

由于我的板子沒有接外接晶振,第一個(gè)條件是不能達(dá)到的,那么,第二個(gè)條件其實(shí)是可以達(dá)到的啊,為什么我會(huì)以為是個(gè)死循環(huán)呢?


讓我們來看看 HSE_STARTUP_TIMEOUT 是個(gè)什么值吧:


查看定義,是這樣的:

#define HSE_STARTUP_TIMEOUT   ((uint16_t)0x0500) /*!< Time out for HSE start up */


其實(shí),不是死循環(huán),只是循環(huán)次數(shù)值太大(1280=0x500),單步調(diào)試,不能點(diǎn)擊走這么多的循環(huán)次數(shù)(另外,在這里,想進(jìn)行斷點(diǎn)執(zhí)行跳過循環(huán)也不管用,不清楚是什么原因,是因?yàn)檫€沒有到執(zhí)行到main()嗎?若有知道原因的高手,請指點(diǎn),謝謝!)。


這樣,我就考慮到了有幾個(gè)辦法解決這個(gè)問題了:


1,改小HSE_STARTUP_TIMEOUT,例如:1        

    評估:危險(xiǎn)!我們盡量不要去修改廠家提供的宏。萬一以后需要用HSE呢?另外還要考慮這個(gè)值是否有其它地方的調(diào)用。

2,調(diào)試時(shí),修改StartUpCounter變量值,為4ff,則很快達(dá)到0x500,跳出循環(huán)。

    評估:可行,但是比較麻煩,每次運(yùn)行都需要修改一次。

    若不想修改任何代碼,這倒也是一個(gè)選擇。

3,像前文說的那樣,修改SystemInit,默認(rèn)選擇HSI。

    評估:可行。不過,代碼修改量比較大?;蛟S我們還有更好的選擇?

4,修改startup_stm32f0xx.s,不執(zhí)行SystemInit了

如下修改:

        IMPORT  __main

;        IMPORT  SystemInit  

;                 LDR     R0, =SystemInit

;                 BLX     R0

                 LDR     R0, =__main

                 BX      R0

                 ENDP

    實(shí)測,可行。修改時(shí)注意,這個(gè)文件也是只讀的,需要去掉只讀屬性后才能修改代碼。

    改動(dòng)量較小。不過風(fēng)險(xiǎn)可不小,因?yàn)槲疫€不能準(zhǔn)確評估去掉 SystemInit 那部分代碼的影響。

    可行的原因分析:系統(tǒng)復(fù)位后,HSI振蕩器默認(rèn)被選為系統(tǒng)時(shí)鐘。

5,去掉SystemIit() 中對 SetSysClock() 的調(diào)用;

    實(shí)測,可行。

    改動(dòng)最較小,只是把那句調(diào)用代碼注釋掉即可。且通過分析SetSysClock()函數(shù),可以知道,若沒有啟用HSE,則相當(dāng)于沒有執(zhí)行任何有效操作??梢哉f,對于使用HSI的情況,邏輯上沒有任何差別。

    

最終,我采用了第5種修改方法,調(diào)試運(yùn)行,一切正常。


關(guān)鍵字:STM32  仿真調(diào)試  SystemInit陷阱 引用地址:STM32-仿真調(diào)試時(shí)的SystemInit陷阱

上一篇:STM32-使用定時(shí)器做延時(shí)函數(shù)時(shí)遇到的坑
下一篇:STM32-基于匯編來分析延時(shí)

推薦閱讀

喝著送餐機(jī)器人送來的咖啡,看人形機(jī)器人整齊劃一地表演舞蹈,欣賞機(jī)器人提筆、沾墨、運(yùn)筆書寫出的書法作品……在唐山新禾智能科技有限公司,記者頗有穿越到未來的感覺。 從搬運(yùn)、碼垛、等生產(chǎn)活動(dòng),到讀報(bào)、陪護(hù)等生活細(xì)節(jié),隨著人工智能技術(shù)的進(jìn)步,我省圍繞工業(yè)機(jī)器人、服務(wù)機(jī)器人、特種機(jī)器人三大領(lǐng)域,從生產(chǎn)制造、技術(shù)研發(fā)、產(chǎn)業(yè)應(yīng)用等路徑推進(jìn)構(gòu)...
在之前的《STM32串口IAP》一文中,通過傳輸數(shù)據(jù)流來升級(jí)程序,但是這種"裸"數(shù)據(jù)的傳輸方式存在這許多的問題,比如它沒有容錯(cuò)機(jī)制,不能保證數(shù)據(jù)的正確傳輸,還比如說它無法獲知升級(jí)文件的信息,導(dǎo)致它在判斷何時(shí)停止接收數(shù)據(jù)上“猶豫不決”。正式為了解決上面的問題,才引進(jìn)了YModem協(xié)議。在《YModem協(xié)議簡介》一文中,已經(jīng)詳細(xì)介紹了YModem的協(xié)議,這里就...
#include <msp430x41x.h>unsigned int L7=~((0X01)<<6);unsigned int L8=~((0X01)<<7);void main(void){ WDTCTL = WDTPW + WDTHOLD; // 禁止看門狗定時(shí)器 //P1DIR |= 0x01; // 設(shè)置P1.0為輸出方向 P2DIR = 0xff; //設(shè)置P2口方向?yàn)檩敵? P2OUT = 0xff; P2OUT |= BIT0; P1IE |= 0x10; //...
從蒸汽到內(nèi)燃機(jī),再到電動(dòng)機(jī),幾百年的歷史進(jìn)程中,世界驅(qū)動(dòng)力的升級(jí)讓城市運(yùn)轉(zhuǎn)的節(jié)奏更快更強(qiáng),而汽車可以說是城市動(dòng)力的親歷者和見證者。不過,正如曾經(jīng)每一次變革都會(huì)受到來自技術(shù)或能源上的阻力一樣,汽車在即將告別化石能源全力擁抱新能源技術(shù),駛向未來駕駛的過程中也面臨著不小的挑戰(zhàn)。“一代正極材料,一代動(dòng)力電池”,從錳酸鋰到磷酸鐵鋰,再到三...

史海拾趣

問答坊 | AI 解惑

XJ4241示波器原理圖

XJ4241示波器原理圖…

查看全部問答∨

WINCE下,我們用的NAND FLASH的FAT32文件系統(tǒng)的文件分配表(FAT表)和文件目錄表(FDT表)在NAND FLASH的那個(gè)地方?還是不需要有?

WINCE下,我們用的NAND FLASH的FAT32文件系統(tǒng)的文件分配表(FAT表)和文件目錄表(FDT表)在NAND FLASH的那個(gè)地方?還是不需要有?…

查看全部問答∨

wince播放視頻文件,c#開發(fā)。

網(wǎng)上找了些資料,關(guān)于用directshow的,依照上面的代碼,運(yùn)行的時(shí)候出錯(cuò)。 private object CreateComObj(Guid ClsID)         {             object com = null;   ...…

查看全部問答∨

軟件開發(fā)不明白這個(gè)怎么實(shí)現(xiàn)啊

模型燈光多媒體控制系統(tǒng) (功能)播放圖片、語音、文字、動(dòng)畫,配合燈光同步控制---觸摸屏的 實(shí)現(xiàn)圖片、語音、文字與沙盤燈光的同步…

查看全部問答∨

請教一個(gè)桌面背景圖片的問題

wince可以設(shè)置桌面背景圖片嘛?如何設(shè)置?…

查看全部問答∨

求助關(guān)于cadence畫原理圖中關(guān)于OFFPAGELEFT的問題

關(guān)于分頁的電路連接(平坦式)中需要用到Off - page Connector, 其中有兩項(xiàng)(或者是4項(xiàng)):OFFPAGELEFT-L和OFFPAGELEFT-R 我看周潤景的書上寫著:設(shè)置采用雙向箭頭,結(jié)點(diǎn)在左(右)的電路端口連接器 而層次式連接器Hierarchical port中有:雙向 ...…

查看全部問答∨

modelsim仿真出現(xiàn)的錯(cuò)誤

Modesim仿真出現(xiàn)的錯(cuò)誤# ** Warning: (vsim-WLF-5000) Waveform log file vsim.wlf currently in use.# File in use by: haohao  Hostname: hao  ProcessID: 1164#           Attempt ...…

查看全部問答∨

請教怎么才能使得輸出電壓步進(jìn)可調(diào)??

應(yīng)該通過什么的方法來實(shí)現(xiàn)開關(guān)電源的輸出電壓連續(xù)步進(jìn)可調(diào)輸出??如30~36V之間,步進(jìn)量為1V,應(yīng)該怎么做,請大家給個(gè)思路>…

查看全部問答∨

關(guān)于嵌入式小作品的創(chuàng)意

大家好,我們正在學(xué)習(xí)單片機(jī)和嵌入式,老師要求每個(gè)人設(shè)計(jì)一個(gè)有趣或者使用的作品。想了好久,沒有什么好的思路,有人有想法能指點(diǎn)一二么??…

查看全部問答∨

spi 從方式 工作不正常

如果我用2條數(shù)據(jù)線是不是就要3條線了,這樣的話庫都不支持了,庫里最多2條線啊,還有就是我上面的ST的片選腳那樣設(shè)置是否合理啊,而且用SPI-RECIVEDATA()這個(gè)函數(shù)的時(shí)候一直讀到的是255。 不知道是什么原因  請各位幫忙…

查看全部問答∨
小廣播
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved