IO使用、时钟、Cortex-A7 ArmV7介绍

Cortex-A7 有 9 种运行模式

image

CPSR寄存器

SPSR:当异常中断发生后将CPSR寄存器保存到SPSR寄存器中,在异常中断结束后,将SPSR寄存器恢复到CPSR寄存器中

其低5位可用于控制处理器模式
image-1740142881640

CCM_CCGRx 使能io始终

image-1740144765587

IO复用

配置IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03第四位为5
image-1740144910651

配置电气属性

配置IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03
image-1740145252650

配置io输入输出 GPIOx_GDIR

image-1740146517022

配置io电平 GPIOx_DR

image-1740146556507

时钟

主要从24Mhz晶振分出来7路时钟信号
image-1740223905043
见下图
image-1740223824420
从七路时钟信号导向不同的外设 见下图时钟树
image-1740224041225
image-1740224066179

配置ARM主频为最大528MHz

image-1740224879270

配置CACRR[ARM_PODF]时钟,二分频

image-1740225650605

配置ARM_PODF为001
image-1740225699704

配置CCM_ANALOG_PLL_ARM[DIV_SELECT]时钟,输出为pll1_main_clk

528 * 2 * 2 / 24 = 88
image-1740224857242

配置PLL1时钟

在配置arm时钟前,需要通过GLITCHLESS MUX修改时钟为step_clk,通过CCSR: step_sel配置为0(24Mhz)晶振时钟
image-1740225292122

配置PLL2 528Mhz PFD0-3

image-1740229702156

PLL3 480Mhz PFD0-3

image-1740230853689

其他外设时钟源

image-1740231015050

查表可知三者的最大时钟

image-1740231101686

配置时钟代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

// 528Mhz
void imx6u_clkinit(void)
{
// 切换系统时钟到24Mhz
if (REG_BIT(CCM->CCSR, 2) == 0)
{
CCM->CCSR &= ~BIT(8);
CCM->CCSR |= BIT(2);
}

#if 1
// 使能PLL1 BIT(13) 配置PLL1 88分频系数 24 * 88 / 2 = 1056Mhz
CCM_ANALOG->PLL_ARM = (BIT(13) | (88u & 0x7fu));

// 配置CACRR二分频 1056Mhz / 2 = 528Mhz
CCM->CACRR = 1;
#else
// 使能PLL1 BIT(13) 配置PLL1 88分频系数 24 * 58 / 2 = 696Mhz
CCM_ANALOG->PLL_ARM = (BIT(13) | (58u & 0x7fu));

// 配置CACRR1分频 696Mhz
CCM->CACRR = 0;
#endif

// 切换时钟源为PLL1
CCM->CCSR &= ~BIT(2);

// PLL2
uint32_t reg = 0;
reg |= 27u << 0; // 528 * 18 / 27 = 352Mhz
reg |= 16u << 8; // 528 * 18 / 16 = 594Mhz
reg |= 24u << 16; // 528 * 18 / 24 = 396Mhz
reg |= 32u << 24; // 528 * 18 / 32 = 297Mhz
CCM_ANALOG->PFD_528 = reg;

// PLL3
reg = 0;
reg |= 12u << 0; // 480 * 18 / 12 = 720Mhz
reg |= 16u << 8; // 480 * 18 / 16 = 540Mhz
reg |= 17u << 16; // 480 * 18 / 17 = 508.2Mhz
reg |= 19u << 24; // 480 * 18 / 19 = 454.7Mhz
CCM_ANALOG->PFD_480 = reg;

// 设置AHB_CLK_ROOT
// 选择PLL2 PFD0的时钟396MHZ
// PRE_PERIPH_CLK_SEL
CCM->CBCMR &= ~(3 << 18);
CCM->CBCMR |= (1 << 18); // PRE_PERIPH_CLK_SEL

// PERIPH_CLK_SEL
CCM->CBCDR &= ~(1 << 25);
while ((CCM->CDHIPR & BIT(5)));

#if 0 // 不能用 仅供学习
// AHB_PODF 设置AHB_CLK_ROOT 3分频 396 / 3 = 132Mhz
CCM->CBCDR &= ~(7 << 10);
CCM->CBCDR |= (2 << 10);
while ((CCM->CDHIPR & BIT(1)));
#endif

// 设置IPG_CLK_ROOT
// IPG_PODF 2分频 132 / 2 = 66Mhz
CCM->CBCDR &= ~(3 << 8);
CCM->CBCDR |= (1 << 8);

// 设置PERCLK_CLK_ROOT
// PERCLK_PODF PERCLK_CLK_SEL 都设置为0
CCM->CSCMR1 &= ~(0x7f);
}