[群150178878]nRF51822學習筆記–硬體外設篇【1】
阿新 • • 發佈:2018-11-09
轉載自:
http://www.eeboard.com/bbs/thread-31077-1-1.html
開始在我的部落格更新nRF51822的學習筆記了,玩51822這麼久一直都在藍芽軟體層玩,硬體這塊特別陌生所以這次準備先把硬體過一遍。然後再更新軟體篇的教程。很多筆記都存在為知筆記裡,只先整理了一篇發出來後續有空會繼續發。有錯的地方大家請指出,歡迎討論交流。
Created: 14-03-20 Updated: 14-03-20
一、介紹一下nRF51822片上資源CPU: 32-bit ARM® Cortex™ M0 32
Memery:256/128 KB embedded flash、 16 KB RAM
System Peripherals:
一個32位定時器,兩個16位定時器。(注:nRF51定時器的位數可以通過暫存器設定的,可變的)
16通道的CPU獨立程式設計外設互聯(PPI)
(翻譯太渣,獻原句:16 channel CPU independent Programmable Peripheral Interconnect (PPI))
128位AES ECB/CCM/AAR加密協處理器
RNG:隨機數發生器
兩個RTC時鐘,RTC0,RTC1
溫度感測器
GPIO:
31
支援多達4路PWM輸出
Digital I/O:
SPI Master/Slave, 2-wire Master (I2C compatible), UART (CTS/RTS)
正交解碼器(Quadrature decoder)
Analog I/O:
8/9/10 bit ADC - 8 configurable channels
Low power comparator
Power Management:
支援1.8V到3.6V寬電壓
在晶片DC/DC轉換
0.6 µA @ 3V OFF mode
1.2 µA @ 3V
2.6 µA @ 3V ON mode, all blocks in idle mode
其他:
MPU
二、暫存器介紹
nRF51822的暫存器分為三類
* Task暫存器 :即該外設可以執行的task
* Event暫存器:即該外設帶有的event
* 普通暫存器
Task暫存器和event暫存器在PPI的使用中是非常重要的,舉個例子,在PPI中,設定EEP暫存器地址為某個外設A的Event暫存器地址,TEP暫存器設為另一個外設B的Task暫存器地址,那麼當那個外設A的event發生時,可以直接觸發執行外設B的task,而不經過CPU,這點在後面的PPI介紹中會有說明。
三、nRF51822的中斷
1.nRF51822的中斷源分別對應外設相應的event暫存器。
2.Nordic為了節省功耗把systick給去掉了,所以SysTick_Handler可以無視。
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
外部中斷源也比常規的ARM晶片要少很多,SWI中斷大多用在藍芽協議棧中。
; External Interrupts
DCD POWER_CLOCK_IRQHandler OWER_CLOCK
DCD RADIO_IRQHandler ;RADIO
DCD UART0_IRQHandler ;UART0
DCD SPI0_TWI0_IRQHandler ;SPI0_TWI0
DCD SPI1_TWI1_IRQHandler ;SPI1_TWI1
DCD 0 ;Reserved
DCD GPIOTE_IRQHandler ;GPIOTE
DCD ADC_IRQHandler ;ADC
DCD TIMER0_IRQHandler ;TIMER0
DCD TIMER1_IRQHandler ;TIMER1
DCD TIMER2_IRQHandler ;TIMER2
DCD RTC0_IRQHandler ;RTC0
DCD TEMP_IRQHandler ;TEMP
DCD RNG_IRQHandler ;RNG
DCD ECB_IRQHandler ;ECB
DCD CCM_AAR_IRQHandler ;CCM_AAR
DCD WDT_IRQHandler ;WDT
DCD RTC1_IRQHandler ;RTC1
DCD QDEC_IRQHandler ;QDEC
DCD LPCOMP_IRQHandler ;LPCOMP
DCD SWI0_IRQHandler ;SWI0
DCD SWI1_IRQHandler ;SWI1
DCD SWI2_IRQHandler ;SWI2
DCD SWI3_IRQHandler ;SWI3
DCD SWI4_IRQHandler ;SWI4
DCD SWI5_IRQHandler ;SWI5
下面簡單介紹一些外設,像定時器、GPIOTE、PPI等後面介紹。
四、NVMC
NVMC和其他ARM晶片一樣,負責晶片Flash的擦寫燒錄,這裡要說一下Nordic nRF51822 Flash結構。截圖選自最新的softdevice 7.0.0.3alpha。新版的s110 softdevice將最底部的0×0~0×1000區域用作MBR,關於MBR和softdevice以及使用者app之間的跳轉過程,看我另一篇筆記 nRF51822-問答筆記【1】。也就是說Region0包含了Softdvice以及MBR,Region1包含了使用者app和bootloader。
nRF51822晶片在flash操作上有個限制,為了保護R0區的softdevice不被破壞,它禁止了R1區的程式呼叫flash操作函式去讀寫R0區。也就是說,在softdevice6.0以及更早版本,我們是無法更新softdevice的,因為bootloader位於R1區。
當然你可以有個極端的辦法,雖然我們無法單獨擦除R0區程式碼,但nRF51822允許我們整個晶片擦除。所以,我們可以把程式拷貝到RAM中,在RAM中跑bootloader,對整個晶片的擦寫,實現bootloader的升級。這樣做的缺點很顯示,一旦中途斷電,整個晶片就癱瘓了。
為了實現softdevice的升級Nordic官方推出了新的softdevice 7.0,加入MBR使得bootloader可以呼叫MBR中的Flash操作函式實現softdevice升級。下面簡單地介紹一下原理:
首先,上電後程序跳轉到MBR中斷向量入口,檢測是否存在bootloader,存在則接著跳轉到Bootload,在bootloader中,通過BLE方式或者串列埠方式收到新的softdevice firmware放在使用者的app區,校驗完畢,開始呼叫MBR中的flash擦寫函式,覆蓋舊版本的softdevice。
四、UICR暫存器的說明
UICR: 使用者資訊配置暫存器(User Information Configuration Registers)
UICR->CLENR0暫存器:很重要 CLENR0存放了Region0的大小,對於softdevice6.0需要設定為0×14000,對於softdevice 7.0要設定為0×15000。換句話說這個暫存器存放了使用者APP的起始地址。(Region0存放softdevice,Region1存放APP、Bootloader)
UICR->RBCONF: read back protection,回讀保護。保護的是region0的。
還有兩個XTALFREQ暫存器和FWID暫存器不常用,見手冊。
五、FICR暫存器
手冊裡面寫的很詳細,常用的暫存器有:
CODEPAGESIZE:softdevice將Region1的Flash分成一個個page,每個page的位元組數存放在此。
CODESIZE:Flash被分成的總的page數
FICR暫存器組的東西很豐富,建議去看看手冊,我用到的不多,其他的以後用到了再更新。
六、GPIO tasks and events (GPIOTE)
1.GPIOTE模組也是設計成減少了CPU佔用的Task Event模式,使得事件可以不經過CPU就能得到響應。
Event引腳的觸發源有:上升沿,下降沿等任何改變
Task引腳的操作方式有:置位,清0,反轉
Event和task之間可以靠PPI連線在一起(見nRF51822學習筆記–硬體外設篇【3】PPI的描述)
2.一旦把某個引腳分配給Task(OUT[n])或Event(IN[n]),那麼該引腳就只能被GPIOTE模組寫操作,正常的GPIO寫入時無效的。
3.當GPIOTE通道被配置用於操作一個任務引腳n,那麼該引腳n的初值需要在CONFIG[n]暫存器的OUTINIT區域中設定。
4.GPIOE的事件觸發源可以不僅僅只是某個引腳,還可以是某個port(nRF51把32個引腳分為4個port),同屬一個port的任意一個引腳只要被檢測到上升沿發生都會觸發Port Event。
5.GPIOTE中斷的使用。
/**
* @brief Function for configuring: pin 0 for input, pin 8 for output,
* and configures GPIOTE to give an interrupt on pin change.
*/
static void gpio_init(void)
{
nrf_gpio_cfg_input(BUTTON_0, BUTTON_PULL);
nrf_gpio_cfg_output(LED_0);nrf_gpio_pin_write(LED_0, BUTTON_0);// Enable interrupt:
NVIC_EnableIRQ(GPIOTE_IRQn);
//配置工作模式為event
//選擇一個引腳作為event來源
//配置該event的觸發源為翻轉
NRF_GPIOTE->CONFIG[0] = (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos)
| (0 << GPIOTE_CONFIG_PSEL_Pos)
| (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
//開啟4路GPIOTE通道中的IN0通道的中斷
NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;
}/** @brief Function for handling the GPIOTE interrupt which is triggered on pin 0 change.
*/
void GPIOTE_IRQHandler(void)
{
// Event causing the interrupt must be cleared.
if ((NRF_GPIOTE->EVENTS_IN[0] == 1) && //判斷中斷是否來自GPIOTE通道0
(NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk))
{
NRF_GPIOTE->EVENTS_IN[0] = 0;
}
nrf_gpio_pin_toggle(LED_0);
}/**
* @brief Function for application main entry.
*/
int main(void)
{
gpio_init();
while (true)
{
// Do nothing.
}
}
6.GPIOTE配合PPI的使用,見PPI部分