28335不单单是个CPU,还有非常多的外设功能模块,像是ADC、SCI、PWM、CAN什么的。这些模块的的功能是有专门的硬件控制器来完成的,在运行时不会占用CPU资源,只是在配置和进行数据交互时才会用到CPU指令。就像你使用SCI只需设置好波特率和相关的中断,然后做好数据的收发,数据的串并/并串转换、fifo的控制、并行帧监测这都是由硬件模块完成。
以上为GPIO三个寄存器的硬件地址分配情况,而DSP2833x_Headers_nonBIOS.cmd这个文件里面有这样的地址空间定义:
而在源文件里面,则是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里面,就如上图所示。
这里可以根据变量名来一一对应这些寄存器,结构体里面的这些联合体类型都是2个16位长度的。 里面的两个rsvd变量是为保证寄存器地址完全对齐而设置的,这说明为寄存器分配的地址上面并不是每一位的空间都是有利用的,这点直接对着文档看地址分配很容易忽略,虽然这个没什么重要性。另外体现的信息,不同的寄存器所用的结构体是不同的,这也是针对寄存器的具体物理结构所做的设置。
CPU跟这些模块的接口就是这些模块的寄存器,模块的配置和访问操作都是通过读写相关寄存器来完成的。这些寄存器的物理存储空间是直接并入数据地址空间的,所以不需要另外的读写指令来操作这些寄存器。
28335里面又把这些模块的寄存器分为4组,分配在不同的地址空间下。上图可以看出4个寄存器组的地址分配情况。中间的Reserved阴影块应该是留给后续版本升级的地址空间,隔开了组号0跟1、2、3。组1、2、3其实是在连续的地址上的,这些组除了所包含的模块不同之外,其总线结构也是稍有不同的。
![](https://i-blog.csdnimg.cn/blog_migrate/99474c6dd84b0a9c2a6d169b261ccb96.png)
28335里面又把这些模块的寄存器分为4组,分配在不同的地址空间下。上图可以看出4个寄存器组的地址分配情况。中间的Reserved阴影块应该是留给后续版本升级的地址空间,隔开了组号0跟1、2、3。组1、2、3其实是在连续的地址上的,这些组除了所包含的模块不同之外,其总线结构也是稍有不同的。
![](https://i-blog.csdnimg.cn/blog_migrate/8694d58b921ca035bd94cb42ea766e3d.png)
上表是Peripheral Frame 0的寄存器分配排列信息,各个不同模块的寄存器占用的空间各有不同,在地址空间上连续排列。
一个模块包含着多个不同功能的寄存器,寄存器的不同位代表着不同的信息。每个寄存器都分配了的物理地址。在CCS的C语言开发系统中,在代码源文件里面用结构体描述外设模块的寄存器结构,然后用cmd文件为其一一分配物理地址,这样就完成了寄存器的映射。
下面就以GPIO模块寄存器为例来展示下这种映射的细节好了。
![](https://i-blog.csdnimg.cn/blog_migrate/31dc8587830f02273955ee9caf25ffa9.png)
以上为GPIO三个寄存器的硬件地址分配情况,而DSP2833x_Headers_nonBIOS.cmd这个文件里面有这样的地址空间定义:
![](https://i-blog.csdnimg.cn/blog_migrate/e1730339db86e3e065a36ba5956485bf.png)
origin表示起始地址,length表示长度,再结合名字,很容易就可以推出这正好是GPIO的三个寄存器组的物理地址空间。
![](https://i-blog.csdnimg.cn/blog_migrate/571bb83701f54373ab3dd2a153a14847.png)
而在源文件里面,则是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里面,就如上图所示。
物理地址的映射就是这些,那寄存器结构就是简单的在这些结构体的成员里面做文章了:
![](https://i-blog.csdnimg.cn/blog_migrate/d04e73c70b8cbd431c698f3122a191c4.png)
这里可以根据变量名来一一对应这些寄存器,结构体里面的这些联合体类型都是2个16位长度的。 里面的两个rsvd变量是为保证寄存器地址完全对齐而设置的,这说明为寄存器分配的地址上面并不是每一位的空间都是有利用的,这点直接对着文档看地址分配很容易忽略,虽然这个没什么重要性。另外体现的信息,不同的寄存器所用的结构体是不同的,这也是针对寄存器的具体物理结构所做的设置。
![](https://i-blog.csdnimg.cn/blog_migrate/b328f77d9627236a709ea14f585523be.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a8376d6b34c7fdca1f6b6fca274e165f.png)
GPACTRL寄存器的数据结构类型是GPACTRL_REG,使用联合体就是既可以用32位的all也可以用结构体GPACTRL_BITS bit里面的四个8为数据来访问这个寄存器。跟GPACTRL的物理逻辑结构一对照就知道为什么要用这种数据结构来定义GPACTRL寄存器了。
28335的外设功能很多,整个寄存器体系结构跟映射关系还是很复杂的,但是找准一个模块慢慢研究,其他的寄存器模块也就触类旁通了。