nRF51822学习笔记–硬件外设篇【1】

开始在我的博客更新nRF51822的学习笔记了,玩51822这么久一直都在蓝牙软件层玩,硬件这块特别陌生所以这次准备先把硬件过一遍。然后再更新软件篇的教程。很多笔记都存在为知笔记里,只先整理了一篇发出来后续有空会继续发。有错的地方大家请指出,欢迎讨论交流。


一、介绍一下nRF51822片上资源
CPU:   32-bit ARM® Cortex™ M0 32-bit CPU
Memery
:256/128 KB embedded flash、 16 KB RAM
System Peripherals

一个32位定时器,两个16位定时器。(注:nRF51定时器的位数可以通过寄存器设置的,可变的)
16通道的CPU独立编程外设互联(PPI)

(翻译太渣,献原句:16 channel CPU independent ProgrammablePeripheral Interconnect (PPI))
128位AES ECB/CCM/AAR加密协处理器
RNG
:随机数发生器
两个RTC时钟,RTC0,RTC1
温度传感器
GPIO:
31个GPIO引脚
支持多达4路PWM输出
Digital I/O:
SPI Master
/Slave, 2-wire Master (I2C compatible), UART (CTS/RTS)
正交解码器(Quadraturedecoder)
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 OFF mode + 1 region RAM retention
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 ;POWER_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
                DCD      0 ;Reserved
                DCD      0 ;Reserved
                DCD      0 ;Reserved
                DCD      0 ;Reserved
                DCD      0 ;Reserved
                DCD      0 ;Reserved

下面简单介绍一些外设,像定时器、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 ConfigurationRegisters)
  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寄存器组的东西很丰富,建议去看看手册,我用到的不多,其他的以后用到了再更新。

六、GPIOtasks 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中断的使用。


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) && (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk))//判断中断是否来自GPIOTE通道0
		{
				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.
		}
}




展开阅读全文

没有更多推荐了,返回首页