吴忠躺衫网络科技有限公司

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

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

3天內不再提示

STM32單片機到底如何軟硬件結合

GReq_mcu168 ? 來源:STM32嵌入式開發 ? 作者:屋脊雀工作室 ? 2022-05-17 15:04 ? 次閱讀
不知道大家有沒有疑惑,為什么軟件能控制硬件?本文分析STM32單片機到底是如何軟硬件結合的,分析單片機程序如何編譯,運行。

軟硬件結合

初學者,通常有一個困惑,就是為什么軟件能控制硬件?就像當年的51,為什么只要寫P1=0X55,就可以在IO口輸出高低電平?要理清這個問題,先要認識一個概念:地址空間

尋址空間

什么是地址空間呢?所謂的地址空間,就是PC指針的尋址范圍,因此也叫尋址空間。
大家應該都知道,我們的電腦有32位系統和64位系統之分,為什么呢?因為32位系統,PC指針就是一個32位的二進制數,也就是0xffffffff,范圍只有4G尋址空間。現在內存越來越大,4G根本不夠,所以需要擴展,為了能訪問超出4G范圍的內存,就有了64位系統。STM32是多少位的?是32位的,因此PC指針也是32位,尋址空間也就是4G。
我們來看看STM32的尋址空間是怎么樣的。在數據手冊《STM32F407_數據手冊.pdf》中有一個圖,這個圖,就是STM32的尋址空間分配。所有的芯片,都會有這個圖,名字基本上都是叫Memory map,用一個新芯片,就先看這個圖。036e53fa-d5a9-11ec-bce3-dac502259ad0.png
  • 最左邊,8個block,每個block 512M,總共就是4G,也就是芯片的尋址空間。

  • block 0 里面有一段叫做FLASH,也就是內部FLASH,我們的程序就是下載到這個地方,起始地址是0X800 0000,大家注意,這個只有1M空間。現在STM32已經有2M flash的芯片了,超出1M的FLASH放在哪里呢?請自行查看對應的芯片手冊。

  • 3 在block 1 內,有兩段SRAM,總共128K,這個空間,也就是我們前面說的內存,存放程序使用的變量。如果需要,也可以把程序放到SRAM中運行。407不是有196K嗎?

  • 其實407有196K內存,但是有64k并不是普通的SRAM,而是放在block 0 內的CCM。這兩段區域不連續,而且,CCM只能內核使用,外設不能使用,例如DMA就不能用CCM內存,否則就死機。

  • block 2,是Peripherals,也就是外設空間。我們看右邊,主要就是APB1/APB2、AHB1/AHB2,什么東西呢?回頭再說。

  • block 3、block4、block5,是FSMC的空間,FSMC可以外擴SRAM,NAND FALSH,LCD等外設。

好的,我們分析了尋址空間,我們回過頭看看,軟件是如何控制硬件的。對于這個疑惑,也可以看此文:代碼是如何控制硬件的?在IO口輸出的例程中,我們配置IO口是調用庫函數,我們看看庫函數是怎么做的。例如:

			GPIO_SetBits(GPIOG, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2| GPIO_Pin_3);這個函數其實就是對一個變量賦值,對GPIOx這個結構體的成員BSRRL賦值。

			void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){ /* Check the parameters */ assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); assert_param(IS_GPIO_PIN(GPIO_Pin));  GPIOx->BSRRL = GPIO_Pin;}
assert_param:這個是斷言,用于判斷輸入參數是否符合要求GPIOx是一個輸入參數,是一個GPIO_TypeDef結構體指針,所以,要用->獲取其成員
GPIOx是我們傳入的參數GPIOG,具體是啥?在stm32f4xx.h中有定義。

			#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)GPIOG_BASE同樣在文件中有定義,如下:

			#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800)AHB1PERIPH_BASE,AHB1地址,有點眉目了吧?在進一步看看

			/*!#define APB1PERIPH_BASE PERIPH_BASE#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000)#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000)再找找PERIPH_BASE的定義

			#define PERIPH_BASE ((uint32_t)0x40000000)到這里,我們可以看出,操作IO口G,其實就是操作0X40000000+0X1800這個地址上的一個結構體里面的成員。說白了,就是操作了這個地方的寄存器。實質跟我們操作普通變量一樣,就像下面的兩句代碼,區別就是變量i是SRAM空間地址,0X40000000+0X1800是外設空間地址。

			u32 i;i = 0x55aa55aa;這個外設空間地址的寄存器是IO口硬件的一部分。關于如下圖STM32的GPIO文章推薦STM32中GPIO工作原理詳解。如下圖,左邊的輸出數據寄存器,就是我們操作的寄存器(內存、變量),它的地址就是0X40000000+0X1800+0x14.03b6ef70-d5a9-11ec-bce3-dac502259ad0.png控制其他外設也類似,就是將數據寫到外設寄存器上,跟操作內存一樣,就可控制外設了。
寄存器,其實應該是內存的統稱,外設寄存器應該叫做特殊寄存器。慢慢的,所有人都把外設的叫做寄存器,其他的統稱內存或RAM。寄存器為什么能控制硬件外設呢?因為,初略的說,一個寄存器的一個BIT,就是一個開關,開就是1,關就是0。通過這個電子開關去控制電路,從而控制外設硬件。

純軟件-包羅萬象的小程序

我們已經完成了串口和IO口的控制,但是我們僅僅知道了怎么用,對其他一無所知。程序怎么跑的?關于程序是怎么在單片機運行的,也可以看此視頻動畫演示單片機是如何跑程序的。代碼到底放在那里?內存又是怎么保存的?下面,我們通過一個簡單的程序,學習嵌入式軟件的基本要素。

分析啟動代碼

  • 函數從哪里開始運行?

每個芯片都有復位功能,復位后,芯片的PC指針(一個寄存器,指示程序運行位置,對于多級流水線的芯片,PC可能跟真正執行的指令位置不一致,這里暫且認為一致)會復位到固定值,一般是0x00000000,在STM32中,復位到0X08000004。因此復位后運行的第一條代碼就是0X08000004。前面我們不是拷貝了一個啟動代碼文件到工程嗎?startup_stm32f40_41xxx.s,這個匯編文件為什么叫啟動代碼?因為里面的匯編程序,就是復位之后執行的程序。在文件中,有一段數據表,稱為中斷向量,里面保存了各個中斷的執行地址復位,也是一個中斷。芯片復位時,芯片從中斷表中將Reset_Handler這個值(函數指針)加載到PC指針,芯片就會執行Reset_Handler函數了。(一個函數入口就是一個指針

			; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size __Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault HandlerReset_Handler函數,先執行SystemInit函數,這個函數在標準庫內,主要是初始芯片時鐘。然后跳到__main執行,__main函數是什么函數?是我們在main.c中定義的main函數嗎?后面我們再說這個問題。03c86df4-d5a9-11ec-bce3-dac502259ad0.png芯片是怎么知道開始就執行啟動代碼的呢?或者說,我們如何把這個啟動代碼放到復位的位置?這就牽涉到一個一般情況下不關注的文件wujique.sct,這個文件在wujiqueprjObjects目錄下,通常把這個文件叫做分散加載文件,編譯工具在鏈接時,根據這個文件放置各個代碼段和變量。在MDK軟件Options菜單Linker下有關于這個菜單的設置。03d54696-d5a9-11ec-bce3-dac502259ad0.png把Use Memory Layout from Target Dialog前面的勾去掉,之前不可設置的框都可以設置了。點擊Edit進行編輯。03ed01aa-d5a9-11ec-bce3-dac502259ad0.png在代碼編輯框出現了分散加載文件內容,當前文件只有基本的內容。
其實這個文件功能很強大,通過修改這個文件可以配置程序的很多功能,例如:1 指定FLASH跟RAM的大小于起始位置,當我們把程序分成BOOT、CORE、APP,甚至進行驅動分離的時候,就可以用上了。2 指定函數與變量的位置,例如把函數加載到RAM中運行。
0421b27e-d5a9-11ec-bce3-dac502259ad0.png從這個基本的分散加載文件我們可以看出:
  • 第6行 ER_IROM1 0x08000000 0x00080000定義了ER_IROM1,也就是我們說的內部FLASH,從0x08000000開始,大小0x00080000。

  • 第7行.o (RESET, +First)從0x08000000開始,先放置一個.o文件, 并且用(RESET, +First)指定RESET塊優先放置,RESET塊是什么?請查看啟動代碼,中斷向量就是一個AREA,名字叫RESET,屬于READONLY。這樣編譯后,RESET塊將放在0x08000000位置,也就是說,中斷向量就放在這個地方。DCD是分配空間,4字節,第一個就是__initial_sp,第二個就是Reset_Handler函數指針。也就是說,最后編譯后的程序,將Reset_Handler這個函數的指針(地址),放在0x800000+4的地方。所以芯片在復位的時候,就能找到復位函數Reset_Handler。

  • 第8行 *(InRoot$$Sections)什么鬼?GOOGLE啊!回頭再說。

  • 第9行 .ANY (+RO)意思就是其他的所有RO,順序往后放。就是說,其他代碼,跟著啟動代碼后面。

  • 第11行 RW_IRAM1 0x20000000 0x00020000定義了RAM大小。

  • 第12行 .ANY (+RW +ZI)所有的RW ZI,全部放到RAM里面。RW,ZI,也就是變量,這一行指定了變量保存到什么地址。

分析用戶代碼

到此,基本啟動過程已經分析完。下一步開始分析用戶代碼,就從main函數開始。1 程序跳轉到main函數后:RCC_GetClocksFreq獲取RCC時鐘頻率;SysTick_Config配置SysTick,在這里打開了SysTick中斷,10毫秒一次。Delay(5);延時50毫秒。

			int main(void){ GPIO_InitTypeDef GPIO_InitStructure;  /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */  /* SysTick end of count event each 10ms */ RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);  /* Add your application code here */ /* Insert 50 ms delay */ Delay(5);2 初始化IO就不說了,進入while(1),也就是一個死循環,嵌入式程序,都是一個死循環,否則就跑飛了。

			/*初始化LED IO口*/RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2| GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_Init(GPIOG, &GPIO_InitStructure);  /* Infinite loop */mcu_uart_open(3);while (1){ GPIO_ResetBits(GPIOG, GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3); Delay(100); GPIO_SetBits(GPIOG, GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3); Delay(100); mcu_uart_test();  TestFun(TestTmp2);}3 在while(1)中調用TestFun函數,這個函數使用兩個全局變量,兩個局部變量。

			/* Private functions ---------------------------------------------------------*/u32 TestTmp1 = 5;//全局變量,初始化為5u32 TestTmp2;//全局變量,未初始化 const u32 TestTmp3[10] = {6,7,8,9,10,11,12,13,12,13}; u8 TestFun(u32 x)//函數,帶一個參數,并返回一個u8值{ u8 test_tmp1 = 4;//局部變量,初始化 u8 test_tmp2;//局部變量,未初始化  static u8 test_tmp3 = 0;//靜態局部變量  test_tmp3++;  test_tmp2 = x;  if(test_tmp2> TestTmp1) test_tmp1 = 10; else test_tmp1 = 5;  TestTmp2 +=TestTmp3[test_tmp1];  return test_tmp1;}然后程序就一直在main函數的while循環里面執行。中斷呢?對,還有中斷。中斷中斷,就是中斷正常的程序執行流程。相關文章:STM32中斷系統。我們查看Delay函數,uwTimingDelay不等于0就死等?誰會將uwTimingDelay改為0?

			/** * @brief Inserts a delay time. * @param nTime: specifies the delay time length, in milliseconds. * @retval None */void Delay(__IO uint32_t nTime){ uwTimingDelay = nTime;  while(uwTimingDelay != 0);}搜索uwTimingDelay變量,函數TimingDelay_Decrement會將變量一直減到0。

			/** * @brief Decrements the TimingDelay variable. * @param None * @retval None */void TimingDelay_Decrement(void){ if (uwTimingDelay != 0x00) { uwTimingDelay--; }}這個函數在哪里執行?經查找,在SysTick_Handler函數中運行。誰用這個函數?

			/** * @brief This function handles SysTick Handler. * @param None * @retval None */void SysTick_Handler(void){ TimingDelay_Decrement();}經查找,在中斷向量表中有這個函數,也即是說這個函數指針保存在中斷向量表內。當發生中斷時,就會執行這個函數。當然,在進出中斷會有保存和恢復現場的操作。這個主要涉及到匯編,暫時不進行分析了。有興趣自己研究研究。通常,現在我們開發程序不用關心上下文切換了。

			__Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD SVC_Handler ; SVCall Handler DCD DebugMon_Handler ; Debug Monitor Handler DCD 0 ; Reserved DCD PendSV_Handler ; PendSV Handler DCD SysTick_Handler ; SysTick Handler

余下問題

1 __main函數是什么函數?是我們在main.c中定義的main函數嗎?2 分散加載文件中*(InRoot$$Sections)是什么?3 ZI段,也就是初始化為0的數據段,什么時候初始化?誰初始化?為什么這幾個問題前面留著不說?因為這是同一個問題。順藤摸瓜!

通過MAP文件了解代碼構成

編譯結果

程序編譯后,在下方的Build Output窗口會輸出信息

			*** Using Compiler 'V5.06 update 5 (build 528)', folder: 'C:Keil_v5ARMARMCCBin'Build target 'wujique'compiling stm32f4xx_it.c......assembling startup_stm32f40_41xxx.s...compiling misc.c......compiling mcu_uart.c...linking...Program Size: Code=9038 RO-data=990 RW-data=40 ZI-data=6000 FromELF: creating hex file...".Objectswujique.axf" - 0 Error(s), 0 Warning(s).Build Time Elapsed: 0032
  • 編譯目標是wujique
  • C文件compiling,匯編文件assembling,這個過程叫編譯
  • 編譯結束后,就進行link,鏈接。
  • 最后得到一個編譯結果,9038字節code,RO 990,RW 40,ZI 6000。CODE,是代碼,很好理解,那RO、RW、ZI都是什么?
  • FromELF,創建hex文件,FromELF是一個好工具,需要自己添加到option中才能用

map文件配置

更多編譯具體信息在map文件中,在MDK Options中我們可以看到,所有信息都放在Listingswujique.map
默認很多編譯信息可能沒鉤,鉤上所有信息會增加編譯時間。
0433f1c8-d5a9-11ec-bce3-dac502259ad0.png

map文件

打開map文件,好亂?習慣就好。我們抓重點就行了。0446ef3a-d5a9-11ec-bce3-dac502259ad0.png
  • map 總信息

從最后看起,看到沒?最后的這一段map內容,說明了整個程序的基本概況。有多少RO?RO到底是什么?有多少RW?RW又是什么?ROM為什么不包括ZI Data?為什么包含RW Data?0459ac7e-d5a9-11ec-bce3-dac502259ad0.png
  • Image component sizes

往上,看看Image component sizes,這個就比剛剛的總體統計更細了。這部分內容,說明了每個源文件的概況首先,是我們自己的源碼,這個程序我們的代碼不多,只有main.o,wujique_log.o,和其他一些STM32的庫文件。048f38f8-d5a9-11ec-bce3-dac502259ad0.png第2部分是庫里面的文件,看到沒?里面有一個main.o。main函數是不是我們寫的main函數?明顯不是,我們的main函數是放在main.o文件。這么小的一個工程,用了這么多庫,你以前關注過嗎?估計沒有,除非你曾經將一個原本在1M flash上的程序壓縮到能在512K上運行。04a39852-d5a9-11ec-bce3-dac502259ad0.png第3部分也是庫,暫時沒去分析這兩個是什么東西。04d0b120-d5a9-11ec-bce3-dac502259ad0.png
庫文件是什么?庫文件就是別人已經別寫好的代碼庫。在代碼中,我們經常會包含一些頭文件,例如:

		#include  #include  #include  這些就是庫的頭文件。這些頭文件保存在MDK開發工具的安裝目錄下。我們經常用的庫函數有:memcpy、memcmp、strcmp等。只要代碼中包含了這些函數,就會鏈接庫文件。
  • 文件map

再往上,就是文件MAP了,也就時每個文件中的代碼段(函數)跟變量在ROM跟RAM中的位置。首先是ROM在0x08000000確實放的是startup_stm32f40_41xxx.o中的RESET
庫文件是什么?
庫文件就是別人已經別寫好的代碼庫。在代碼中,我們經常會包含一些頭文件,例如:

			#include #include #include 這些就是庫的頭文件。相關文章:C語言中的頭文件。這些頭文件保存在MDK開發工具的安裝目錄下。我們經常用的庫函數有:memcpy、memcmp、strcmp等。只要代碼中包含了這些函數,就會鏈接庫文件。
  • 文件map
再往上,就是文件MAP了,也就時每個文件中的代碼段(函數)跟變量在ROM跟RAM中的位置。首先是ROM在0x08000000確實放的是startup_stm32f40_41xxx.o中的RESET0501280a-d5a9-11ec-bce3-dac502259ad0.png每個文件有有多行,例如串口,4個函數。051033c2-d5a9-11ec-bce3-dac502259ad0.png然后是RAM的,main.o中的變量,放在0x20000000,總共有0x0000000c,類型是Data、RW。串口有兩種變量,data和bss,什么是bss?這兩個名稱,是section name,也就是段的意思。看前面type和Attr,RW Data,放在.data段;RW Zero放在.bss段,RW Zero,其實就是ZI。到底哪些變量是RW,哪些是ZI?052fc4bc-d5a9-11ec-bce3-dac502259ad0.png
  • Image Symbol Table

再往上就是Image Symbol Table,就更進一步到每個函數或者變量的信息了056647c6-d5a9-11ec-bce3-dac502259ad0.png例如,全局變量TestTmp1,是Data,4字節,分配的位置是0x20000004。0593906e-d5a9-11ec-bce3-dac502259ad0.pngTestTmp3數組放在哪里?放在0X080024E0這個地方,這可是代碼區額。因為我們用const修飾了這個全局變量數組,告訴編譯器,這個數組是不可以改變的,編譯器就將這個數組保存到代碼中了。程序中我們經常會使用一些大數組數據,例如字符點陣,通常有幾K幾十K大,不可能也沒必要放到RAM區,整個程序運行過程這些數據都不改變,因此通過const修飾,將其存放到代碼區。
const的用處比較多,可以修飾變量,也可以修飾函數。更多用法自行學習
05b68498-d5a9-11ec-bce3-dac502259ad0.png那局部變量存放在哪里呢?我們找到了test_tmp3,05c7606a-d5a9-11ec-bce3-dac502259ad0.png沒找到test_tmp1/test_tmp2,為什么呢?在定義時,test_tmp3增加了static定義,意思就是靜態局部變量,功能上,相當于全局變量,定義在函數內,限制了這個全局變量只能在這個函數內使用。哪test_tmp1、test_tmp2放在哪里呢?局部變量,在編譯鏈接時,并沒有分配空間,只有在運行時,才從棧分配空間。

			u8 TestFun(u32 x)//函數,帶一個參數,并返回一個u8值{ u8 test_tmp1 = 4;//局部變量,初始化 u8 test_tmp2;//局部變量,未初始化  static u8 test_tmp3 = 0;//靜態局部變量上一部分,我們留了一個問題,哪些變量是RW,哪些是ZI?我們看看串口變量的情況,UartBuf3放在bss段,其他變量放在.data段。為什么數組就放在bss?bss是英文Block Started by Symbol的簡稱。05dd085c-d5a9-11ec-bce3-dac502259ad0.png到這里,我們可解釋下面幾個概念了:
Code就是代碼,函數。RO Data,就是只讀變量,例如用const修飾的數組。RW Data,就是讀寫變量,例如全局變量跟static修飾的局部變量。ZI Data,就是系統自動初始化為0的讀寫變量,大部分是數組,放在bss段。RO Size等于代碼加只讀變量。RW Size等于讀寫變量(包括自動初始化為0的),這個也就是RAM的大小。ROM Size,也就是我們編譯之后的目標文件大小,也就是FLASH的大小。但是?為什么會包含RW Data呢?因為所有全局變量都需要一個初始化的值(就算沒有真正初始化,系統也會分配一個初始化空間),例如我們定義一個變量u8 i = 8;這樣的全局變量,8,這個值,就需要保存在FALSH區。
06091afa-d5a9-11ec-bce3-dac502259ad0.png我們看看函數的情況,前面我們不是有一個問題嗎?__main和main是一個函數嗎?查找main后發現,main是main,放在0x080005790617d45a-d5a9-11ec-bce3-dac502259ad0.pngmain是main,放在0x080001890629b56c-d5a9-11ec-bce3-dac502259ad0.png__main到main之間發生了什么?還記得分散加載文件中的這句嗎?

			*(InRoot$$Sections)__main就在這個段內。下圖是__main的地址,在0x08000189。__Vectors就是中斷向量,放在最開始。063d6cba-d5a9-11ec-bce3-dac502259ad0.png在分散加載文件中,緊跟RESET的就是*(InRoot$$Sections)。064c13dc-d5a9-11ec-bce3-dac502259ad0.png而且,RESET段正好大小0x00000188。06829394-d5a9-11ec-bce3-dac502259ad0.png巧合?可以參考PPT文檔《ARM嵌入式軟件開發.ppt》。06928e66-d5a9-11ec-bce3-dac502259ad0.png這一段代碼都完成什么功能呢?主要完成ZI代碼的初始化,也就是將一部分RAM初始化為0。其他環境初始化……

最后

到這里,一個程序,是怎么組成的,程序是如何運行的,基本有一個總體印象了。

原文標題:STM32是如何軟硬件結合,編譯后怎么樣一步步運行起來的

文章出處:【微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。

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

    關注

    6043

    文章

    44621

    瀏覽量

    638589
  • STM32
    +關注

    關注

    2272

    文章

    10924

    瀏覽量

    357591
  • 軟硬件
    +關注

    關注

    1

    文章

    303

    瀏覽量

    19268

原文標題:STM32是如何軟硬件結合,編譯后怎么樣一步步運行起來的

文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    單片機是怎么做到軟硬件結合

    我們通過IO和串口的軟件開發,已經體驗了嵌入式軟件開發。不知道大家有沒有疑惑,為什么軟件能控制硬件?反正當年我學習51的時候,有這個疑惑。今天我們就暫停軟件開發,分析單片機到底是如何 軟硬件
    的頭像 發表于 01-17 15:25 ?4286次閱讀
    <b class='flag-5'>單片機</b>是怎么做到<b class='flag-5'>軟硬件</b><b class='flag-5'>結合</b>的

    STM32單片機到底是如何實現軟硬件結合

    本文分析 STM32 單片機到底是如何實現軟硬件結合的,接著分析單片機程序如何編譯、運行。
    發表于 05-16 09:54 ?1204次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>單片機</b><b class='flag-5'>到底</b>是如何實現<b class='flag-5'>軟硬件</b><b class='flag-5'>結合</b>?

    單片機到底是如何軟硬件結合

    ? 不知道大家有沒有疑惑,為什么軟件能控制硬件?反正當年我學習51的時候,有這個疑惑。今天我們就暫停軟件開發,分析單片機到底是如何 軟硬件結合
    的頭像 發表于 08-08 09:31 ?1403次閱讀
    <b class='flag-5'>單片機</b><b class='flag-5'>到底</b>是如何<b class='flag-5'>軟硬件</b><b class='flag-5'>結合</b>的

    AVR單片機軟硬件設計教程入門篇

    AVR單片機軟硬件設計教程入門篇單片機就是一臺微型電腦。麻雀雖小,五臟俱全,單片機將微型電腦的所有基本部分都集成在一片硅片上。構成單片機的基
    發表于 12-09 15:22

    承接單片機軟硬件開發

    領先單片機工作室在廣州,專業承接控制類,消費類電子產品軟硬件開發業務,包括51,PIC,AVR,三星,EMC等8位單片機,MSP430等16位單片機以及LPC,
    發表于 04-04 14:16

    單片機按鍵軟硬件設計技巧有哪些

    單片機按鍵軟硬件設計技巧!
    發表于 04-22 14:37

    為什么軟件能控制硬件單片機到底是如何軟硬件結合

    我們通過IO和串口的軟件開發,已經體驗了嵌入式軟件開發。不知道大家有沒有疑惑,為什么軟件能控制硬件?反正當年我學習51的時候,有這個疑惑。今天我們就暫停軟件開發,分析單片機到底是如何軟硬件
    發表于 02-14 06:22

    單片機測控系統的軟硬件平臺技術

    本文探討了一種用于工業測控系統的單片機軟硬件綜合設計方法——軟硬件平臺技術,重點闡述了其基本原理、設計思想、實現方法,并給出了一個單片機測控系統軟硬
    發表于 08-13 09:38 ?12次下載

    AVR單片機軟硬件學習教程

    AVR單片機軟硬件學習教程 o第一講:單片機及其開發工具簡介 o第二講:AVR硬件電路設計教程 o第三講:AVR開發環境的建立,數字邏輯與C語言程序設計基礎知識 o第四講:流水燈、蜂鳴
    發表于 11-30 15:36 ?526次下載
    AVR<b class='flag-5'>單片機</b><b class='flag-5'>軟硬件</b>學習教程

    單片機系統軟硬件調試及維修技術

    單片機系統軟硬件調試及維修技術,快來下載吧
    發表于 09-01 18:17 ?0次下載

    深度解剖單片機是如何軟硬件結合的并分析單片機程序的編譯,運行

    我們通過IO和串口的軟件開發,已經體驗了嵌入式軟件開發。不知道大家有沒有疑惑,為什么軟件能控制硬件?反正當年我學習51的時候,有這個疑惑。今天我們就暫停軟件開發,分析單片機到底是如何軟硬件
    的頭像 發表于 04-03 11:46 ?1922次閱讀
    深度解剖<b class='flag-5'>單片機</b>是如何<b class='flag-5'>軟硬件</b><b class='flag-5'>結合</b>的并分析<b class='flag-5'>單片機</b>程序的編譯,運行

    深度:單片機到底是如何軟硬件結合的?

    我們通過IO和串口的軟件開發,已經體驗了嵌入式軟件開發。不知道大家有沒有疑惑,為什么軟件能控制硬件?反正當年我學習51的時候,有這個疑惑。今天我們就暫停軟件開發,分析單片機到底是如何軟硬件
    發表于 12-09 10:51 ?0次下載
    深度:<b class='flag-5'>單片機</b><b class='flag-5'>到底</b>是如何<b class='flag-5'>軟硬件</b><b class='flag-5'>結合</b>的?

    專業軟硬件開發

    如下:1、采用單片機(PIC)設計架空線路單相故障指示器,其中大量模擬電路用于采集高壓電纜電流電壓,信號濾波放大處理,繪制4層PCB板、軟硬件結合實現低功耗100uA。2、采樣STM32
    發表于 12-16 16:51 ?13次下載
    專業<b class='flag-5'>軟硬件</b>開發

    深度:單片機到底是如何軟硬件結合的?

    分析單片機到底是如何軟硬件結合的。并通過一個基本的程序,分析單片機程序的編譯,運行。
    發表于 02-08 16:29 ?2次下載
    深度:<b class='flag-5'>單片機</b><b class='flag-5'>到底</b>是如何<b class='flag-5'>軟硬件</b><b class='flag-5'>結合</b>的?

    深度:單片機到底是如何軟硬件結合的?

    本文我們將分析單片機到底是如何軟硬件結合的,并通過一個基本的程序,分析單片機程序的編譯,運行。
    發表于 02-08 16:53 ?7次下載
    深度:<b class='flag-5'>單片機</b><b class='flag-5'>到底</b>是如何<b class='flag-5'>軟硬件</b><b class='flag-5'>結合</b>的?
    玩百家乐官网凤凰娱乐城| 百家乐闲和庄| 大世界娱乐城| 大发888娱乐场下载ypu| 博狗| 百家乐新注册送彩金| 洛克百家乐的玩法技巧和规则 | 百家乐博娱乐赌百家乐的玩法技巧和规则 | 百家乐官网一邱大师打法| 视频百家乐官网平台| 三元风水24山水法| 百家乐稳赢秘笈| 金矿百家乐的玩法技巧和规则| 威尼斯人娱乐城代理合作| 迪威网上娱乐| 波密县| 作弊百家乐官网赌具价格| 康莱德百家乐官网的玩法技巧和规则| 百家乐庄闲机率| 百家乐大路小路| 百家乐官网路书| 吉利百家乐的玩法技巧和规则| 伯爵百家乐赌场娱乐网规则| 香港六合彩公司| 潢川县| 澳门百家乐官网走势图| 三合四局24向黄泉| 百家乐英皇赌场娱乐网规则| 在线赌博网| 百家乐官网园百利宫娱乐城信誉好...| 百家乐官网网上漏洞| 百家乐真人斗地主| 大发888娱乐游戏下载| 网上百家乐官网骗人不| 百家乐官网赌博大全| 百家乐官网稳赢投资法| 天天百家乐的玩法技巧和规则| 湄潭县| 百家乐最全打法| 十六浦娱乐城信誉| 澳门百家乐官网打法百家乐官网破解方法|