總網頁瀏覽量

顯示具有 STM32Cube 標籤的文章。 顯示所有文章
顯示具有 STM32Cube 標籤的文章。 顯示所有文章

2021年8月16日 星期一

【阿良的嵌入式系統技術學習區】STM32系列MCU韌體程式設計基礎實務 課程內容介紹

課程涵蓋內容如下:

  • 韌體程式常用程式語言
    • 組合語言指令集與MCU架構簡介
      • 以架構簡潔清晰的Intel MCS51指令集為教材範例
    • C語言基礎複習
    • 高階與低階語言(C語言 與 組合語言Assembly)差異介紹與實驗驗證

  • STM32 MCU常見開發環境操作教學
    • ARM KEILC 評估版 整合開發環境(IDE)操作教學
    • STM32CubeMX工具與STM32Cube IDE操作教學
    • 其它IDE簡介(如 IAR)

  • 中斷(Interrupt)機制
    • ARM Cortex-Mx系列搭配之NVIC (嵌套式向量中斷控制器)介紹
    • 中斷優先權實驗

  • 周邊裝置驅動原理與實作
    • GPIO(通用輸入/輸出介面)
      • GPIO架構與驅動原理
        • IO Port結構原理、Open-drain(開汲極)、Push-Pull output(推挽式輸出)、Pull-up、Pull-down等相關硬體電路原理
      • 外部簡易電路整合應用設計原理
      • 輸出驅動實驗(GPO, General Purpose Output)
      • 輸入驅動實驗(GPI, General Purpose Input)
    • Timer/Counter(計時器/計數器
      • 計時器
      • 計數器
      • 輪詢與中斷應用實驗
    • UART (通用非同步串列傳輸通訊介面
      • UART之協定原理
      • 輪詢與中斷應用實驗 (與其它具備UART介面之設備進行通訊實驗
      • RS232與RS485纜線介紹
        • 電氣位準轉換原理
        • 相關IC介紹
    • ADC(類比轉數位轉換器
      • 輪詢與中斷機制  搭配 亮度感測器 進行實驗
    • I²C串列通訊介面
    • SPI串列通訊介面
    • 其它各種周邊裝置、I/O介面或協定(PWM、1-wire、DAC、DMA...)

  • 基礎電子電路與元件應用
      • 類比電子電路 與 數位電子電路 基礎原理觀念
      • 基本電壓、電流量測
      • 二極體
      • 電晶體
        • 如: BJT開關應用、MOSFET (如level shift電路應用)
      • OPA(運算放大器)基本應用
      • 穩壓IC應用介紹
        • 光耦合IC
          • Relay繼電器驅動

        • 進階選修
          • GPIO進階應用之 矩陣多按鈕鍵盤 掃描輸入演算法
          • GPIO進階應用之 多合一七段顯示器 掃描輸出演算法
          • LCD顯示驅動
          • 各式無線通訊模組應用(藍牙、ZigBee、LoRa、Wifi等等)
          • 各式感測器應用(如: 溫度、溼度、三軸加速度感測器、陀螺儀、電流感測、pH酸鹼值、ORP氧化還原...等等)
          • 步進馬達驅動
          • 直流馬達驅動
          • 應用專題
            • 物聯網IoT (如 智慧家庭、智慧農業、自動化系統...)
            • 穿戴式裝置(慣性感測、生醫訊號處理應用...)


         


        2021年3月18日 星期四

        【課程內容介紹】本學習區之嵌入式系統SoC/MCU晶片內部IO Port結構、Open-drain(開汲極)、Push-Pull output(推挽式輸出)等相關課程內容介紹

        歡迎透過合法的方式分享此文內容,若要轉載/轉貼,請明確貼出此原始連結並標示作者基本資訊請勿抄襲及非法轉貼(例如擷取內文但並未註明出處)

        近期在對擔任韌體開發工程師的學員進行授課的過程中,以8051 MCU作為實驗目標教材,介紹到了8051 MCU四組I/O Port的內部硬體結構和運作原理,


        尤其是Port0的部分,因為其兼顧作為8051存取外部記憶體所使用的Address/Data bus的IO Port,當談到如何將其作為一般用途的IO Port(GPIO)時,也會介紹到Open-drain(開汲極)與外加Pull-up resister的相關原理,也會藉由ST官方的STM32 MCU AN4899這份AP note資料手冊的GPIO內部結構圖來額外補充Push-Pull output(推挽式輸出)的概念。


        ST官方 STM32 MCU AN4899 AP note

        並且會說明在軟韌體層面(以組合語言/指令集說明),是如何與上述的IO Port硬體運作進行相互作用/搭配而共同完成開發者肉眼可視的這些IO功能。

        此外,關於8051 MCU之Port0搭配Port2作為存取外部記憶體所使用的Address/Data bus的相關原理的部分,雖然現在的MCU很少直接這樣做了,但是仍為學習底層相關原理的一個重要概念,故仍然會在課程內對學員進行說明。


        相關文章:

        1.【課程介紹】本學習區已開設 & 未來即將開設之嵌入式系統軟韌體技術課程 & 課程特色!

        2. 許多人對於8051 MCU常有的錯誤觀念討論與闢除 (2020/10/12更新) 


        --------------------------

        孫文良 (阿良的嵌入式系統技術學習區)

        【若需要嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章

        2020年9月16日 星期三

        8051 MCU 錯誤觀念闢除 第二彈文章!

        歡迎透過合法的方式分享此文內容,若要轉載/轉貼,請明確貼出此原始連結並標示作者基本資訊請勿抄襲及非法轉貼(例如擷取內文但並未註明出處)

        為了闢除許多人對於嵌入式系統基礎學習的一些錯誤觀念,之前有發表過一篇文章:


        但發現還是有不少朋友無法完整理解上列文章內容,在這裡做一些常見的錯誤觀念迷思的Q&A給大家參考:

        Q1: 32bits ARM based的MCU不是比較好嗎?何必學這麼老舊的8051 MCU?

        A1: 雖然上面內容中已經有說明,但這裡再詳細解釋。

        很多人都誤以為用規格比較強的學習教材(嵌入式硬體平台),就代表自己神功附體,以為這樣子就可以讓學習效率大增。事實上,許多人常迷信於表面,以為自己用所謂ARM based的平台就代表自己比較厲害? 但其實在MCU應用開發的這塊,有多少人有去了解ARM CPU架構和指令集?多數人包含開課的講師通常也只不過將這個平台當成一塊MCU去跑code去設定周邊的registers而已不是嗎?有真正摸到ARM CPU架構嗎? 終究不就只是在玩一塊比較複雜的MCU? 真的有因為用ARM based的MCU所以就有去實際接觸到ARM CPU嗎? 終究不也是只是一樣在應用MCU內的各式周邊(如UART、I2C、SPI等等)? 其實CPU這塊當然是要有人理解的,例如搞出這個MCU軟體編譯工具與開發環境的工程師們,但這塊大多數已經被開源社群與IC design house做掉了,但這塊大多數已經被IC design house做掉了,對於MCU應用開發者來說,這塊已經是現成的工具。舉個例子,多數人玩MCU的C語言程式起跑點是main function,但是事實上在code flow跑到main function之前早就已經必須先去做其他事(startup),例如針對堆疊進行初始化等等(否則哪有C語言裡面這樣可以呼叫到函數跳來跳去的流程可用呢?),這塊是必要的,但是多數MCU應用者是拿現成的。好,把話題拉回來,用32bits MCU給初學者學,初學者真的會去細細探究這些已經是現成但較深入的部分嗎? 不會的,反而會因為32bits MCU的周邊大多較新穎又比8051的周邊複雜許多,反而會去忽略一些重要的周邊操作員裡細節基礎,而且也會因此而不敢挑戰這裡所說的所謂現成的部分(如透過Assembly組合語言去熟悉指令集),畢竟ARM(即便是ARM Cortex-Mx系列)指令集對於多數的所謂MCU應用初學者來說太複雜了(當然做MCU系統應用開發也未必就一定要很懂CPU這部分,但是用簡單具體而微的平台來熟悉一次這些細節,其基礎不是會更紮實嗎? 而且也會包含一些重要的細節如中斷、堆疊等底層原理,這就是我說的為何MCU初學者應該要先以8051這類較簡單MCU來入門的原因。並不是拿8051來應用,而是透過較簡易的MCU來徹底的了解一次MCU底層的這些細節,在經歷過這樣的過程後,未來要再接觸較複雜的MCU基本上也不是太大的問題)。反過來,如果一開始就學32bits MCU,不但可能沒有真正學到什麼ARM CPU架構,而且反而可能會因為這類MCU周邊的複雜度而混淆初學者應該要學到的一些重點,反而未必會讓基礎紮實。例如某些32bits MCU的Timer模式眾多且其對應設定過程相對繁複,因為這是針對許多現代各式產品應用而生,但這對於多數初學者而言可能太複雜了,其實初學者只要從8051那類較簡易的Timer去理解什麼是Timer和實際上如何使用的原理就夠了,而往後如果需要了解更複雜的Timer相信也不會是太大的問題,寧可不要讓初學者因為太複雜的周邊導致觀念混淆或者提前放棄。

        其實接觸國內名校的這些年來,我發現即便光是8位元的MCU,其實我沒看過有多少名校學生真正在第一次課程內就學得好的,至今依舊如此(MCU基礎範圍內其實還有基本介面電子電路等硬體觀念,並非只有MCU本身)。如果一開始就用複雜的MCU當教材,只是表面上好像用很新很強的平台在學習,但實際上並沒有讓初學者學得比較紮實,

        就像樹莓派學其實是個非常非常龐大的系統,許多初學者或學生表面上都會用,但是這類平台下面的內容硬要說起來就多得跟大海一樣廣又深,表面上的功能會動並不代表學生已經掌握了這些內容,只是拿了很多現成的東西去做相當後續的應用而已...我的第一份工作的公司就是做這類平台的,從這種大SoC IC到上面的整個系統軟韌體,這個複雜度比MCU還高太多太多(所以這種公司的研發工程師人數也很多),而許多初學者或學生甚至規劃課程的老師們並沒有去了解以及看到這個面向。而自己曾經帶過的同學們也蠻多在國內知名的MCU IC設計公司服務,所以整體來說,從產業經驗來回頭看,我還是覺得8051蠻適合教學的。

        --------

        Q2: 8051時脈這麼慢,學這有用嗎?

        A2: 其實這又是類似Q1的問題(千篇一律),我認為對於專業技術的學習效率應該不是硬體規格問題,學習一門技術所應該著重的是基礎,而不是在比較實驗教材的規格強弱(就像是使用個人電腦的人就代表懂個人電腦這麼複雜的系統設計嗎),何況MCU在多數的應用上通常本來就不是在比速度的呀(這是用途差異的問題),例如做許多I/O控制應用大多不需要太過於高速,畢竟需要等待例如馬達這些設備的反應,這些機電設備的反應動作速度是遠比不上MCU內的CPU的。如果在應用上需要複雜的演算,從系統設計的角度上來說,也未必適合在MCU端來做全部的演算,應由本身具備較強運算功能的平台專門做演算。(補充一下,近年來ST等大廠有一些很不像傳統MCU的較高速的MCU產品推出,通常用在某些具備多媒體應用功能的消費性電子產品裝置,但這類的MCU平台規格已經和網路多媒體類的SoC或Embedded Microprocessor這類通常具有MMU的CPU的平台的應用很相近了)。

        --------

        Q3: 近代新的MCU大多是32 bits,很多還是based on ARM Cortex-Mx CPU的MCU(如STM32/笙泉/盛群/新唐/松翰等廠商接有出產這類的MCU IC產品),若用8051會不會因為期開發環境太老舊而導致學習者在往後無法適應32 bits MCU呢?

        A3: 這不太是問題,因為現代MCU應用開發,不論8051 MCU或者32bits MCU,其開發環境基本上都是使用現成的圖形介面IDE(整合開發環境,如KEILC、IAR、STM32Cube等等),其環境大同小異(應該說幾乎一樣)。真正與MCU開發環境差異大的是Embedded Linux或者更精確地說是Linux kernel space相關系統軟體的開發,幾乎全部都是透過terminal敲指令式的開發環境,這種環境下很可能根本沒有IDE這類現成的圖形化介面可用,且就開發文化/生態系而言大多還是指令式較多。

        --------

        Q4: 繼Q1,初學者或學生們會因為用ARM based的MCU或SoC板子而突然神功附體、學習效益突飛猛進嗎?

        A4: 不會。因為初學者和學生的普遍學習狀況並不會因為硬體平台規格增強,所以就學得比較好和比較多。實際上,對於大多數的初學者來說,硬體平台複雜反而容易忽略很多重要的觀念,正因為複雜,為了能看到東西會動(功能會動),反而會使用表面或現成的內容草草帶過,其觀念容易零碎化。與其如此,那還不如用麻雀雖小五臟俱全、具體而微、易於學習掌握的平台,還比較能夠掌握到底層的細節基礎,雖然是具體而微的平台,但在學習體會過這些基礎內容之後,未來再去接觸複雜的平台也比較能接受,也比較有觀念,比較不會太過零碎。

        --------

        Q5: 那照上面這樣說,初學者學習MCU是否一定只能學8051不可?

        A5: 當然不一定只能用8051不可! 我也不是要當什麼8051的死忠擁護愛戴者,這些東西(平台)都是死的,沒什麼好迷信或死忠的。關鍵是要能從這些東西(平台)學到紮實且能延伸融會貫通的技術經驗和專業知識,才是核心重點。
        如果今天有一款平台像是8051這樣,擁有麻雀雖小五臟俱全且具體而微的特性,複雜度不至於太高(對初學者來說其實如果談細節的話還是不容易)的MCU,而且又有很多技術資料可參考(容易取得),那當然絕對不一定只能用8051。
        會推薦8051的原因只不過是因為這是一顆快要40年的長青樹等級的MCU,除了擁有較容易入門的特性外(事實上如果是用assembly並且針對MCU硬體架構細節原理去琢磨也已經有一些複雜度了),其技術資料、書籍和各路技術高手與網友們的經驗非常多,初學者相當容易取得這些資料來做為學習教材,所以才會這麼推薦用8051 MCU來作為教學平台。
        另外再次重申/強調,教學應該著重於基礎技術觀念的紮實度,而不該只是看重讓東西(功能)會動就好,既然應該著重的是基礎的紮實程度(如堆疊、中斷、常見周邊的運作基本原理特性等),所以用8051這種在此些方面複雜度不算太高的平台是再適合不過了。

        【若需要阿良的嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章

        2020年2月18日 星期二

        【使用STM32CubeIDE進行STM32 MCU軟韌體開發】STM32 Timer之計數器功能簡易使用教學與Demo

        歡迎透過合法的方式分享此文內容,若要轉載/轉貼,請明確貼出此原始連結並標示作者基本資訊請勿抄襲及非法轉貼(例如擷取內文但並未註明出處)

        • 前言
        有接觸過8051 MCU的朋友可能知道,在8051中,能夠使用其內部Timer來達成計數器(counter)的功能。對相關的暫存器設定完成無誤後,從8051晶片外部輸入負緣訊號(falling edge)到8051的T1或T0(對應Timer1和Timer0)腳位,即可實現計數功能。每當輸入一個負緣訊號,就會看到timer中的計數暫存器(THx/TLx)的值+1,也就是進行上數(count up)的動作

        而STM32系列MCU內部的Timer當然也有這種功能,只是又更加的複雜且多元(畢竟8051是30幾年被開發的MCU晶片)

        近期因為收到朋友的緊急協助需求,希望使用STM32 MCU上面的計數器的功能(由MCU外部輸入訊號達成計數)

        起初使用網路上許多文章所介紹使用ETR的方式(數年前曾用過),但在此IDE上使用STM32CubeMX tool作相對應的設定後沒有成功(原因尚不清楚,或許有些小地方沒注意到)。於是花了些時間查資料,後來在網路上有看到外國朋友所做的影片,是透過STM32CubeMX tool去做對應的設定,並產生出相對應的code。這篇文章會介紹參考這個影片的設定方式,並在STM32CubeIDE開發環境上面重現實驗和功能測試的過程,過程中會有一些與上述影片中不同的地方

        所以這篇文章就僅當成一個實驗紀錄供參考,暫時不分析講解STM32內部Timer的各種模式或較複雜的細節

        對於細節有興趣的朋友可自行參考ST官方文件,例如:



        ----------------

        • 本文重點
        我們用的實驗平台是STM32F407G-DISC1 (STM32 discovery系列的板子MB997D),與上述國外網友的影片中所用的平台型號不同


        - STM32F405xx, STM32F407xx MCU官方datasheet: 
        STM32F407G-DISC1開發板

        而從上述官方資料中的電路圖可得知,板子上面的藍色按鈕(代號B1)是被接到STM32F407VG MCU晶片的PA0這根pin腳,且平常是pull down(透過編號R39的220K電阻)的狀況,而當按鈕按下時會是一個high level訊號輸入PA0。如下圖:


        STM32F407G-DISC1開發板上的藍色小按鈕對應電路圖
        (圖片來源: 
        ST官方資料 UM1472 User manual Discovery kit with STM32F407VG MCU)

        而我們可以從STM32F407G datasheet的pin out & pin description中看到,PA0這隻腳位的Alternate functions欄位中,是有包含TIM2_CH1_ETR的。基本上這些資訊就提示了我們可以使用這塊開發板上面的藍色按鈕來進行計數器的MCU晶片外部訊號的產生來源(demo驗證功能用)


        STM32F407G datasheet中的PA0的pin out & pin description


        接下來開始關於軟體的部分。在STM32Cube IDE開設一個關於你自己的STM32平台所屬的專案(看是針對你的MCU型號或者你所使用的開發板型號)

        並且使用STM32CubeMX tool開啟專案內的.ioc檔案,在左方的Timers裡面的TIM2的Slave Mode設定為External Clock Mode 1 並將Mode(深灰色項目)中Trigger Source選擇為TI1FP1。此時會在右方MCU對應腳位圖看到PA0這根腳位被設為TIM2_CH1用途 (眾多alternate functions之一)

        STM32Cube IDE相關設定(Mode)


        再來接著進行Configuration(深灰色項目)中的設定,首先是Parameter Settings(深藍色選項,被選到時會變成比較淺的藍色)。注意: Counter Period一定要設定,且不能設為0。例如你設定100,那Timer最多計數到100,再到下一個tick時,計數值(CNT register的值)就會變成0,簡單來說這個就是設定上限。而因為這顆STM32F407的Timer2(TIM2)的長度是32bits,所以這個Counter Period在這顆MCU晶片上最多可以設定到2的32次方),Trigger polarity設為Rising Edge(正緣觸發)。設定畫面如下:

        STM32Cube IDE相關設定(Configuration-Parameter Settings)


        而關於計數器從外部輸入訊號所需對應的GPIO Settings(深藍色選項,被選到時會變成比較淺的藍色)如下圖,基本上在我這次的應用需求上沒什麼需要更動的

        STM32Cube IDE相關設定(Configuration-GPIO Settings)

        接下來就是按下Ctrl + S或者IDE上面的Project選項內的Generate Code,以產生相關的程式碼



        接著,在程式中加入實際執行時須呼叫的函式HAL_TIM_Base_Start(&htim2)以啟動TIM2 ,否則TIM2是不會動的。

        再來就是燒錄&執行程式(若不清楚操作步驟的朋友可參考網路上其他教學),這邊是用Debug模式進行測試 (透過板子上的stlink進行線上除錯模式觀看暫存器的值)。


        進入Debug模式後透過右上方的tool觀察TIM2之CNT暫存器的值

        執行結果如下影片(特別觀察上圖中下方紅色圈起來的地方的CNT(counter register)值的變化,每按一下板子上了藍色按鈕,其值即會+1(上數)。而用滑鼠點擊IDE畫面上的Debug tool的RD按鈕圖示是為了更新畫面上顯示的暫存器值



        另外,如果要用軟體的方式取得本例中的TIM2的CNT值,可以使用__HAL_TIM_GET_COUNTER這個macro function,其內容在stm32f4xx_hal_tim.h內



        __HAL_TIM_GET_COUNTER macro function

        而像本例是用TIM2,所以加上參數後的函式呼叫就是長這樣子: __HAL_TIM_GET_COUNTER(&htim2);


        【若需要嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章

        2020年2月15日 星期六

        【使用STM32CubeIDE進行STM32 MCU軟韌體開發】CMSIS-OS wrapping layer和FreeRTOS之thread優先權號碼之對應與互轉



        • 簡介:

        當我們使用STM32Cube IDE進行STM32 MCU的軟韌體開發時


        若有透過STM32CubeMX工具勾選FreeRTOS


        STM32Cube IDE將會自動產生(長出)結合了ARM CMSIS介面層與third party RTOS(我們目前的狀況下就是FreeRTOS)的code出來,加入到我們的MCU開發專案檔中

        本文將要介紹的code基本上都是由STM32Cube IDE所自動生成的code,將會追蹤一下這篇文章主題所要追蹤的一個小小部分的source code


        而關於這方面的一些較詳細的部分,例如何謂CMSIS,
        與third party RTOS之間的關係為何? 未來應該會再另寫文章作介紹,若有興趣的讀者可先參考ST官方文件: UM1722 User manual- Developing applications on STM32Cube with RTOS  以及下方於此ST官方文件中的架構圖


        CMSIS-RTOS Architecture(圖片來源: ST官方文件)



        而這篇文章的重點會放在有關於CMSIS-OS wrapping layer(以下簡稱CMSIS)和FreeRTOS的task優先權號碼之對應與互轉相關的部分

        基本上內容簡單,所以適合在BLOG將追蹤過程大致寫出來(技術過程太複雜的文章不太適合用BLOG寫)


        註: 本例是用CMSIS-RTOS V1來實驗的 (現在已經有V2了)

        ---------------------



        • 本文重點:


        當我們在屬於應用程式層的main.c裡面,要藉由CMSIS API創建thread(在FreeRTOS裡面稱作task)時,會需要指定優先權。例如osPriorityHigh或osPriorityNormal即為列舉(enum)內的常數元素項目的名稱(而此數這個常數就是優先權號碼)



        osThreadDef 的第三個參數即為優先權號碼

        而實際關於這部分的列舉型態宣告之內容如下圖:


        osPriority enum declaration in cmsis_os.h

        也就是關於我們在STM32Cube with CMSIS & FreeRTOS環境下的CMSIS創建thread時所指定的 -3到3這樣的7個優先權號碼,是CMSIS_OS這層介面所宣告制定的

        這時有或許有些接觸過FreeRTOS的人就會有疑問,FreeRTOS的優先權號碼,不是從0(the lowest priority)到configMAX_PRIORITIES - 1 嗎(the highest priority, 預設是6)嗎? 這之間如何對應呢?

        FreeRTOSConfig.h

        實際上,CMSIS的優先權號碼(-33),是對應到FreeRTOS06(configMAX_PRIORITIE-1,而在FreeRTOSConfig.h內的configMAX_PRIORITIES預設是7,所以號碼就是06)

        關於這方面的互轉實作,可以參考cmsis_os.c makeFreeRtosPriority()makeCmsisPriority() 這兩隻函數即可看出來(前者的作用就是就是將CMSISthread優先權號碼轉為FreeRTOS的優先權號碼。而後者的作用就是與前者相反)

        makeFreeRtosPriority和makeFreeRtosPriority API

        這邊舉個實際例子例如CMSIS層的優先權3,在makeFreeRtosPriority函式裡面就會去減掉-3 (由程式碼裡面的priority - osPriorityIdle可得知,這邊的priority3,而osPriorityIdle從上面介紹過的cmsis_os.h中的宣告是-3),而3-3會得到6,可以簡單地從這些資訊判斷CMSIS層的優先權號碼3,其實是對應到FreeRTOS的優先權號碼6

        再舉另一個例子如果CMSIS層的優先權號碼-3,就會對應到FreeRTOS的優先權號碼0,因為-3減-3會得到0。其餘號碼皆以此類推


        而理所當然地,osThreadCreate()的內容中,會去呼叫到makeFreeRtosPriority(),以此完成CMSISthread優先權號碼與FreeRTOS thread優先權號碼的轉換對應


        osThreadCreate API


        所以總結一下,下表為CMSISFreeRTOS優先權號碼對照表






        另外,最後也將osThreadDefosThread以及 os_thread_def struct貼出來供參考

        osThreadDef




        os_thread


         os_thread_def  struct


        【若需要嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章