我在開始STM32的仿真調(diào)試時,遇到一個問題,就是調(diào)試時程序一直停在SystemInit()中的等待晶振中,怎么也出不來。
SystemInit()前面部分的代碼,都能走過,就是在執(zhí)行到最后一個函數(shù)時出問題了。
最后一個函數(shù)是:SetSysClock();
執(zhí)行到下面這個循環(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,我希望的是直接進main函數(shù),那么,這個SystemInit()函數(shù)是從哪里來的?
2,為什么會進入死循環(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的啊。
接下來是第二個問題,為什么進入死循環(huán)?
看看注釋:/* Wait till HSE is ready and if Time out is reached exit */
等待HSE準(zhǔn)備就緒且超時時間到達。超時時間且不去管它,這個HSE是什么?
HSE(High Speed External Clock signal),高速外部時鐘信號,是接外部時鐘源的。
相應(yīng)的還有HSI(High Speed Internal Clock signal),高速內(nèi)部時鐘信號,是stm32芯片自帶的。
看到這個概念,我就明白問題所在了:是我用的板子,沒有接外部晶振啊!
所以,等待HSE準(zhǔn)備就緒,這是永遠不能達成的條件啊。
所以,這里需要修改一下,不再等待HSE了,其實是不使用HSE了,而是修改為使用HSI。
當(dāng)我準(zhǔn)備修改文件的時候,發(fā)現(xiàn)了一個問題,我居然修改不了這個文件!
敲了字母,它不出現(xiàn)在代碼中!?
上網(wǎng)一查,原來是system_stm32f0xx.c這個文件是只讀的。
好吧,從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)時鐘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時鐘頻率 2MHz
}
}
這樣修改之后,再進入在線調(diào)試,果然走過了SystemInit(),然后進入了main()。
這樣,就解決了在線調(diào)試總是進不來main()的問題了。
不過,我還是有個疑問:為什么,這樣的代碼,在調(diào)試時有問題,而在全速運行的時候就沒有問題呢?
再次仔細查看這段代碼:
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
其實并不是一個死循環(huán),跳出的條件有兩個:HSE準(zhǔn)備好了,或者超時。
由于我的板子沒有接外接晶振,第一個條件是不能達到的,那么,第二個條件其實是可以達到的啊,為什么我會以為是個死循環(huán)呢?
讓我們來看看 HSE_STARTUP_TIMEOUT 是個什么值吧:
查看定義,是這樣的:
#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */
其實,不是死循環(huán),只是循環(huán)次數(shù)值太大(1280=0x500),單步調(diào)試,不能點擊走這么多的循環(huán)次數(shù)(另外,在這里,想進行斷點執(zhí)行跳過循環(huán)也不管用,不清楚是什么原因,是因為還沒有到執(zhí)行到main()嗎?若有知道原因的高手,請指點,謝謝!)。
這樣,我就考慮到了有幾個辦法解決這個問題了:
1,改小HSE_STARTUP_TIMEOUT,例如:1
評估:危險!我們盡量不要去修改廠家提供的宏。萬一以后需要用HSE呢?另外還要考慮這個值是否有其它地方的調(diào)用。
2,調(diào)試時,修改StartUpCounter變量值,為4ff,則很快達到0x500,跳出循環(huán)。
評估:可行,但是比較麻煩,每次運行都需要修改一次。
若不想修改任何代碼,這倒也是一個選擇。
3,像前文說的那樣,修改SystemInit,默認選擇HSI。
評估:可行。不過,代碼修改量比較大。或許我們還有更好的選擇?
4,修改startup_stm32f0xx.s,不執(zhí)行SystemInit了
如下修改:
IMPORT __main
; IMPORT SystemInit
; LDR R0, =SystemInit
; BLX R0
LDR R0, =__main
BX R0
ENDP
實測,可行。修改時注意,這個文件也是只讀的,需要去掉只讀屬性后才能修改代碼。
改動量較小。不過風(fēng)險可不小,因為我還不能準(zhǔn)確評估去掉 SystemInit 那部分代碼的影響。
可行的原因分析:系統(tǒng)復(fù)位后,HSI振蕩器默認被選為系統(tǒng)時鐘。
5,去掉SystemIit() 中對 SetSysClock() 的調(diào)用;
實測,可行。
改動最較小,只是把那句調(diào)用代碼注釋掉即可。且通過分析SetSysClock()函數(shù),可以知道,若沒有啟用HSE,則相當(dāng)于沒有執(zhí)行任何有效操作。可以說,對于使用HSI的情況,邏輯上沒有任何差別。
最終,我采用了第5種修改方法,調(diào)試運行,一切正常。
上一篇:STM32-使用定時器做延時函數(shù)時遇到的坑
下一篇:STM32-基于匯編來分析延時
推薦閱讀
史海拾趣
近年來,AFOP的發(fā)展取得了顯著成就,其產(chǎn)品在光網(wǎng)通信領(lǐng)域處于領(lǐng)先地位。202X年,世界500強康寧公司看中了AFOP的技術(shù)實力和市場潛力,決定對其進行收購。這一收購使得AFOP獲得了更多的資源和支持,加速了公司的技術(shù)創(chuàng)新和市場拓展步伐。同時,康寧公司也通過收購AFOP進一步鞏固了其在光纖通信領(lǐng)域的領(lǐng)先地位。
背景:為了進一步擴大市場份額和提高品牌影響力,振華新云積極開展市場拓展和國際合作。
內(nèi)容:公司積極參加國內(nèi)外電子展會和論壇等活動,加強與國內(nèi)外客戶的溝通和交流。同時,積極尋求與國際先進企業(yè)的合作機會,共同開展技術(shù)研發(fā)和市場推廣等活動。
成果:通過市場拓展和國際合作,振華新云的產(chǎn)品逐漸走向世界舞臺,贏得了廣大客戶的信賴和好評。同時,公司也積累了寶貴的國際化經(jīng)驗和資源,為未來的國際化發(fā)展奠定了堅實基礎(chǔ)。
Digi International成立于1985年,最初是一家位于明尼蘇達州的公司。隨著業(yè)務(wù)的不斷發(fā)展,公司于1989年進行了首次公開募股,并隨后重組為特拉華州的公司。Digi International在納斯達克全球精選市場上交易,股票代碼為DGII。這一轉(zhuǎn)型不僅為公司帶來了更多的資金支持,也為其后續(xù)的發(fā)展奠定了堅實的基礎(chǔ)。
ETI公司成立于20世紀(jì)初,當(dāng)時電子產(chǎn)業(yè)正處于起步階段。創(chuàng)始人張三看準(zhǔn)了電子技術(shù)的巨大潛力,決定投身其中。然而,初創(chuàng)時期資金短缺、技術(shù)落后、市場競爭激烈等問題讓ETI步履維艱。張三憑借著對電子技術(shù)的熱情和不懈的努力,帶領(lǐng)團隊不斷研發(fā)新產(chǎn)品,拓展市場,最終使ETI在電子行業(yè)中嶄露頭角。
Bedford Opto公司在成立初期,面臨著激烈的市場競爭和技術(shù)瓶頸。然而,公司的研發(fā)團隊通過不懈努力,成功開發(fā)出一款具有革命性的光電傳感器。這款產(chǎn)品不僅提高了信號傳輸?shù)男剩€降低了能耗,迅速在市場上獲得了認可。Bedford Opto公司因此逐漸在電子行業(yè)中嶄露頭角。
隨著國內(nèi)市場的飽和,Bedford Opto公司開始尋求國際化擴張的機會。通過與國外知名企業(yè)的合作,公司成功打入國際市場,并獲得了更多的業(yè)務(wù)機會。同時,公司還積極參與國際技術(shù)交流與合作,不斷提升自身的技術(shù)水平和創(chuàng)新能力。
在電池供電電路或恒流供電電路中,使繼電器工作的突發(fā)電流電涌可導(dǎo)致電源電壓下降。這是由于內(nèi)部電阻或電流限制影響的結(jié)果。圖1所示的電路可克服此問題,此電路在各種條件下從電源吸入恒定1mA電流。 圖1所示電路控制三個Teledyne RF自鎖繼電器7221 ...… 查看全部問答∨ |
本人在“電子制作”08第一期上看到標(biāo)題為“基于89S52單片機的電子體溫計。”但上面沒有給任何程序。 那位大俠有??可否發(fā)上來? 溫度傳感器是:DS18B20.還有個122*64點陣的液晶顯示。。 Help~~~~… 查看全部問答∨ |
cygwin安裝mips編譯器后不識別庫函數(shù),請高手指教,謝謝! cygwin下安裝了mips的編譯器,但不能識別函數(shù),即使寫一個“Hello World”,使用mips-elf-gcc編譯時也會提示“undefined reference to `printf\'”,直接用gcc編譯就沒問題。不知是何原因,望高手指教,謝謝!… 查看全部問答∨ |
|
最近需要寫個讀寫SMBUS設(shè)備的寄存器的程序,好象掛在SMBUS上的各類設(shè)備都有自己固定的SLAVE ADDRESS,所以想問下是否有相關(guān)的資料記錄了各類設(shè)備預(yù)先分配好的地址,如果有相關(guān)資料的話,是否可以提供下哪里下載?比如SPD的SLAVE ADDRESS為A0,A2,A4 ...… 查看全部問答∨ |
|
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- 意法半導(dǎo)體推出用于匹配遠距離無線微控制器STM32WL33的集成的匹配濾波芯片
- ESP32開發(fā)板連接TFT顯示屏ST7789跳坑記
- 如何讓ESP32支持analogWrite函數(shù)
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹莓派進行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲html,css,js文件,以及網(wǎng)頁和arduino的通訊
- ESP32 freeRTOS使用測試
- API調(diào)用小記(Touchdesigner和ESP32)
- 關(guān)于ESP32/8266使用async-mqtt-client庫的一些基本介紹
- 座椅、天窗、電動尾門應(yīng)用 國產(chǎn)車規(guī)級高壓霍爾效應(yīng)傳感器推薦
- 突發(fā)!又一車企車機“崩了”
- 寧德時代為陳立泉院士頒發(fā)“卓越貢獻獎”
- 一文速覽吉利雷神 AI 電混 2.0 發(fā)布會重點
- 2025年1-4月ADAS供應(yīng)商裝機量排行榜:頭部集中與國產(chǎn)突圍并存
- 國內(nèi)飛行汽車無線通信測試成功,通信安全新突破
- SPAD席卷車載激光雷達市場
- 大聯(lián)大品佳集團推出基于Microchip和ams OSRAM產(chǎn)品的10Base-T1S萬級像素大燈方案
- 哈曼推出采用三星Neo QLED技術(shù)的全新顯示屏
- Syntiant推出超低功耗汽車AI創(chuàng)新技術(shù) 提升車輛安全性和用戶體驗
- 羅姆有獎直播|從0到1,帶你了解電機及其驅(qū)動 開始報名啦~
- 省錢、省心的購買租賃方案,讓您不再為預(yù)算煩惱!
- Discover mmWave 走進 TI 毫米波雷達世界 快速獲得設(shè)計技能
- 嵌入式Rust修煉營:動手寫串口燒錄工具和MCU例程,Rust達人Hunter直播帶你入門Rust
- EEWorld 芯積分兌換年度回饋來襲~多種賺積分捷徑曝光+禮品兌換劇透
- 有獎直播:艾邁斯歐司朗智慧農(nóng)業(yè)與植物照明
- ADI有獎下載活動之7 可編程邏輯控制器(PLCs)解決方案
- 開發(fā)板芯幣競拍,每日一款!今日競拍開發(fā)板:大黃蜂開發(fā)板
- ADI有獎下載活動之13升級版ADI電機控制解決方案—伺服控制
- 豐田將與Uber聯(lián)手開發(fā)無人駕駛技術(shù)
- 青海首座電動汽車充電站6月15日投運
- 高通:不會放棄服務(wù)器芯片業(yè)務(wù) 將專注于大型云計算設(shè)備
- 芯片產(chǎn)業(yè)深度調(diào)查|存儲篇:紫光欲打破巨頭壟斷
- 二極管漲價超十七倍,預(yù)計訂單已排到年底
- 在msp430上使用SHT70
- msp430如何設(shè)置IO口上拉還是下拉?
- MSP430F149的DS18B20C語言程序
- 臺積電預(yù)計4月量產(chǎn)5nm產(chǎn)品
- 關(guān)于STM8的程序下載問題:SWIM Error[30006]報錯解決辦法匯總