[TOC]
外设简述
28335不单单是个CPU,还有非常多的外设功能模块,像是ADC、SCI、PWM、CAN什么的。这些模块的的功能是有专门的硬件控制器来完成的,在运行时不会占用CPU资源,只是在配置和进行数据交互时才会用到CPU指令。就像你使用SCI只需设置好波特率和相关的中断,然后做好数据的收发,数据的串并/并串转换、fifo的控制、并行帧监测这都是由硬件模块完成。
寄存器物理结构
CPU跟这些模块的接口就是这些模块的寄存器,模块的配置和访问操作都是通过读写相关寄存器来完成的。这些寄存器的物理存储空间是直接并入数据地址空间的,所以不需要另外的读写指令来操作这些寄存器。
28335里面又把这些模块的寄存器分为4组,分配在不同的地址空间下。上图可以看出4个寄存器组的地址分配情况。中间的Reserved阴影块应该是留给后续版本升级的地址空间,隔开了组号0跟1、2、3。组1、2、3其实是在连续的地址上的,这些组除了所包含的模块不同之外,其总线结构也是稍有不同的。
NAME | ADDRESS RANGE | SIZE (x16) |
---|---|---|
Device Emulation Registers | 0x00 0880 – 0x00 09FF | 384 |
FLASH Registers(3) | 0x00 0A80 – 0x00 0ADF | 96 |
Code Security Module Registers | 0x00 0AE0 – 0x00 0AEF | 16 |
ADC registers (dual-mapped) | 0x00 0B00 – 0x00 0B0F | 16 |
XINTF Registers | 0x00 0B20 – 0x00 0B3F | 32 |
CPU–TIMER0/1/2 Registers | 0x00 0C00 – 0x00 0C3F | 64 |
PIE Registers | 0x00 0CE0 – 0x00 0CFF | 32 |
PIE Vector Table | 0x00 0D00 – 0x00 0DFF | 256 |
DMA Registers | 0x00 1000 – 0x00 11FF | 512 |
上表是Peripheral Frame 0的寄存器分配排列信息,各个不同模块的寄存器占用的空间各有不同,在地址空间上连续排列。
一个模块包含着多个不同功能的寄存器,寄存器的不同位代表着不同的信息。每个寄存器都分配了的物理地址。在CCS的C语言开发系统中,在代码源文件里面用结构体描述外设模块的寄存器结构,然后用cmd文件为其一一分配物理地址,这样就完成了寄存器的映射。
寄存器地址空间映射
下面就以GPIO模块寄存器为例来展示下这种映射的细节好了。
Name | Address |
---|---|
GPIO Control Registers | 0x6F80 - 0x6FBF |
GPIO Data Registers | 0x6FC0 - 0x6FDF |
GPIO Interrupt and LPM Select | 0x6FE0 - 0x6FFF |
以上为GPIO三个寄存器的硬件地址分配情况,而DSP2833x_Headers_nonBIOS.cmd这个文件里面有这样的地址空间定义:
|
|
origin
表示起始地址,length
表示长度,再结合名字,很容易就可以推出这正好是GPIO的三个寄存器组的物理地址空间。
|
|
↓↓↓
|
|
↓↓↓
|
|
↓↓↓
|
|
↓↓↓
|
|
而在源文件里面,则是GPIO_CTRL_REGS、GPIO_DATA_REGS、GPIO_INT_REGS分别表示这三个寄存器组,DSP2833x_Gpio.h文件里面声明了这三个寄存器组全局结构,然后是DSP2833x_GlobalVariableDefs.c为这三个结构体定义自定义数据段GpioCtrlRegsFile 、GpioDataRegsFile、GpioIntRegsFile,在DSP2833x_Headers_nonBIOS.cmd文件里面将这三个数据段映射到定义好的三个数据空间GPIOCTRL、GPIODAT、GPIOINT里面,就如上图所示。
物理地址的映射就是这些,那寄存器结构就是简单的在这些结构体的成员里面做文章了:
|
|
↓↓↓
Name (1) | Address | Size (x16) |
---|---|---|
GPACTRL | 0x6F80 | 2 |
GPAQSEL1 | 0x6F82 | 2 |
GPAQSEL2 | 0x6F84 | 2 |
GPAMUX1 | 0x6F86 | 2 |
GPAMUX2 | 0x6F88 | 2 |
GPADIR | 0x6F8A | 2 |
GPAPUD | 0x6F8C | 2 |
GPBCTRL | 0x6F90 | 2 |
GPBQSEL1 | 0x6F92 | 2 |
GPBQSEL2 | 0x6F94 | 2 |
GPBMUX1 | 0x6F96 | 2 |
GPBMUX2 | 0x6F98 | 2 |
GPBDIR | 0x6F9A | 2 |
GPBPUD | 0x6F9C | 2 |
GPCMUX1 | 0x6FA6 | 2 |
GPCMUX2 | 0x6FA8 | 2 |
GPCDIR | 0x6FAA | 2 |
GPCPUD | 0x6FAC | 2 |
这里可以根据变量名来一一对应这些寄存器,结构体里面的这些联合体类型都是2个16位长度的。里面的两个rsvd变量是为保证寄存器地址完全对齐而设置的,这说明为寄存器分配的地址上面并不是每一位的空间都是有利用的,这点直接对着文档看地址分配很容易忽略,虽然这个没什么重要性。另外体现的信息,不同的寄存器所用的结构体是不同的,这也是针对寄存器的具体物理结构所做的设置。
|
|
GPACTRL寄存器的数据结构类型是GPACTRL_REG,使用联合体就是既可以用32位的all也可以用结构体GPACTRL_BITS bit里面的四个8位数据来访问这个寄存器。跟GPACTRL的物理逻辑结构一对照就知道为什么要用这种数据结构来定义GPACTRL寄存器了。
小总结
28335的外设功能很多,整个寄存器体系结构跟映射关系还是很复杂的,但是找准一个模块慢慢研究,其他的寄存器模块也就触类旁通了。