RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Cortex-M3入門指南(二):寄存器

安芯教育科技 ? 來源:極術(shù)社區(qū) ? 2023-05-31 17:36 ? 次閱讀
這篇文章我們將會來講講嵌入式系統(tǒng)中非常重要的概念 —— 寄存器。因為單片機(jī)對于外界響應(yīng)和自身功能的控制基本上全部都要通過寄存器進(jìn)行交互,所以寄存器的使用將會貫穿整個單片機(jī)的學(xué)習(xí)過程。這篇文章將通過手把手重寫我們的 Blinky 程序來介紹寄存器的概念和操作方法。

文章前半部分會先講寄存器的基本原理,然后后半部分再通過代碼示范寄存器的操作方法。

這里使用的嵌入式平臺是 STM32F103,它的的寄存器手冊可以在 這里 下載

寄存器操作

在之前我們說過: 寄存器指代的是一段特殊的內(nèi)存地址區(qū)域,但是它沒有實際對應(yīng)的 SRAM (Static Random-Access Memor, 靜態(tài)隨機(jī)存取存儲器) 存儲,對寄存器的操作與對內(nèi)存的操作完全一致,可以將寄存器當(dāng)作內(nèi)存來讀寫,而對寄存器內(nèi)存段的讀寫將會被轉(zhuǎn)化為總線上與外設(shè)的數(shù)據(jù)交換。 所以對寄存器的操作實際上就是對特殊地址的內(nèi)存進(jìn)行讀寫操作。在手冊中我們可以找到各寄存器的起始地址 (28頁): 6c14865e-ff8d-11ed-90ce-dac502259ad0.jpg

我們拿 GPIOA 外設(shè)的寄存器來做個例子,我們跳到手冊中 GPIO 的章節(jié) (115頁),這里有一張表格列出了 GPIO_BSRR 寄存器的結(jié)構(gòu)。 這個寄存器到底有什么用并不重要,我們這里只需掌握如何讀懂寄存器表格: 6c27b1f2-ff8d-11ed-90ce-dac502259ad0.jpg ?第一行是偏移地址。偏移地址指明了這個寄存器相對于外設(shè)寄存器區(qū)段的位置,從起始地址表中我們可以知道 GPIOA 寄存器區(qū)段的起始地址是 0x4001_0800,而 GPIO_BSRR 的偏移地址為 0x10,因此 GPIOA 的 GPIOA_BSRR 寄存器的真正地址即為 0x4001_0800 + 0x10 = 0x4001_0810。 下面的兩行格子是寄存器位的說明。格子上的數(shù)字是位偏移地址,格子中間的是位的名稱,格子下面的是可讀寫性,這里格子下方都是 w,也就是說這些位都是只寫位。 根據(jù)下方說明,如果我們要對 ODR3(另一個寄存器的位) 清0,我們就要對 BR3 寫1。這個操作實際上就是對 0x4001_0810 內(nèi)存地址寫 0x1 << 19 (除第19位以外都是0的32位無符號整數(shù))。 使用 Rust 來操作就是這樣:
core::write_volatile(0x4001_0810 as *mut u32, 1 << 19);

GPIO(通用接口)

Blinky 的原理很簡單,只需定時改變連接 LED 的引腳的電平,就可以讓 LED 閃爍起來了。我們查看核心板的電路原理圖可以發(fā)現(xiàn) LED 被連接在了 PC13 引腳上,而且從原理圖中可以看出 LED 采用了共陽極接法,當(dāng)引腳輸出低電平時 LED 才會點亮: 6c412af6-ff8d-11ed-90ce-dac502259ad0.jpg6c53e704-ff8d-11ed-90ce-dac502259ad0.jpgSTM32F103C8T6 引腳圖 注意:有的 STM32F103 核心板 LED 會連接在 PB12 引腳上,需要查看原理圖來確定。 STM32 中的引腳被分為了 GPIOA,GPIOB,GPIOC,GPIOD ... 等等多個組,每組中各控制有 16 個引腳,每個組都是一個獨立的外設(shè)。 在這里,我們需要學(xué)習(xí) GPIO 兩個關(guān)鍵寄存器:配置寄存器 (GPIOx_CRL,GPIOx_CRH) 和置位/復(fù)位寄存器 (GPIOx_BSRR)。(寄存器名中的 x 即為 GPIO 分組中的 A, B, C .. 等等)

GPIO 配置寄存器

單片機(jī)的引腳往往兼有多種功能,比如輸入或輸出,因此在使用引腳之前要通過配置寄存器配置它的功能。 我們注意到這里出現(xiàn)了兩個配置寄存器 GPIOx_CRL 和 GPIOx_CRH,這其實是配置寄存器的高/低部分,低寄存器 (GPIOx_CRL) 負(fù)責(zé)配置 0..7 號引腳,高寄存器 (GPIOx_CRH) 負(fù)責(zé)配置 8..15 號引腳。

GPIO 擁有以下幾種模式:

  • 輸入浮空
  • 輸入上拉
  • 輸入下拉
  • 模擬輸入
  • 開漏輸出
  • 推挽式輸出
  • 推挽式復(fù)用功能 ─ 開漏復(fù)用功能

輸入可以理解為讀取引腳上的電平,相反,輸出就是控制引腳電平。因為我們想要通過控制引腳電平來點亮 LED,所以我們這里選擇輸出模式。

輸出模式有 推挽式輸出 和 開漏輸出 兩種。推挽輸出模式下引腳可以自行輸出高低兩種電平,但是電流驅(qū)動力較弱,適合于和數(shù)字元件通訊或驅(qū)動 LED;開漏輸出只有低電平和截止兩種狀態(tài),所以需要在電路上加上 上拉電阻 (一端電源一端接引腳的電阻) 才能在截止?fàn)顟B(tài)下輸出高電平,開漏輸出的電流驅(qū)動能力更強, 適合于做電流型的驅(qū)動。 這里我們選擇最簡單的推挽式輸出模式就可以了。 查閱手冊我們可以找到配置寄存器的結(jié)構(gòu) (114頁): 6c690148-ff8d-11ed-90ce-dac502259ad0.jpg ?PC13 引腳對應(yīng)了 MODE13 和 CNF13 兩段寄存器位,我們將 MODE13 設(shè)置為輸出模式即 0x11 (最大速度指的是最大電平翻轉(zhuǎn)頻率,這里任選一個都行),然后將 CNF13 設(shè)為 0x00 就可以推挽輸出了。

GPIO 置位/復(fù)位寄存器

置位/復(fù)位寄存器專門用于操作引腳輸出電平,對 BR (R意為Reset) 寫1會讓對應(yīng)引腳輸出低電平,對 BS (S意為Set) 寫1會讓對應(yīng)引腳輸出高電平。操作十分簡單,這里就不贅述了。 6c27b1f2-ff8d-11ed-90ce-dac502259ad0.jpg ? ?

RCC 總線開關(guān)

總線就是之前提到過的時間總線 APB1 和 APB2。單片機(jī)中的任何外設(shè)都需要從總線上獲取時間信號,然而在單片機(jī)啟動復(fù)位后,所有外設(shè)都是默認(rèn)關(guān)閉來節(jié)省能源,因此在使用外設(shè)前需要手動打開總線開關(guān)。 RCC (Reset and Clock Control,復(fù)位和時鐘控制器) 負(fù)責(zé)單片機(jī)時間總線相關(guān)的配置,它的 APB2ENR 寄存器用于開關(guān) APB2 總線上的外設(shè)。而 GPIO 外設(shè)位于 APB2 總線上,我們查找 RCC_APB2ENR 寄存器 (95頁): 6c853c46-ff8d-11ed-90ce-dac502259ad0.jpg6c927190-ff8d-11ed-90ce-dac502259ad0.jpg ?從圖中可知,對 APB2ENR 的 IOPCEN 寫 1 就可以啟動 GPIOC 外設(shè)。

Blinky 示例

我們打開之前文章建立的工程項目,修改 src/main.rs 恢復(fù)為最小可編譯版本:
#![no_std]
#![no_main]
 extern crate panic_halt;
use core::ptr;
use cortex_m::asm;
use cortex_m_rt::entry;
use stm32f103xx;
#[entry]
 fn main() -> ! {
     asm::nop();
     loop { }
  }
修改 Cargo.toml 中的依賴。在這里我們暫時沒有使用 stm32f103xx 的寄存器功能,只是讓編譯器自動鏈接它提供的中斷向量表,否則會無法編譯:
 [denpendencies] cortex-m = "0.5.8" cortex-m-rt = "0.6.5" panic-halt = "0.2.0" stm32f103xx = "0.11"
我們根據(jù)手冊的信息定義寄存器的地址:
const RCC_APB2ENR: *mut u32 = (0x4002_1000 + 0x18) as *mut u32;
const GPIOC_CRH: *mut u32 = (0x4001_1000 + 0x04) as *mut u32;
const GPIOC_BSRR: *mut u32 = (0x4001_1000 + 0x10) as *mut u32;
再定義要用到的寄存器位偏移量:
const APB2ENR_IOPCEN: usize = 4;
const CRH_MODE13: usize = 20;
const BSRR_BS13: usize = 13;
const BSRR_BR13: usize = 13 + 16;
修改 main 函數(shù)。
#[entry]
fn main() -> ! {
    unsafe {
// 啟用 GPIOC
        ptr::write_volatile(RCC_APB2ENR, 1 << APB2ENR_IOPCEN);
// 配置 GPIOC - PC13 為推挽輸出
        ptr::write_volatile(GPIOC_CRH, 0b0011 << CRH_MODE13);
// 重置 PC13 以輸出低電平
        ptr::write_volatile(GPIOC_BSRR, 1 << BSRR_BR13);
    }
    loop { }
}
注意這里使用了 ptr::write_volatile() 進(jìn)行內(nèi)存寫入操作,這是因為如果使用 ptr::write() 函數(shù),編譯器有可能會把內(nèi)存的寫入操作優(yōu)化掉或者調(diào)換執(zhí)行順序,這在內(nèi)存操作上可以提高效率,但在寄存器上會完全改變我們程序的意圖,導(dǎo)致不可預(yù)測的后果。對寄存器的讀操作也同樣不能使用 ptr::read() 而要使用 ptr::read_volatile()。 此時編譯運行就能看到點亮的 LED 了。 接下來我們制造一個簡單的延遲函數(shù):
fn delay() {
for _ in 0..2_000 {
asm::nop();
    }
}
這里使用了一個匯編函數(shù) nop,即為 No Operation。它會空轉(zhuǎn)耗費 CPU 一個時鐘周期,然后我們再對它循環(huán)來得到一個肉眼可見的延遲。 其實按照 Cortex-M3 72MHz 的時鐘速率來計算,2000 周期級別的延遲也應(yīng)該在毫秒級以下,然而這里的延遲竟然可以達(dá)到半秒左右。這是因為在單片機(jī)剛啟動的時候,芯片默認(rèn)采用了啟動較快但是頻率較低的內(nèi)部時鐘,頻率大概在 40kHz 左右,一般情況下我們在復(fù)位后要設(shè)置 RCC 的寄存器將時鐘源轉(zhuǎn)為外部高速時鐘,這部分我們留到之后再細(xì)講。 修改 loop 循環(huán):
loop {
    delay();
// Reset:輸出低電平,點亮 LED
    unsafe { ptr::write_volatile(GPIOC_BSRR, 1 << BSRR_BR13); }
    delay();
// Set:輸出高電平,LED 熄滅
    unsafe { ptr::write_volatile(GPIOC_BSRR, 1 << BSRR_BS13); }
}
至此我們的寄存器版本的 Blinky 就完成了!下面是完整代碼:
#![no_std]
#![no_main]
extern crate panic_halt;
use core::ptr;
use stm32f103xx;
use cortex_m::asm;
use cortex_m_rt::entry;
const RCC_APB2ENR: *mut u32 = (0x4002_1000 + 0x18) as *mut u32;
const GPIOC_CRH: *mut u32 = (0x4001_1000 + 0x04) as *mut u32;
const GPIOC_BSRR: *mut u32 = (0x4001_1000 + 0x10) as *mut u32;
const APB2ENR_IOPCEN: usize = 4;
const CRH_MODE13: usize = 20;
const BSRR_BS13: usize = 13;
const BSRR_BR13: usize = 13 + 16;
#[entry]
fn main() -> ! {
    unsafe {
// 啟用 GPIOC
         ptr::write_volatile(RCC_APB2ENR, 1 << APB2ENR_IOPCEN);
// 配置 GPIOC - PC13 為推挽輸出
        ptr::write_volatile(GPIOC_CRH, 0b0011 << CRH_MODE13);
// 重置 PC13 以輸出低電平
        ptr::write_volatile(GPIOC_BSRR, 1 << BSRR_BR13);
    }
     loop {
        delay();
// Reset:輸出低電平,點亮 LED
        unsafe { ptr::write_volatile(GPIOC_BSRR, 1 << BSRR_BR13); }
        delay();
// Set:輸出高電平,LED 熄滅
        unsafe { ptr::write_volatile(GPIOC_BSRR, 1 << BSRR_BS13); }
    }
}
fn delay() {
for _ in 0..2_000 {
        asm::nop();
    }
}

Blinky:抽象

上面代碼中使用的就是 C 語言中操作寄存器的方法,簡單直接。雖然這樣可用,但是可以看出這樣操作的語義非常模糊,常常需要反復(fù)翻查手冊,而且這樣會大量使用 unsafe 內(nèi)存操作,很容易發(fā)生人為錯誤。幸好,Rust 為我們提供了更安全的抽象,可以極大地改善以上兩個問題。 stm32f103xx 庫安全地封裝了寄存器的操作接口,而且它是由 svd2rust 自動生成的,所以可以杜絕人工錯誤。在 這里 可以找到它的文檔。 我們來看看怎樣使用這個庫:
// 獲取 Peripheralslet dp = stm32f103xx::take().unwrap();// 啟用 GPIOCdp.RCC.apb2enr.write(|w| w.iopben().enabled());
第一行的 stm32f103xx::take() 只會在第一次調(diào)用時返回 Some(dp),這樣避免了存在多個寄存器實例而的導(dǎo)致數(shù)據(jù)競爭。 Peripherals 是一個結(jié)構(gòu)體,它擁有所有外設(shè)的接口定義,比如說這里的 RCC??梢詫?RCC 的 apb2enr 寄存器進(jìn)行寫操作,這個庫對寄存器的讀寫操作都被包含在了閉包中,這樣庫可以在讀寫前后執(zhí)行一些保險操作(重置寄存器值或關(guān)閉中斷)。w 是 apb2enr 的寫入器,我們對其調(diào)用 w.iopben().enabled() 和之前使用 unsafe 寫入內(nèi)存完全等價,而且 zero-cost,編譯后的指令一般不會有差別。 同理我們對 GPIOC 的操作可以改寫為:
// 配置 PC13dp.GPIOC.crh.write(|w| w.mode13().output().cnf13().push());// Setdp.GPIOC.bsrr.write(|w| w.bs13().set());// Resetdp.GPIOC.bsrr.write(|w| w.br13().reset());
完整代碼:
#![no_std]
#![no_main]
extern crate panic_halt;
use core::ptr;
use stm32f103xx;
use cortex_m::asm;
use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
// 獲取 Peripherals
    let dp = stm32f103xx::take().unwrap();
// 啟用 GPIOC
    dp.RCC.apb2enr.write(|w| w.iopben().enabled());
// 配置 PC13
    dp.GPIOC.crh.write(|w| w.mode13().output().cnf13().push());
    loop {
        delay();
// Reset:輸出低電平,點亮 LED
        dp.GPIOC.bsrr.write(|w| w.br13().reset());
        delay();
// Set:輸出高電平,LED 熄滅
        dp.GPIOC.bsrr.write(|w| w.bs13().set());
    }
}
fn delay() {
for _ in 0..2_000 {
        asm::nop();
    }
}
相比于 C style 的寄存器操作,svd2rust 封裝了所有寄存器地址信息,而且不需要使用任何 unsafe 代碼,這在 Rust 中保證了不會出現(xiàn)任何內(nèi)存錯誤。

Blinky:再抽象

stm32f103xx 的表現(xiàn)非常驚艷,但是這還沒能完全發(fā)掘 Rust 的潛力。嵌入式工作組為我們提供了 embedded-hal 抽象庫,stm32f103xx-hal 就是 embedded-hal 在 stm32f103 上的具體實現(xiàn)。stm32f103xx-hal 庫在 stm32f103xx 的基礎(chǔ)上再次抽象封裝了寄存器的邏輯細(xì)節(jié)。比如說,stm32f103xx-hal 可以在我們使用 GPIOC 前自動啟用 apb2enr 總線開關(guān)。同樣,這個庫也是 zero-cost 的。 修改 Cargo.toml,添加依賴:
[dependencies.stm32f103xx-hal]features = ["rt"]git = "https://github.com/japaric/stm32f103xx-hal"
在 src/main.rs 里引入 hal:
extern crate stm32f103xx_hal as hal;use hal::*;
hal::prelude 中定義了許多 trait,這些 trait 默認(rèn)實現(xiàn)于外設(shè)結(jié)構(gòu)體(比如說 RCC)上來提供 constrain() 轉(zhuǎn)換函數(shù)。constrain() 會將 stm32f103xx 的外設(shè)實例轉(zhuǎn)化為 stm32f103xx-hal 中的外設(shè)類型。
let dp = stm32f103xx::Peripherals::take().unwrap();// 將 RCC 寄存器結(jié)構(gòu)體轉(zhuǎn)換為進(jìn)一步抽象的 hal 結(jié)構(gòu)體let mut rcc = dp.RCC.constrain();// 獲取 GPIOC 實例,這里會自動打開總線開關(guān)let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);// 獲取 PC13 實例,并進(jìn)行引腳配置let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);// 輸出高電平led.set_high();// 輸出低電平led.set_low();
完整代碼:
#![no_std]#![no_main]extern crate panic_halt;extern crate stm32f103xx_hal as hal;use core::ptr;use stm32f103xx;use cortex_m::asm;use cortex_m_rt::entry;use hal::*;#[entry]fn main() -> ! {// 獲取 Peripherals    let dp = stm32f103xx::take().unwrap();// 將 RCC 寄存器結(jié)構(gòu)體轉(zhuǎn)換為進(jìn)一步抽象的 hal 結(jié)構(gòu)體    let mut rcc = dp.RCC.constrain();// 獲取 GPIOC 實例,這里會自動打開總線開關(guān)    let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);// 獲取 PC13 實例,并進(jìn)行引腳配置    let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);    loop {        delay();// 輸出低電平        led.set_low();        delay();// 輸出高電平        led.set_high();    }}fn delay() {for _ in 0..2_000 {        asm::nop();    }}

Conclusion

這篇文章篇幅較長,從寄存器原理一直講到了內(nèi)存操作方法,然后展示了如何通過 Rust 強大的抽象能力將零散的內(nèi)存操作隱藏在安全的操作接口后面,并且還基于 embedded-hal 對寄存器操作的邏輯再一次抽象,得到了安全且容易使用的 API,還可以根據(jù)需要靈活選擇抽象級別。相信讀者已經(jīng)能感受到Rust 在嵌入式領(lǐng)域相對于 C 的巨大的優(yōu)勢了。


審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5336

    瀏覽量

    120228
  • 存儲器
    +關(guān)注

    關(guān)注

    38

    文章

    7484

    瀏覽量

    163760
  • 總線
    +關(guān)注

    關(guān)注

    10

    文章

    2878

    瀏覽量

    88051
  • Cortex
    +關(guān)注

    關(guān)注

    2

    文章

    202

    瀏覽量

    46482
收藏 人收藏

    評論

    相關(guān)推薦

    【圖書分享】《ARM Cortex-M3權(quán)威指南

    指令小結(jié)附錄B 16位Thumb指令及架構(gòu)版本附錄C Cortex?M3異??焖賲⒖几戒汥 NVIC寄存器小結(jié)附錄E Cortex-M3疑難解答附件:
    發(fā)表于 03-13 10:40

    ARM Cortex-M3系統(tǒng)該如何去設(shè)計呢

    STM32 MCU系統(tǒng)時鐘樹 1.4 Cortex-M3簡介2. 通用并行GPIO口 2.1 GPIO結(jié)構(gòu)及寄存器說明 2.2 GPIO設(shè)計實例...
    發(fā)表于 11-10 07:50

    ARM Cortex-M3 DesignStart? Eval RTL和FPGA快速入門指南

    不支持更改處理配置。 當(dāng)用戶修改Cortex-M3 DesignStart評估系統(tǒng)時,模糊后的RTL用于構(gòu)建一個FPGA映像。 混淆后的RTL僅暴露一組有限的內(nèi)部寄存器用于調(diào)試目的。 出于模擬和調(diào)試目的,建議使用處理
    發(fā)表于 08-12 07:38

    Cortex-M3 技術(shù)參考手冊

    第 1 章概述本章描述了 Cortex-M3 處理的組件以及處理的指令集。第 2 章編程模型(programmer’s model)本章描述了 Cortex-M3
    發(fā)表于 07-08 16:40 ?112次下載

    ARM Cortex-M3權(quán)威指南

    《ARM Cortex-M3權(quán)威指南》重點介紹了新的ARM架構(gòu)、指令集的總結(jié)、硬件特性以及調(diào)試系統(tǒng)的概覽。《ARM Cortex-M3權(quán)威指南》還提供了一些程序示例,并且在其中講解了使
    發(fā)表于 12-14 15:08 ?48次下載

    Cortex-M3操作指南

    Cortex-M3操作指南
    發(fā)表于 12-27 22:12 ?3次下載

    Cortex-M3權(quán)威指南中文版

    Cortex-M3權(quán)威指南中文版
    發(fā)表于 09-20 09:03 ?0次下載
    <b class='flag-5'>Cortex-M3</b>權(quán)威<b class='flag-5'>指南</b>中文版

    Cortex-M3權(quán)威指南中文版資料

    Cortex-M3權(quán)威指南中文版資料
    發(fā)表于 10-29 09:45 ?0次下載
    <b class='flag-5'>Cortex-M3</b>權(quán)威<b class='flag-5'>指南</b>中文版資料

    Cortex-M3寄存器組資料下載

    電子發(fā)燒友網(wǎng)為你提供Cortex-M3寄存器組資料下載的電子資料下載,更有其他相關(guān)的電路圖、源代碼、課件教程、中文資料、英文資料、參考設(shè)計、用戶指南、解決方案等資料,希望可以幫助到廣大的電子工程師們。
    發(fā)表于 04-13 08:47 ?2次下載
    <b class='flag-5'>Cortex-M3</b><b class='flag-5'>寄存器</b>組資料下載

    Cortex-M3權(quán)威指南 Joseph Yiu 著

    Cortex-M3權(quán)威指南 Joseph Yiu 著
    發(fā)表于 11-02 09:15 ?0次下載

    Cortex-M3處理內(nèi)核與基于Cortex-M3的MCU關(guān)系

    低實時性好代碼密度得到很大改善使用更加方便低成本的整體解決方案開發(fā)工具眾多:keil、Cube…者之間的關(guān)系上圖是基于Cortex-M3內(nèi)核的MCU,Cortex-M3相當(dāng)于一個小CPU(中央處理
    發(fā)表于 11-05 18:35 ?8次下載
    <b class='flag-5'>Cortex-M3</b>處理<b class='flag-5'>器</b>內(nèi)核與基于<b class='flag-5'>Cortex-M3</b>的MCU關(guān)系

    ARM Cortex-M3系統(tǒng)設(shè)計與實現(xiàn)

    STM32 MCU系統(tǒng)時鐘樹 1.4 Cortex-M3簡介2. 通用并行GPIO口 2.1 GPIO結(jié)構(gòu)及寄存器說明 2.2 GPIO設(shè)計實例...
    發(fā)表于 11-05 19:50 ?22次下載
    ARM <b class='flag-5'>Cortex-M3</b>系統(tǒng)設(shè)計與實現(xiàn)

    Cortex-M3 內(nèi)部寄存器

    ;R13R13,SP,堆棧指針;Cortex-M3有兩個堆棧指針,它們是Banked,任一時刻只能使用其中一個;當(dāng)引用R13/SP時,引用的是當(dāng)前正在使用的那一個,另一個必須使用MRS/MSR指令來訪...
    發(fā)表于 11-26 16:21 ?39次下載
    <b class='flag-5'>Cortex-M3</b> 內(nèi)部<b class='flag-5'>寄存器</b>

    《STM32 Cortex-M3權(quán)威指南》宋巖譯

    《STM32 Cortex-M3權(quán)威指南》宋巖譯
    發(fā)表于 12-30 10:24 ?58次下載

    Cortex-M3寄存器等基礎(chǔ)知識

    Cortex-M3擁有R0~R15通用寄存器和一些特殊功能寄存器。R0~R12這些通用寄存器,復(fù)位初始值都是不可預(yù)料的。
    發(fā)表于 02-08 16:28 ?2次下載
    <b class='flag-5'>Cortex-M3</b><b class='flag-5'>寄存器</b>等基礎(chǔ)知識
    RM新时代网站-首页