Embedded
使用 ALIENTEK正點原子 探索者 STM32F407 開發板
CPU: Cortex-M4 (ARMv7-M 架構)
FLASH: 1Mbytes
RAM: 128 KB
市面上常見用來開發 Cortex-M 的 IDE 整理在下表
IDE 名稱 | Pros | Cons |
---|---|---|
Keil µVision | 適合新手,不需要太多環境的設置就能開始寫程式,算是最簡單能夠上手的 IDE | 此為授權軟體,免費版限制程式大小最大為 32 KB,超過則需要付費。 另外不知道為何,我用 STM32CubeMX 產生的程式碼跟我設定的有誤,在 STM32CubeIDE 就沒這問題 |
STM32CubeIDE | 專門用來寫 STM32 的 IDE,各種功能都整合得很好,因為是基於 Eclipse,所以有用過 Eclipse 大概會覺得很親切 | 沒什麼缺點,硬要說的話就是設定比 µVision 多一點,autocomplete 不像 µVision 能夠自動觸發 |
GNU MCU Eclipse | 完全開源的 IDE | 多年前用過覺得設定相當複雜,不但要了解檔案樹,還要懂 openocd、linker 等,看了一個月可能都還不會用 |
使用 Keil µVision 如果超過 32KB,則會出現以下錯誤
error: L6050U: The code size of this image (66612 bytes) exceeds the maximum allowed for this version of the linker.
先開啟一個 Project,並試著燒錄程式到板子上。我的 Debugger 叫 fireDAP,所以使用 openocd,在 Run Configuration ➔ 調試器 (debugger) ➔ 調試探頭 中選擇 ST-Link (OpenOCD),並且在底下的 Configuration Script 中選擇 User Defined,接著我們要修改 openocd 的腳本
在 xxx.cfg 的檔案中修改 source 跟 transport 這兩行,根據你使用的 debugger 會有所不同
按一下 Run 的箭頭應該就可以燒錄了
Semihosting 可以讓 Target 跟主機用 debugger 來做溝通,所以就不用另外用一個 UART 做 debug。具體來說,可以在板子上呼叫 printf,IDE 的 Console 就可以看到結果,或者是把除錯資料輸出到一個檔案中,方便之後做 debug。
以下這篇說明得很清楚,照做就可以了,exclude 那一欄要注意路徑,在我的 Project 裡要是設定 Src/syscalls.c
https://shawnhymel.com/1840/how-to-use-semihosting-with-stm32/
到目前為止基本的設定都做好了
在不需要 Debug 的時候應該要註解掉所有 printf 及相關輸出的操作,否則之後在燒錄的時候就不能正常運作,程式會卡在 printf 裡。
試試看點亮板子上的 LED 確認一切都能正常運作
這個暫存器可以控制 slew rate,也就是電壓從 low 到 high 或是從 high 到 low 所需要的時間,STM32F407 提供四種速度
參考 http://fastbitlab.com/gpio-output-speed-register-applicability/
From STM32F4-Technical-Training
參考
http://wiki.csie.ncku.edu.tw/embedded/GPIO#stm32f4xx-gpio特性
先來試試最簡單的外部中斷,剛好板子上有按鈕,就直接拿來用,硬體電路圖如下
使用 KEY2,這個按鈕最後連接到 PE2 腳位,沒有消除彈跳的硬體,下面三個按鈕都連到接地,所以之後要在 STM32 晶片裡設定 PULL-UP。
開啟外部中斷有幾個步驟
HAL_GPIO_EXTI_Callback
Prototype 為
Q. STM32F4 明明不同的 EXTI line 都有對應的外部中斷函數,為什麼不同 line 的 callback 都是使用
HAL_GPIO_EXTI_Callback
?A. HAL 函數庫對以上 IRQ 做封裝,他們最後都會呼叫使用者定義的
HAL_GPIO_EXTI_Callback
,使用者必須檢查 GPIO_Pin 來得知這是哪一條 line 的外部中斷
簡單跑一下試試看,順便檢查是否有按鍵彈跳會重複觸發外部中斷
輸出結果,果不其然按鍵有彈跳,當我按一下按鍵會同時印出好幾行
參考
http://wiki.csie.ncku.edu.tw/embedded/PWM
試試看 STM32F4 的 PWM 功能,嘗試讓板子上的 LED 變成呼吸燈。
PWM 功能有兩個重要的暫存器,ARR (autoreload register) 和 CRR,Tim14 只有一個通道所以只有一個 CCR 暫存器叫 CCR1
使用以下設定
Counter Settings:
PWM Generation Channel 1:
因為開發版上的 LED 是低電平亮,所以 Polarity 設定 Low,讓 CCR1 數值 (duty cycle) 越大時 LED 越亮,反之越暗。
以下盡量只列出使用者程式碼的部分
This is an identifier that tells you which of the physical PHYs were used to interface to the network. The numbers range from 0 - 31 and change, depending on whether or not you specified a specific PHY or if you let the driver select the default (which varies from card to card).
PHY 外部晶片在初始化時,需要指定 PHY Address (非實體記憶體),數值介於 0 到 31 之間,因為一個 MAC 介面最多可以控制 32 個 PHY,這張板子的 PHY 設定在 0,用以下的程式碼設定。
我使用開源軟體叫做 SOEM,此專案提供輕量級的 EtherCAT 函式庫,由於官方並沒有支援 stm32 架構,因此必須動手修改程式碼,由於 SOEM 軟體架構做了很明確的分層,所要修改的程式碼並不多,要修改檔案的目錄如下
gettimeofday
和 osal_usleep
,使用 timer 就能很簡單的做出 osal_usleep
,而 gettimeofday
大概需要 RTC,但我是寫死一個起始數值,從開機後累加時間HAL_ETH_*
系列函式實作。搞定上面兩個目錄 SOEM 就能移植到 stm32 的板子上了,如果遇到問題有很大的機率是 Ethernet 初始化沒設定好。
我遇到的問題是使用 auto negotiation 無法直接連接,板子和驅動器之間必須接上 switch 才能正常互通,把 auto negotiation 關掉再調整一些 timing 就成功連上驅動器了。
stm32f4 移植參考的專案: https://os.mbed.com/users/EasyCAT/code/SOEM//file/543d6784d4cc/oshw/nicdrv.cpp/
nicdrv.c 會是需要修改最多的檔案,如果是使用 STM32cubeIDE 設定 ETH,ETH 初始化對應的程式碼會自動產生,所以就不用另外寫了。 (但還是要注意 auto negotiation,STM32cubeIDE 似乎沒有處理 disable 的情況)
PDO 分為兩種,在規格書 (CiA402) 中稱作 Transmit-PDOs (TPDOs) and Receive-PDOs (RPDOs),但台達手冊稱作 TxPDO 和 RxPDO。
TxPDO 和 RxPDO 是以從站的角度來看,自從站發出的訊息是 TxPDO,接收的訊息叫 RxPDO
Index Start from | |
---|---|
TxPDO | 0x1A00 |
RxPDO | 0x1600 |
TxPDO0 index: 0x1A00
TxPDO1 index: 0x1A01
以此推類…
The mappings are held in the sub-indexes and are encoded as 32-bit unsigned integers
參考: https://stackoverflow.com/questions/27132341/how-to-setup-pdo-mapping
還未修改 PDO Mapping 之前驅動器的設定如下所示,注意 SM2 和 SM3 兩列輸出,他們分別對應 RxPDO 和 TxPDO。
修改 PDO Mapping 之後預期可見 SM2 和 SM3 的輸出改變
我用的是以下這片觸控螢幕
LCD 驅動晶片 | 電容觸控驅動晶片 | 解析度 |
---|---|---|
SSD1963 | FT5206 | 800*480 |
實際使用
:warning: 注意如果初始化後出現畫面閃爍,或是印出雜訊,極有可能是 FSMC 的 timing 沒有設定好,很大可能是因為設得太小導致的!
可嘗試使用以下設定:
參考:
https://arm-stm.blogspot.com/2016/12/ssd1963-init-collection.html
https://www.youtube.com/watch?v=dQoy4wQpcTI&ab_channel=EEbyKarl
https://support.touchgfx.com/zh-TW/docs/development/touchgfx-hal-development/touchgfx-generator