文章目錄
- 有了Linux為什么還需要寫匯編?
- STM32 IO初始化流程
- I.MX6Q IO初始化流程
- 1、使能時鐘
- 2、IO復用
- IO命名
- IO復用
- 3、電氣屬性
- 電氣屬性
- GPIO功能圖
- 4、GPIO配置
- 配置GPIO功能
本人原使用平臺為STM32F407,對于i.MX6平臺的使用,通過STM32的對照來進行學習,
有了Linux為什么還需要寫匯編?
首先是帶來一個疑問,既然平臺使用i.MX6,有了Liunx作業系統,按理來說我們應該更多的精力放在上層的設計,
我們在學習 STM32的時候幾乎沒有用到過匯編,可能在學習 UCOS、 FreeRTOS等 RTOS類作業系統移植的時候可能會接觸到一點匯編,
但是我們在進行嵌入式 Linux開發的時候是絕對要掌味訓本的 ARM匯編,因為 Cortex-A芯片一上電 SP指標還沒初始化, C環境還沒準備好,所以肯定不能運行 C代碼,必須先用匯編語言設定好 C環境,比如初始化 DDR、設定 SP指標等等,當匯編把 C環境設定好了以后才可以運行 C代碼,
所以 Cortex-A一開始肯定是匯編代碼,其實 STM32也一樣的,一開始也是匯編,以 STM32F103為例,啟動檔案startup_stm32f10x_hd.s就是匯編檔案,只是這個檔案 ST已經寫好了,我們根本不用去修改,所以大部分學習者都沒有深入的去研究,
對于 Cortex-A芯片來講,大部分芯片在上電以后 C語言環境還沒準備好,所以第一行程式肯定是匯編的,至于要寫多少匯編程式,那就看你能在哪一步把 C語言環境準備好,
所謂的 C語言環境就是保證 C語言能夠正常運行, C語言中的函式呼叫涉及到出堆疊入堆疊,出堆疊入堆疊就要對堆疊進行操作,所謂的堆疊其實就是 一段記憶體,這段記憶體比較特殊,由 SP指標訪問, SP指標指向堆疊頂,
芯片一上電 SP指標還沒有初始化,所以 C語言沒法運行,對于有些芯片還需要初始化 DDR,因為芯片本身沒有 RAM,或者內部 RAM不開放給用戶使用,用戶代碼需要在DDR中運行,因此一開始要用匯編來初始化 DDR控制器,后面學習 Uboot和 Linux 內核的時候匯編是必須要會的,
STM32 IO初始化流程
- 使能GPIO時鐘
- 設定IO復用,將其復用為GPIO
- 配置GPIO的電氣屬性
- 使用GPIO,輸出高/低電平
I.MX6Q IO初始化流程
1、使能時鐘
- 使能時鐘,CCGRO-CCGR6這7個暫存器控制著所有外設的使能, 為了簡單,設定CCGRO-CCGR6這7個暫存器全部為0xFFFFFFFF,相當于使能所有外設時鐘,

2、IO復用
IO命名
STM32中的 IO都是 PA0~15、 PB0~15這樣命名的, I.MX6U的 IO是怎么命名的呢?打開I.MX6UL參考手冊的“IOMUX Controller(IOMUXC)”,如圖

圖中的形如“ IOMUXC_SW_MUC_CTL_PAD_GPIO1_IO00”的就是 GPIO命名,命名形式就是“ IOMUXC_SW_MUC_CTL_PAD_XX_XX”,后面的 XX_XX”就是 GPIO命名,比如: GPIO1_IO01、 UART1_TX_DATA、 JTAG_MOD、 SNVS_TAMPER1等等, I.MX6U的 GPIO并不像 STM32一樣以 PA0~15這樣命名,他是根據某個 IO所擁有的功能來命名的,比如我們一看到 GPIO1_IO01就知道這個肯定能做 GPIO,看到 UART1_TX_DATA肯定就知道這個 IO肯定能做為 UART1的發送引腳,“ IOMUX Controller(IOMUXC)”這一章列出了I.MX6U的所有 IO,如果你找遍第 30章的書簽,你會發現貌似 GPIO只有GPIO1_IO00~GPIO1_IO09,難道 I.MX6U的 GPIO只有這 10個?
顯然不是的, 我們知道 STM32的很多 IO是可以復用為其它功能的,那么 I.MX6U的其它 IO也是可以復用為 GPIO功能,同樣的,GPIO1_IO00~GPIO_IO09也是可以復用為其它外設引腳的,接下來就是 I.MX6U IO復用,
IO復用
- IO復用,將暫存器IOMUXC_SW_MUX_CTL_PAD_GPIO03的bit2-0設定為 101 = 5,這樣IO口就復用為GPIO1_IO03,

"IOMUX Controller(IOMUXC)”的書簽中,每一個 IO會出現兩次,它們的名字差別很小,不仔細看就看不出來,比如 GPIO1_IO00有如下兩個書簽:

3、電氣屬性
電氣屬性
-
電器屬性,暫存器IOMUXC_SW_PAD_CTL_PAD_GPIO03,包括壓擺率、速度、驅動能力、開漏、上下拉等,
這也是個 32位暫存器,但是只用到了其中的低 17位,在看這寫位的具體含義之前,先來看一下圖 8.1.4.2所示的 GPIO功能圖:

GPIO功能圖

HYS(bit16):對應圖中 HYS,用來使能遲滯比較器,當 IO作為輸入功能的時候有效,用于設定輸入接收器的施密特觸發器是否使能,如果需要對輸入波形進行整形的話可以使能此位,此位為 0的時候禁止遲滯比較器,為 1的時候使能遲滯比較器,PUS(bit15: 對應圖中的 PUS,用來設定上下拉電阻的,一共有四種選項可以 選擇,如表所示:

PUE( 圖沒有給出來,當 IO作為輸入的時候,這個位用來設定 IO使用上下拉還是狀態保持器,當為 0的時候使用狀態保持器,當為 1的時候使用上下拉,狀態保持器在IO作為輸入的時候才有用,顧名思義,就是當外部電路斷電以后此 IO口可以保持住以前的狀態,
PKE( 對應圖中的 PKE,此為用來使能或者禁止上下拉 /狀態保持器功能,為0時禁止上下拉 /狀態保持器,為 1時使能上下拉和狀態保持器,ODE(bit11):對應圖中的 ODE,當 IO作為輸出的時候,此位用來禁止或者使能開路輸出,此位為 0的時候禁止開路輸出,當此位為 1的時候就使能開路輸出功能,
SPEED(bit7: 對應圖中的 SPEED,當 IO用作輸出的時候,此位用來設定 IO速度,設定如表所示:

DSE(bit5:3):對應圖中的 DSE,當 IO用作輸出的時候用來設定 IO的驅動能力,總共有 8個可選選項,如表所示:

SRE( 對應圖中的 SRE,設定壓擺率,當此位為 0的時候是低壓擺率,當為 1的時候是高壓擺率,這里的壓擺率就是 IO電平跳變所需要的時間,比如從 0到 1需要多少時間,時間越小波形就越陡,說明壓擺率越高;反之,時間越多波形就越緩,壓擺率就越低,如果你的產品要過 EMC的話那就可以使用小的壓擺率,因為波形緩和,如果你當前所使用的 IO做高速通信的話就可以使用高壓擺率,
4、GPIO配置
IOMUXC_SW_MUX_CTL_PAD_XX_XX
和
IOMUXC_SW_PAD_CTL_PAD_XX_XX
這兩種暫存器都是配置 IO的,注意是 IO!不是 GPIO GPIO是一個 IO眾多復用功能中的一種,比如 GPIO1_IO00這個 IO可以復用為: I2C2_SCL、 GPT1_CAPTURE1、 ANATOP_OTG1_ID、ENET1_REF_CLK、 MQS_RIGHT、 GPIO1_IO00、ENET1_1588_EVENT0_IN、SRC_SYSTEM_RESET和 WDOG3_WDOG_B這 9個功能, GPIO1_IO00是其中的一種,我們想要把 GPIO1_IO00用作哪個外設就復用為哪個外設功能即可,如果我們要用 GPIO1_IO00來點個燈、作為按鍵輸入啥的就是使用其 GPIO(通用輸入輸出 )的功能,將其復用為 GPIO以后還需要對其 GPIO的功能進行配置,關于 I.MX6的 GPIO請參考
《 IMX6芯片手冊》
的第 28章“ Chapter 28 General Purpose Input/Ouput( GPIO結構如圖所示:

配置GPIO功能
配置GPIO功能,設定輸入輸出,
設定GPIO1_GDIR暫存器,因為是IO03,所以是bit3位

根據上圖,bit3為1為OUTPUT模式,設定為輸出模式,
設定GPIO1_DR暫存器的bit3,為1表示輸出高電平,為0表示輸出低電平,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/224351.html
標籤:其他
上一篇:2020-11-17
