上次我们说到SCGC5,也就是系统门控时钟5,这个是SIM模块里面的寄存器。那么今天我们就来看看,这个SIM模块究竟是干什么的?
在技术手册的第12章详细地描述了这个模块
SIM(System Integartion Module)
开宗明义,这个模块提供了系统控制和芯片配置寄存器。
它的特性包括了:
1、系统时钟配置:系统时钟分频值;Architectural clock gating control(这个不太懂);USB时钟选择和分频值;SDHC 时钟源选择;1588以太网时间戳和RMII的时钟源选择
2、Flash和RAM的大小设置
3、USB校准配置
4、灵活计数器,硬件触发器和错误源的选择
5、UART0(UART1)的发送(接收)源的选择和配置
SIM模块有许多的域来控制和配置不同模块的时钟源和分频值,关于这一点,在时钟配置章节有更详尽的描述。其实也没有详尽多少,只是有些点还是值得一提的。
1、由于SIM,使得芯片时钟可以依据模块,部分启动和关闭
2、基本的时钟是源于MCGOUTCLK,但是通过时钟发生器可以让不同的模块有不同的时钟频率,来满足低功耗的要求
3、还有一部分的时钟源自于MCGPLLCLK和MCGFLLCLK,并且还有备用的时钟源,并且这些模块都有SIM模块的SOPT寄存器控制
那么接下来的更为细致的寄存器描述就不一 一看了。根据我们写的代码。我们拶指只看我们要使用的寄存器和相应的位就好。
这次我们要解析下面的函数
void PORT_PinPullConfig(uint32_t instance, uint8_t pin, PORT_Pull_Type pull){
SIM->SCGC5 |= SIM_GPIOClockGateTable[instance];
switch(pull)
{
case kPullDisabled:
PORT_InstanceTable[instance]->PCR[pin] &= ~PORT_PCR_PE_MASK;
break;
......
default:
break;
}}
上次已知的代码是这样的:
#define SIM_BASE 0x40047000u
#define SIM (SIM_Type *)SIM_BASE
__IO uint32_t SCGC5; /**< System Clock Gating Control Register 5, offset: 0x1038 */
那么我们要关注的寄存器地址是0x40047000u+0x1038 =0x40048038。让我们在技术手册中查找一下。正好是SIM_SCGC5寄存器,那么要对这个寄存器操作做什么事情呢?嗯,看代码:
SIM->SCGC5 |= SIM_GPIOClockGateTable[instance];
关于SIM_GPIOClockGateTable在gpio.c文件中有定义:
static const uint32_t SIM_GPIOClockGateTable[] =
{
SIM_SCGC5_PORTA_MASK,
SIM_SCGC5_PORTB_MASK,
SIM_SCGC5_PORTC_MASK,
SIM_SCGC5_PORTD_MASK,
SIM_SCGC5_PORTE_MASK,
};
那个instance在本次代码中表示的是0x04。之前说过的通过#define定义的。也就是说这句代码的意思是将SIM_SCGC5_PORTE_MASK赋给地址为0x40048038的寄存器,那么这个SIM_SCGC5_PORTE_MASK值又是多少呢?查定义,追踪一下就ok。
#define SIM_SCGC5_PORTE_MASK 0x2000u
好了到了这里,这句话的意思就很清楚了
将0x2000这个值赋给寄存器SIM_SCGC5.
那么问题来了,这句话又表示什么意思?
查...手...册......
关于SIM_SCGC5的寄存器,它长这个样子
那句话的意思就是,将其中的第13位设置为1!
好了,说了这么多。一层又一层的,其实说白了。就是设了一个1.是不是感觉收到了严重的欺骗!我就是这种感觉!
昨天晚上一高兴就忘记自己还没有写完了。以后不会这样了!现在不需哦天没有写完的补上。
然后就是这句代码了!
PORT_InstanceTable[instance]->PCR[pin] &= ~PORT_PCR_PE_MASK;
关于PORT_InstanceTable[],这个定义比较复杂,单独说一下,定义如下:
static PORT_Type * const PORT_InstanceTable[] = PORT_BASES;
解析:首先,这个static,静态的;PORT_Type* 表示PORT_Type类型的结构体指针;const 表示常量类型,不可更改;PORT_BASES是地址0x4004D000。这个定义表示将PORT_InstanceTable定义为指向PORT_Type结构体的指针的指针这个指针的值是0x4004D000。蛮复杂的还是!
言归正传!地址解析如下:
首先展示与代码有关的定义:
#define PORTE_BASE (0x4004D000u)
/** Peripheral PORTE base pointer */
#define PORTE ((PORT_Type *)PORTE_BASE)
/** Array initializer of PORT peripheral base pointers */
#define PORT_BASES { PORTA, PORTB, PORTC, PORTD, PORTE }
__IO uint32_t PCR[32]; /**< Pin Control Register n, array offset: 0x0, array step: 0x4 */
#define PORT_PCR_PE_MASK 0x2u
接下来计算一下就好了
左边的地址是0x4004D000+0x4*6右边的值是0x2,这样,再参阅相关的技术手册之后就可以知道到底是做什么的了!
上图就是相关的寄存器了。结合代码,表示将PE位清零。那么实际的意义需要阅读相关的章节才行,下次吧!
好了今天的就补完了!